Przejdź do głównej treści

Dla programistów

SDK i CLI Hushscript

Oficjalne biblioteki dla TypeScript, Python, Go i PHP oraz narzędzie wiersza poleceń, które jednym wywołaniem zamieniają nagrany plik w transkrypcję.

Oficjalne SDK opakowują REST API na potrzeby kodu serwerowego i skryptów. Jedno wywołanie transkrybuje plik: przesyła nagranie, czeka na zadanie i zwraca transkrypcję. Po drodze SDK sprawdza plik, zanim zostaną zarezerwowane jakiekolwiek minuty, ponawia to, co można bezpiecznie ponowić, podtrzymuje długie przesyłanie i dołącza klucz idempotentności do każdego przesłania i zakupu, więc ponowienie nigdy nie obciąży dwa razy. CLI jest zbudowane na SDK dla TypeScript i robi to samo z terminala.

Pakiety

Język Pakiet Rejestr Źródło
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

Minimalne wersje środowisk:

SDK są przeznaczone dla serwerów i skryptów. API nie przyjmuje źródeł przeglądarkowych (origin), a token w paczce dla przeglądarki to wyciekły token, więc SDK dla TypeScript odmawia uruchomienia tam, gdzie istnieją window i document.

Uzyskaj token

Każde SDK i CLI uwierzytelniają się osobistym tokenem dostępu. Utwórz go w sekcji Create a new token na stronie MCP w koncie, wybierz zakresy potrzebne twojemu kodowi i zdecyduj, czy token może kupować minuty. Token jest pokazywany raz i wygląda tak: hsr1:<region>:pat.<id>.<secret>. Zakresy i sposób działania tokenu opisano na stronie API.

Jeśli nie podasz tokenu, SDK odczytują go ze zmiennej HUSHSCRIPT_TOKEN:

export HUSHSCRIPT_TOKEN=hsr1:...

Agent może też sam otworzyć własne konto, opłacić je na hostowanej stronie płatności i odebrać swój pierwszy token z poziomu kodu: Hushscript.agent.signup() i Hushscript.agent.claim() w TypeScripcie, Hushscript.agent_signup() i Hushscript.agent_claim() w Pythonie, AgentSignup i AgentClaim w Go oraz Client::agentSignup() i Client::agentClaim() w PHP. Przebieg i jego zasady opisuje przewodnik Automatyzacja.

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() przyjmuje ścieżkę, Blob, Uint8Array lub ReadableStream<Uint8Array>. Strumień wymaga podania dokładnych wartości size i durationSeconds. hs.balance() zwraca minuty, które możesz wydać, hs.transcripts.list() stronicuje gotowe transkrypcje, a hs.buy("300min", { acknowledgeNoRefund: true }) kupuje pakiet. Każda operacja /v1 jest dostępna także jako hs.api, z tymi samymi ponowieniami, limitami czasu i ukrywaniem danych wrażliwych.

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")

Każde wywołanie ma odpowiednik asyncio w AsyncHushscript o tych samych nazwach. transcribe() przyjmuje ścieżkę, bytes lub binarny obiekt pliku; obiekt pliku, który nie obsługuje przewijania, wymaga size i duration_seconds. hs.balance(), hs.transcripts.list() oraz hs.buy("300min", acknowledge_no_refund=True) obsługują saldo, listę transkrypcji i zakupy.

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 przyjmuje ścieżkę, TranscribeReader przyjmuje io.ReaderAt i jego dokładny rozmiar, a TranscribeStream czytnik tylko do przodu wraz z rozmiarem i DurationSeconds. client.Balance, client.Transcripts.List i client.Buy obsługują saldo, listę transkrypcji i zakupy. Opcje, które mogą być wyłączone, włączone lub nieustawione, mają typ *bool i buduje się je przez 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() przyjmuje ścieżkę lub otwarty strumień; strumień, który nie obsługuje przewijania, wymaga opcji size i duration_seconds. Opcje używają kluczy tablicy w snake_case, a wyniki mają właściwości w camelCase. $hs->balance(), $hs->transcripts()->list() i $hs->buy('300min', true) obsługują saldo, listę transkrypcji i zakupy. W Laravelu zwiąż jeden Client w dostawcy usług (service provider) i uruchamiaj transkrypcje w zadaniu w kolejce ze stałą opcją idempotency_key.

