Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ aai.settings.api_key = "your-key"
- `aai.TranscriptionConfig` — All transcription options: `speech_models`, `speaker_labels`, `sentiment_analysis`, `entity_detection`, `auto_chapters`, `content_safety`, `language_detection`, `summarization`, `word_boost`, `disfluencies`
- `aai.Transcript` — Result object with `.text`, `.status`, `.utterances`, `.words`, `.chapters`, `.entities`, `.sentiment_analysis`. Methods: `get_sentences()`, `get_paragraphs()`, `export_subtitles_srt()`, `export_subtitles_vtt()`
- `aai.SyncTranscriber` — Synchronous pre-recorded transcription: audio in, transcript out, one request (no polling). Methods: `transcribe()`, `transcribe_async()`
- `aai.SyncTranscriptionConfig` — Sync options: `model` (default `u3-sync-pro`), `prompt`, `keyterms_prompt`, `conversation_context`, `language_codes`, `timestamps`, `sample_rate`, `channels`
- `aai.SyncTranscriptionConfig` — Sync options: `model` (default `universal-3-5-pro`), `prompt`, `keyterms_prompt`, `conversation_context`, `language_codes`, `timestamps`, `sample_rate`, `channels`
- `aai.SyncTranscriptResponse` — Sync result: `.text`, `.words` (`SyncWord` with `confidence` always, `start`/`end` only when `timestamps=True`), `.confidence`, `.audio_duration_ms`, `.session_id`, `.request_time_ms`
- `assemblyai.streaming.v3.StreamingClient` — Real-time streaming with event-based API (threaded)
- `assemblyai.streaming.v3.AsyncStreamingClient` — Asyncio-native counterpart; same options/events
Expand Down Expand Up @@ -161,8 +161,8 @@ server (`bad_audio`, `audio_too_short`, `audio_too_large`, `capacity_exceeded`,
`inference_timeout`, …) — and `.retry_after` (seconds) on 429/503. Audio limits: 80 ms–120 s,
≤40 MB, 16-bit, mono/stereo, sample rate ∈ {8000, 16000, 22050, 24000, 32000, 44100, 48000}.

**Model**: `config.model` defaults to `"u3-sync-pro"` and is sent as the `X-AAI-Model`
routing header (`aai.SyncSpeechModel.u3_sync_pro`).
**Model**: `config.model` defaults to `"universal-3-5-pro"` and is sent as the `X-AAI-Model`
routing header (`aai.SyncSpeechModel.universal_3_5_pro`).

**Pre-warming the connection**: the sync API is one request/response, so a `transcribe()`
that connects on demand pays the full DNS + TCP + TLS handshake on the critical path —
Expand Down
130 changes: 130 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -388,6 +388,136 @@ while page.page_details.before_id_of_prev_url is not None:

---

### **Sync STT Transcription Examples**

`aai.SyncTranscriber` posts a whole audio file and returns the finished transcript in one round trip — no job id, no polling, no status to check. Use it for short clips where you want the answer inline; use `aai.Transcriber` for long-form audio, URLs, or the rich audio-intelligence features (speaker labels, chapters, sentiment, …) the sync API doesn't expose.

<details>
<summary>Transcribe a local file synchronously</summary>

```python
import assemblyai as aai

aai.settings.api_key = "<YOUR_API_KEY>"

result = aai.SyncTranscriber().transcribe("./call.wav")

print(result.text)
for word in result.words:
print(word.text, word.confidence)
```

The input can be a local file path, raw `bytes`, or a binary file object — but not a URL. Pass a path/bytes, or use `aai.Transcriber` for URL ingestion.

</details>

<details>
<summary>Configure the transcription</summary>

```python
import assemblyai as aai

aai.settings.api_key = "<YOUR_API_KEY>"

config = aai.SyncTranscriptionConfig(
prompt="Transcribe verbatim. Preserve disfluencies.", # max 4096 chars
keyterms_prompt=["AssemblyAI", "Lemur", "U3-Pro"], # max 2048 chars total
conversation_context=[
# prior turns from the same conversation, oldest first
"I'd like to book a flight to Denver.",
"Sure, what date were you thinking?",
],
)

result = aai.SyncTranscriber().transcribe("./call.wav", config=config)
print(result.text)
```

Raw S16LE PCM audio needs `sample_rate` and `channels`; WAV reads them from its header.

