Vai al contenuto principale

Sviluppatori

SDK e CLI di Hushscript

Librerie ufficiali per TypeScript, Python, Go e PHP, più uno strumento da riga di comando, che trasformano un file registrato in una trascrizione con una sola chiamata.

Gli SDK ufficiali racchiudono l’API REST per il codice server e gli script. Una sola chiamata trascrive un file: carica la registrazione, attende il job e restituisce la trascrizione. Nel frattempo l’SDK controlla il file prima che vengano trattenuti dei minuti, ripete ciò che si può ripetere senza rischi, mantiene attivo un caricamento lungo e inserisce una chiave di idempotenza in ogni caricamento e acquisto, così un nuovo tentativo non addebita mai due volte. La CLI è costruita sull’SDK TypeScript e fa lo stesso da terminale.

Pacchetti

Linguaggio Pacchetto Registro Sorgente
TypeScript @hushscript/sdk npm: www.npmjs.com/package/@hushscript/sdk github.com/Hushscript/hushscript-sdk-typescript
Python hushscript PyPI: pypi.org/project/hushscript github.com/Hushscript/hushscript-sdk-python
Go github.com/Hushscript/hushscript-sdk-go pkg.go.dev: pkg.go.dev/github.com/Hushscript/hushscript-sdk-go github.com/Hushscript/hushscript-sdk-go
PHP hushscript/sdk Packagist: packagist.org/packages/hushscript/sdk github.com/Hushscript/hushscript-sdk-php
CLI @hushscript/cli npm: www.npmjs.com/package/@hushscript/cli github.com/Hushscript/hushscript-cli

Versioni minime del runtime:

Gli SDK sono pensati per server e script. L’API non accetta origini del browser, e un token in un bundle per il browser è un token compromesso, quindi l’SDK TypeScript si rifiuta di avviarsi dove esistono window e document.

Ottenere un token

Ogni SDK e la CLI si autenticano con un token di accesso personale. Creane uno sotto Crea un nuovo token nella pagina MCP dell’account, scegli gli scope che servono al tuo codice e decidi se può acquistare minuti. Il token viene mostrato una sola volta e ha la forma hsr1:<region>:pat.<id>.<secret>. Gli scope e il funzionamento di un token sono nella pagina dell’API.

Gli SDK leggono il token da HUSHSCRIPT_TOKEN quando non ne passi uno:

export HUSHSCRIPT_TOKEN=hsr1:...

Un agente può anche aprire un proprio account, farlo pagare su una pagina di checkout ospitata e ottenere il suo primo token da codice: Hushscript.agent.signup() e Hushscript.agent.claim() in TypeScript, Hushscript.agent_signup() e Hushscript.agent_claim() in Python, AgentSignup e AgentClaim in Go, e Client::agentSignup() e Client::agentClaim() in PHP. Il flusso e le sue regole sono in Uso automatizzato.

TypeScript

npm install @hushscript/sdk
import { writeFile } from "node:fs/promises";
import { Hushscript } from "@hushscript/sdk";

const hs = new Hushscript(); // reads HUSHSCRIPT_TOKEN
const transcript = await hs.transcribe("meeting.mp3");
console.log(transcript.text);
await writeFile("meeting.srt", transcript.toSRT());

transcribe() accetta un percorso, un Blob, un Uint8Array o un ReadableStream<Uint8Array>. Uno stream richiede il suo size e il suo durationSeconds esatti. hs.balance() restituisce i minuti che puoi spendere, hs.transcripts.list() scorre le trascrizioni completate e hs.buy("300min", { acknowledgeNoRefund: true }) acquista un pacchetto. Ogni operazione /v1 è disponibile anche come hs.api, con gli stessi nuovi tentativi, timeout e oscuramento.

Python

pip install hushscript
from pathlib import Path

from hushscript import Hushscript

with Hushscript() as hs:  # reads HUSHSCRIPT_TOKEN
    transcript = hs.transcribe("meeting.mp3")
    print(transcript.text)
    Path("meeting.srt").write_text(transcript.to_srt(), encoding="utf-8")

Ogni chiamata ha un gemello asyncio su AsyncHushscript con gli stessi nomi. transcribe() accetta un percorso, bytes o un file object binario; un file object che non supporta il seek richiede size e duration_seconds. hs.balance(), hs.transcripts.list() e hs.buy("300min", acknowledge_no_refund=True) coprono saldo, elenco delle trascrizioni e acquisti.

Go

go get github.com/Hushscript/hushscript-sdk-go
package main

import (
	"context"
	"fmt"
	"log"
	"os"

	hushscript "github.com/Hushscript/hushscript-sdk-go"
)