CLI

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

CLI bierze token z --token, potem z HUSHSCRIPT_TOKEN, a na końcu z tego, który zapisał hushscript login. login prosi o token bez wyświetlania go na ekranie i zapisuje go w pliku czytelnym tylko dla twojego użytkownika; hushscript logout go usuwa. W CI wybieraj zmienną środowiskową.

Polecenie Co robi
login Prosi o token i go zapisuje.
logout Usuwa zapisany token.
balance Pokazuje minuty, które możesz wydać.
transcribe <file> Przesyła nagranie, czeka i wypisuje transkrypcję. Flagi: --language, --translate, --format srt|vtt|txt|json, --out, --key.
resume <token> <file> Kończy transkrypcję, którą transcribe zostawiło niedokończoną.
transcripts Wypisuje gotowe transkrypcje, od najnowszej.
transcript <id> Wypisuje jedną transkrypcję.
jobs Wypisuje zadania; --active pokazuje te, które się nie zakończyły.
packs Wypisuje pakiety minut, które możesz kupić, z cenami.
buy <pack> Kupuje pakiet zapisaną kartą domyślną. Flagi: --yes, --key.

--json wypisuje na stdout jeden dokument JSON i nic więcej, a stderr zamienia na JSON Lines. Kod wyjścia to 0 przy sukcesie, 1, gdy błąd zgłosiło API lub SDK, 2 przy błędzie użycia (nic nie zostało wysłane) i 130, gdy uruchomienie przerwano.

Obsługiwane pliki

MP3, M4A, MP4 i MOV (używana jest ścieżka audio wideo), WAV, FLAC oraz OGG z Vorbis lub Opus, od 15 sekund do 10 godzin. SDK sprawdzają format po bajtach pliku i badają czas trwania, zanim zostaną zarezerwowane jakiekolwiek minuty. Nie konwertują multimediów, więc wszystko inne najpierw przekonwertuj:

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

Błędy

Każdy błąd zgłaszany przez SDK należy do jednej rodziny, więc jeden catch obejmuje wszystko: HushscriptError w TypeScripcie i Pythonie, *hushscript.Error w Go oraz HushscriptException w PHP. Błąd zawiera tekstowy code, na przykład insufficient_balance, kod liczbowy, status HTTP, komunikat, hint podpowiadający, co zrobić dalej, szczegóły oraz retryAfter (w PHP slug nazywa się errorCode, a w Pythonie retryAfter to 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;
}

PreflightError oznacza, że SDK odrzuciło plik, zanim zarezerwowano jakiekolwiek środki. To, czy saldo wystarcza na plik, rozstrzyga serwer: kod 402 wraca przy tworzeniu przesyłania, zanim zostanie wysłana jakakolwiek część.

Obciążenia i ponowienia

Każde przesłanie i każdy zakup niesie klucz idempotentności, a ponowienia używają go ponownie, więc ponowione wywołanie odtwarza pierwsze zamiast rozpoczynać drugie.

buy() obciąża twoją zapisaną kartę domyślną. Kupowanie z kodu jest wyłączone, dopóki nie zezwolą na nie trzy przełączniki: token ma zakres billing, token ma włączoną opcję “Let this token buy minutes”, a dla konta włączona jest opcja “Let connected apps buy minutes”. Jeśli brakuje któregoś z nich, wywołanie kończy się błędem pat_scope_missing. Przed wywołaniem pokaż kupującemu informację o braku zwrotów.