```python
config = aai.SyncTranscriptionConfig(sample_rate=16000, channels=1)
result = aai.SyncTranscriber().transcribe(raw_pcm_bytes, config=config)
```

</details>

<details>
<summary>Set the transcription language</summary>

`language_codes` steers the model toward one or more languages — a single-element list for monolingual audio, or several codes for multilingual audio. It is mutually exclusive with `prompt`; pass one or the other, not both.

```python
import assemblyai as aai

aai.settings.api_key = "<YOUR_API_KEY>"

config = aai.SyncTranscriptionConfig(language_codes=["es"]) # or ["en", "es"] for multilingual
result = aai.SyncTranscriber().transcribe("./call.wav", config=config)
print(result.text)
```

</details>

<details>
<summary>Get word timestamps</summary>

Word timestamps are opt-in. By default each word carries `text` and `confidence` only — `start`/`end` are `None`. Set `timestamps=True` to compute accurate per-word timings at a small latency cost.

```python
import assemblyai as aai

aai.settings.api_key = "<YOUR_API_KEY>"

config = aai.SyncTranscriptionConfig(timestamps=True)
result = aai.SyncTranscriber().transcribe("./call.wav", config=config)

for word in result.words:
print(word.text, word.start, word.end) # milliseconds
```

</details>

<details>
<summary>Pre-warm the connection</summary>

The sync API is a single request/response, so a `transcribe()` that connects on demand pays the full DNS + TCP + TLS handshake on the critical path. Call `warm()` as soon as you know audio is coming — for example while it is still being recorded — so the next `transcribe()` reuses the open connection.

```python
import assemblyai as aai

aai.settings.api_key = "<YOUR_API_KEY>"

with aai.SyncTranscriber() as transcriber:
transcriber.warm() # fire as recording starts
audio = record_until_done()
result = transcriber.transcribe(audio) # reuses the hot connection
print(result.text)
```

</details>

<details>
<summary>Handle errors</summary>

Failures raise `aai.SyncTranscriptError` with the HTTP `status_code`, a machine-readable `error_code` (`bad_audio`, `audio_too_short`, `audio_too_large`, `capacity_exceeded`, …), and `retry_after` (seconds) on 429/503 responses.

```python
import assemblyai as aai

aai.settings.api_key = "<YOUR_API_KEY>"

try:
result = aai.SyncTranscriber().transcribe("./call.wav")
print(result.text)
except aai.SyncTranscriptError as error:
print(error.status_code, error.error_code, error.retry_after)
```

</details>

---

### **Speech Understanding Examples**

<details>
Expand Down
2 changes: 1 addition & 1 deletion assemblyai/__version__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = "0.64.29"
__version__ = "0.64.31"
10 changes: 5 additions & 5 deletions assemblyai/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -3021,7 +3021,7 @@ def _normalize_conversation_context(v):
class SyncSpeechModel(str, Enum):
"""Speech models available on the synchronous transcription API."""

u3_sync_pro = "u3-sync-pro"
universal_3_5_pro = "universal-3-5-pro"


class SyncTranscriptionConfig(BaseModel):
Expand All @@ -3035,7 +3035,7 @@ class SyncTranscriptionConfig(BaseModel):
sent as the `X-AAI-Model` routing header, not in the request body.
"""

model: str = SyncSpeechModel.u3_sync_pro.value
model: str = SyncSpeechModel.universal_3_5_pro.value
"The sync speech model to route to. Sent as the `X-AAI-Model` header."

prompt: Optional[str] = Field(default=None, max_length=_SYNC_MAX_PROMPT_LEN)
Expand All @@ -3059,9 +3059,9 @@ class SyncTranscriptionConfig(BaseModel):
language_codes: Optional[List[str]] = None
"""ISO 639-1 codes for the language(s) of the audio — a single-element
list (e.g. `["es"]`) for monolingual audio, or several codes (e.g.
`["en", "es"]`) for multilingual audio. Steers the default transcription
prompt toward the named language(s); ignored when `prompt` is set.
Defaults to English. Supported: en, es, de, fr, it, pt, tr, nl, sv, no,
`["en", "es"]`) for multilingual audio. Overrides the default prompt
to guide the model to the named language(s); ignored when `prompt` is set.
Defaults to None. Supported: en, es, de, fr, it, pt, tr, nl, sv, no,
da, fi, hi, vi, ar, he, ja, ur, zh."""

sample_rate: Optional[int] = None
Expand Down
Loading