func main() {
	client, err := hushscript.New() // reads HUSHSCRIPT_TOKEN
	if err != nil {
		log.Fatal(err)
	}
	transcript, err := client.Transcribe(context.Background(), "meeting.mp3", nil)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(transcript.Text(nil))
	if err := os.WriteFile("meeting.srt", []byte(transcript.SRT(nil)), 0o600); err != nil {
		log.Fatal(err)
	}
}

Transcribe accetta un percorso, TranscribeReader un io.ReaderAt con la sua dimensione esatta, e TranscribeStream un lettore sequenziale con la sua dimensione e DurationSeconds. client.Balance, client.Transcripts.List e client.Buy coprono saldo, elenco delle trascrizioni e acquisti. Le opzioni che possono essere attive, disattive o non impostate sono *bool, create con hushscript.Bool.

PHP

composer require hushscript/sdk
<?php

require __DIR__ . '/vendor/autoload.php';

use Hushscript\Client;

$hs = new Client(); // reads HUSHSCRIPT_TOKEN

$transcript = $hs->transcribe('meeting.mp3');
echo $transcript->text();
file_put_contents('meeting.srt', $transcript->toSrt());

transcribe() accetta un percorso o uno stream aperto; uno stream che non supporta il seek richiede le opzioni size e duration_seconds. Le opzioni usano chiavi di array in snake_case e i risultati usano proprietà in camelCase. $hs->balance(), $hs->transcripts()->list() e $hs->buy('300min', true) coprono saldo, elenco delle trascrizioni e acquisti. Per Laravel, collega un solo Client in un service provider ed esegui le trascrizioni in un job in coda con un’opzione idempotency_key stabile.

CLI

npm install --global @hushscript/cli
hushscript login
hushscript transcribe meeting.mp3 --format srt --out meeting.srt

La CLI prende il token da --token, poi da HUSHSCRIPT_TOKEN, poi da quello salvato da hushscript login. login chiede il token senza mostrarlo a schermo e lo conserva in un file leggibile solo dal tuo utente; hushscript logout lo elimina. In CI, preferisci la variabile d’ambiente.

Comando Cosa fa
login Chiede un token e lo salva.
logout Elimina il token salvato.
balance Mostra i minuti che puoi spendere.
transcribe <file> Carica una registrazione, attende e stampa la trascrizione. Flag: --language, --translate, --format srt|vtt|txt|json, --out, --key.
resume <token> <file> Completa una trascrizione lasciata in sospeso da transcribe.
transcripts Elenca le trascrizioni completate, dalla più recente.
transcript <id> Stampa una trascrizione.
jobs Elenca i job; --active per quelli non ancora terminati.
packs Elenca i pacchetti di minuti acquistabili, con i prezzi.
buy <pack> Acquista un pacchetto con la tua carta predefinita salvata. Flag: --yes, --key.

--json stampa un solo documento JSON su stdout e nient’altro, e trasforma stderr in JSON Lines. Il codice di uscita è 0 in caso di successo, 1 quando l’API o l’SDK hanno segnalato un errore, 2 per un errore d’uso (non è stato inviato nulla) e 130 quando l’esecuzione è stata interrotta.

File supportati

MP3, M4A, MP4 e MOV (si usa la traccia audio di un video), WAV, FLAC e OGG con Vorbis o Opus, da 15 secondi a 10 ore. Gli SDK verificano il formato dai byte del file e misurano la durata prima che vengano trattenuti dei minuti. Non convertono i contenuti multimediali, quindi converti prima qualsiasi altro formato:

ffmpeg -i input -vn -c:a libopus output.opus

Errori

Ogni errore generato da un SDK appartiene a una sola famiglia, quindi un solo catch copre tutto: HushscriptError in TypeScript e Python, *hushscript.Error in Go e HushscriptException in PHP. Un errore porta uno slug code come insufficient_balance, il codice numerico, lo stato HTTP, un messaggio, un hint che indica cosa fare dopo, i dettagli e retryAfter (in PHP lo slug è errorCode; in Python retryAfter è retry_after).

import { HushscriptError, InsufficientBalanceError } from "@hushscript/sdk";

try {
  await hs.transcribe("meeting.mp3");
} catch (error) {
  if (error instanceof InsufficientBalanceError) console.log(error.hint);
  else if (error instanceof HushscriptError) console.log(error.code, error.hint ?? error.message);
  else throw error;
}

Un PreflightError significa che l’SDK ha rifiutato il file prima che venisse trattenuto del credito. Stabilire se il saldo copre un file spetta al server: un 402 arriva quando il caricamento viene creato, prima che venga inviata qualsiasi parte.

Addebiti e nuovi tentativi

Ogni caricamento e ogni acquisto porta una chiave di idempotenza, e i nuovi tentativi la riutilizzano, quindi una chiamata ripetuta ripropone la prima invece di avviarne una seconda.