Zakup jest ponawiany co najwyżej raz, po błędzie sieci, odpowiedzi 502 lub 503, z tym samym kluczem. Niektóre odpowiedzi dowodzą, że nic nie obciążono: 400, 402, 404 lub 422 oraz 403 z kodem 4021 (pat_purchase_requires_app, karta została odrzucona albo nie można jej obciążyć bez ciebie) lub 4023 (pat_purchase_requires_authentication, bank chce potwierdzić płatność). Po 4021 lub 4023 kup pakiet w aplikacji. Każda inna porażka po wysłaniu żądania, także 401 lub 429, oznacza, że karta mogła zostać obciążona. Taki błąd niesie klucz idempotentności: ponów próbę z tym samym kluczem, a zakup nigdy nie wykona się dwa razy. W Pythonie:

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)

Zakup, który zawiódł przed wysłaniem żądania, nie ma klucza: nic nie zostało obciążone. Klucz, który podajesz samodzielnie, musi mieć od 1 do 128 znaków z zestawu A-Za-z0-9_-; nie używaj go ponownie dla innego pakietu. CLI wypisuje klucz, gdy zakup mógł zostać wysłany:

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

Tokeny wznowienia

Gdy zadanie już istnieje, błąd niesie token wznowienia obok klucza idempotentności. Oczekiwanie, które się wyczerpie, zgłasza WaitTimeoutError z tokenem, a zadanie nadal trwa. Przekaż token z powrotem do resume(), aby kontynuować bez drugiego obciążenia: zadanie po etapie przesyłania nie potrzebuje pliku, a to, które jeszcze się przesyła, jest kontynuowane z tym samym plikiem. W PHP:

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

W CLI naciśnięcie Ctrl-C podczas transcribe wypisuje token wznowienia zadania i polecenie, które je kontynuuje:

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

Logowanie i ukrywanie danych

SDK nie wysyłają telemetrii; jedyną identyfikacją klienta jest nagłówek User-Agent. Logowanie jest domyślnie wyłączone. HUSHSCRIPT_LOG=debug zapisuje na standardowym wyjściu błędów jedną linię na żądanie, z metodą, ścieżką, statusem i czasem, i nigdy z nagłówkiem, treścią, tytułem ani tekstem transkrypcji.

Token jest ukrywany w każdym błędzie, linii logu i wypisanej postaci klienta. W komunikatach błędów, podpowiedziach i przyczynach adres URL zachowuje host i ścieżkę, ale jego ciąg zapytania zmienia się w ?[redacted], więc podpisany adres przesyłania nigdy się nie wypisze. Wyniki, które przekazują ci sekret, takie jak sekret odbioru lub nowy token, zachowują go jako czytelne pole, ale po wypisaniu pokazują [redacted]; eksport JSON jest twój i zawiera tę wartość. CLI usuwa ze stderr każdy znany mu token; jego wyniki na stdout to twoje dane wyjściowe i nie są czyszczone.

Konfiguracja

Ustawienie Zmienna środowiskowa Domyślnie
Token HUSHSCRIPT_TOKEN brak
Bazowy adres URL HUSHSCRIPT_BASE_URL https://api.hushscript.com
Poziom logowania HUSHSCRIPT_LOG off
Limit czasu żądania brak 60 sekund
Ponowienia brak 3

Opcja podana w kodzie ma pierwszeństwo przed swoją zmienną środowiskową, a pusta wartość jest traktowana jak nieustawiona. Minuty pochodzą z tego samego salda co w aplikacji; pakiety i ceny znajdziesz na stronie cennika.

Zacznij transkrybować z 30 bezpłatnymi minutami

Sprawdź podgląd do 5 minut, zanim utworzysz konto, a nowe konto osobiste otrzymuje bezpłatny podgląd pierwszego pliku przesłanego w aplikacji. Pełna transkrypcja wymaga konta i minut; konta osobiste spełniające warunki jednorazowo dostają 30 bezpłatnych minut, po weryfikacji karty lub przy pierwszym zakupie. Bez abonamentu.

Otrzymaj 30 bezpłatnych minut