buy() addebita la tua carta predefinita salvata. Acquistare da codice è disattivato finché tre interruttori non lo consentono: il token ha lo scope billing, il token ha “Consenti a questo token di acquistare minuti” attivato e “Consenti alle app connesse di acquistare minuti” è attivo per l’account. Se ne manca uno, la chiamata fallisce con pat_scope_missing. Mostra al tuo acquirente l’avviso di non rimborsabilità prima di chiamarla.

Un acquisto viene ripetuto al massimo una volta, dopo un errore di rete, un 502 o un 503, con la stessa chiave. Alcune risposte dimostrano che non è stato addebitato nulla: un 400, 402, 404 o 422, e un 403 con codice 4021 (pat_purchase_requires_app, la carta è stata rifiutata o non può essere addebitata senza di te) o 4023 (pat_purchase_requires_authentication, la banca vuole confermare il pagamento). Dopo 4021 o 4023, acquista il pacchetto nell’app. Qualsiasi altro errore dopo l’invio della richiesta, compresi un 401 o un 429, significa che la carta potrebbe essere stata addebitata. Quell’errore porta la chiave di idempotenza: riprova con la stessa chiave e l’acquisto non può mai avvenire due volte. In Python:

from hushscript import HushscriptError

try:
    purchase = hs.buy("300min", acknowledge_no_refund=True)
except HushscriptError as error:
    refused = error.status in {400, 402, 404, 422} or (
        error.status == 403 and error.numeric_code in {4021, 4023}
    )
    if error.idempotency_key is None or refused:
        raise  # only these refusals charged nothing; any other failure keeps the key for a retry
    purchase = hs.buy("300min", acknowledge_no_refund=True, idempotency_key=error.idempotency_key)

Un acquisto fallito prima dell’invio della richiesta non porta alcuna chiave: non è stato addebitato nulla. Una chiave che passi tu stesso deve avere da 1 a 128 caratteri tra A-Za-z0-9_-; non riutilizzarla per un pacchetto diverso. La CLI stampa la chiave quando un acquisto potrebbe essere stato inviato:

hushscript buy 300min --yes --key <key>

Token di ripresa

Una volta creato il job, un errore porta un token di ripresa accanto alla chiave di idempotenza. Un’attesa che scade genera WaitTimeoutError con il token, e il job continua a funzionare. Passa il token a resume() per proseguire senza un secondo addebito: un job oltre il caricamento non richiede il file, e uno ancora in caricamento prosegue con lo stesso file. In PHP:

try {
    $hs->transcribe($path, ['wait_timeout' => 60]);
} catch (\Hushscript\Exception\WaitTimeoutError $timeout) {
    $transcript = $hs->resume($timeout->resumeToken, $path);
}

Nella CLI, premere Ctrl-C durante transcribe stampa il token di ripresa del job e il comando che lo porta avanti:

hushscript resume <token> meeting.mp3 --format srt --out meeting.srt

Log e oscuramento

Gli SDK non inviano alcuna telemetria; l’intestazione User-Agent è l’unica identificazione del client. I log sono disattivati per impostazione predefinita. HUSHSCRIPT_LOG=debug scrive una riga per richiesta sullo standard error con metodo, percorso, stato e tempi, e mai un’intestazione, un corpo, un titolo o il testo di una trascrizione.

Il token viene oscurato in ogni errore, riga di log e forma stampata del client. Nei messaggi di errore, negli hint e nelle cause, un URL mantiene host e percorso ma la sua query string diventa ?[redacted], così un URL di caricamento firmato non viene mai stampato. I risultati che ti consegnano un segreto, come un segreto di attivazione o un nuovo token, lo mantengono leggibile come campo ma mostrano [redacted] quando vengono stampati; un export JSON è tuo e contiene il valore. La CLI ripulisce da stderr ogni token che conosce; i suoi risultati su stdout sono il tuo output e non vengono ripuliti.

Configurazione

Impostazione Variabile d’ambiente Predefinito
Token HUSHSCRIPT_TOKEN nessuno
URL di base HUSHSCRIPT_BASE_URL https://api.hushscript.com
Livello di log HUSHSCRIPT_LOG off
Timeout della richiesta nessuna 60 secondi
Nuovi tentativi nessuna 3

Un’opzione passata nel codice ha la precedenza sulla sua variabile d’ambiente, e un valore vuoto vale come non impostato. I minuti provengono dallo stesso saldo dell’app; pacchetti e prezzi sono nella pagina dei prezzi.

Inizia a trascrivere con 30 minuti da provare

Prova un’anteprima fino a 5 minuti prima di creare un account; un nuovo account personale riceve inoltre un’anteprima gratuita del primo caricamento nell’app. La trascrizione completa richiede un account e minuti; gli account personali idonei ricevono 30 minuti gratuiti una sola volta, dopo la verifica della carta o con il primo acquisto. Nessun abbonamento.

Inizia con 30 minuti gratuiti