soniox 2.3.1__tar.gz → 2.4.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- soniox-2.4.0/.claude/settings.local.json +15 -0
- soniox-2.4.0/.gitignore +15 -0
- {soniox-2.3.1 → soniox-2.4.0}/CHANGELOG.md +43 -9
- {soniox-2.3.1 → soniox-2.4.0}/PKG-INFO +28 -15
- {soniox-2.3.1 → soniox-2.4.0}/README.md +19 -12
- {soniox-2.3.1 → soniox-2.4.0}/docs/async_client.md +49 -1
- {soniox-2.3.1 → soniox-2.4.0}/docs/realtime_client.md +48 -22
- {soniox-2.3.1 → soniox-2.4.0}/docs/types.md +348 -11
- soniox-2.4.0/docs/utils.md +201 -0
- {soniox-2.3.1 → soniox-2.4.0}/examples/async_soniox_client/tts_realtime_multiplexed_example.py +1 -1
- {soniox-2.3.1 → soniox-2.4.0}/justfile +25 -0
- {soniox-2.3.1 → soniox-2.4.0}/pyproject.toml +51 -6
- {soniox-2.3.1 → soniox-2.4.0}/scripts/generate_docs.py +29 -6
- {soniox-2.3.1 → soniox-2.4.0}/src/soniox/api/__init__.py +8 -0
- {soniox-2.3.1 → soniox-2.4.0}/src/soniox/api/async_auth.py +4 -0
- soniox-2.4.0/src/soniox/api/async_concurrency_limits.py +30 -0
- {soniox-2.3.1 → soniox-2.4.0}/src/soniox/api/async_files.py +13 -0
- {soniox-2.3.1 → soniox-2.4.0}/src/soniox/api/async_stt.py +13 -0
- {soniox-2.3.1 → soniox-2.4.0}/src/soniox/api/async_tts.py +1 -2
- soniox-2.4.0/src/soniox/api/async_usage_logs.py +77 -0
- {soniox-2.3.1 → soniox-2.4.0}/src/soniox/api/auth.py +4 -0
- soniox-2.4.0/src/soniox/api/concurrency_limits.py +30 -0
- {soniox-2.3.1 → soniox-2.4.0}/src/soniox/api/files.py +13 -0
- {soniox-2.3.1 → soniox-2.4.0}/src/soniox/api/stt.py +13 -0
- {soniox-2.3.1 → soniox-2.4.0}/src/soniox/api/tts.py +1 -2
- soniox-2.4.0/src/soniox/api/usage_logs.py +76 -0
- {soniox-2.3.1 → soniox-2.4.0}/src/soniox/client.py +28 -0
- {soniox-2.3.1 → soniox-2.4.0}/src/soniox/errors.py +5 -2
- soniox-2.4.0/src/soniox/py.typed +0 -0
- {soniox-2.3.1 → soniox-2.4.0}/src/soniox/realtime/async_stt.py +23 -11
- {soniox-2.3.1 → soniox-2.4.0}/src/soniox/realtime/async_tts.py +5 -5
- {soniox-2.3.1 → soniox-2.4.0}/src/soniox/realtime/stt.py +23 -11
- {soniox-2.3.1 → soniox-2.4.0}/src/soniox/realtime/tts.py +5 -5
- {soniox-2.3.1 → soniox-2.4.0}/src/soniox/types/__init__.py +48 -0
- {soniox-2.3.1 → soniox-2.4.0}/src/soniox/types/api.py +244 -17
- {soniox-2.3.1 → soniox-2.4.0}/src/soniox/types/realtime.py +35 -7
- {soniox-2.3.1 → soniox-2.4.0}/src/soniox/utils.py +14 -5
- soniox-2.4.0/tests/__init__.py +0 -0
- soniox-2.4.0/tests/conftest.py +26 -0
- soniox-2.4.0/tests/data/openapi.json +1 -0
- soniox-2.4.0/tests/helpers.py +43 -0
- soniox-2.4.0/tests/realtime/__init__.py +0 -0
- soniox-2.4.0/tests/realtime/cases.py +84 -0
- soniox-2.4.0/tests/realtime/mock_ws.py +148 -0
- soniox-2.4.0/tests/realtime/test_async_tts_realtime.py +732 -0
- soniox-2.4.0/tests/realtime/test_chaos_realtime.py +157 -0
- soniox-2.4.0/tests/realtime/test_fuzz_realtime.py +98 -0
- soniox-2.4.0/tests/realtime/test_keepalive.py +118 -0
- soniox-2.4.0/tests/realtime/test_live_ws.py +267 -0
- soniox-2.4.0/tests/realtime/test_stt_realtime.py +433 -0
- soniox-2.4.0/tests/realtime/test_tts_realtime.py +688 -0
- soniox-2.4.0/tests/unit/__init__.py +0 -0
- soniox-2.4.0/tests/unit/_openapi.py +87 -0
- soniox-2.4.0/tests/unit/_sdk_bindings.py +215 -0
- soniox-2.4.0/tests/unit/test_api.py +250 -0
- soniox-2.4.0/tests/unit/test_async_client.py +231 -0
- soniox-2.4.0/tests/unit/test_async_stt_workflows.py +317 -0
- soniox-2.4.0/tests/unit/test_async_tts_workflows.py +111 -0
- soniox-2.4.0/tests/unit/test_client.py +196 -0
- soniox-2.4.0/tests/unit/test_concurrency_limits.py +58 -0
- soniox-2.4.0/tests/unit/test_coverage_gaps.py +174 -0
- soniox-2.4.0/tests/unit/test_schema_drift.py +94 -0
- soniox-2.4.0/tests/unit/test_stt_extras.py +151 -0
- soniox-2.4.0/tests/unit/test_stt_workflows.py +322 -0
- soniox-2.4.0/tests/unit/test_sync_async_parity.py +138 -0
- soniox-2.4.0/tests/unit/test_tts_workflows.py +115 -0
- soniox-2.4.0/tests/unit/test_usage_logs.py +166 -0
- soniox-2.4.0/tests/unit/test_utils.py +266 -0
- soniox-2.4.0/tests/unit/test_webhooks.py +139 -0
- {soniox-2.3.1 → soniox-2.4.0}/uv.lock +338 -5
- soniox-2.3.1/.gitignore +0 -3
- soniox-2.3.1/docs/soniox/__init__.md +0 -282
- soniox-2.3.1/docs/soniox/api/__init__.md +0 -1968
- soniox-2.3.1/docs/soniox/api/api__utils.md +0 -112
- soniox-2.3.1/docs/soniox/api/api_async_auth.md +0 -61
- soniox-2.3.1/docs/soniox/api/api_async_files.md +0 -239
- soniox-2.3.1/docs/soniox/api/api_async_models.md +0 -55
- soniox-2.3.1/docs/soniox/api/api_async_stt.md +0 -595
- soniox-2.3.1/docs/soniox/api/api_async_transcriptions.md +0 -546
- soniox-2.3.1/docs/soniox/api/api_async_webhooks.md +0 -10
- soniox-2.3.1/docs/soniox/api/api_auth.md +0 -61
- soniox-2.3.1/docs/soniox/api/api_files.md +0 -239
- soniox-2.3.1/docs/soniox/api/api_models.md +0 -55
- soniox-2.3.1/docs/soniox/api/api_stt.md +0 -595
- soniox-2.3.1/docs/soniox/api/api_transcriptions.md +0 -546
- soniox-2.3.1/docs/soniox/api/api_webhooks.md +0 -152
- soniox-2.3.1/docs/soniox/realtime/__init__.md +0 -1148
- soniox-2.3.1/docs/soniox/realtime/realtime__utils.md +0 -194
- soniox-2.3.1/docs/soniox/realtime/realtime_async_stt.md +0 -548
- soniox-2.3.1/docs/soniox/realtime/realtime_stt.md +0 -546
- soniox-2.3.1/docs/soniox/soniox_client.md +0 -346
- soniox-2.3.1/docs/soniox/soniox_errors.md +0 -204
- soniox-2.3.1/docs/soniox/soniox_utils.md +0 -195
- soniox-2.3.1/docs/soniox/types/__init__.md +0 -532
- soniox-2.3.1/docs/soniox/types/types_api.md +0 -400
- soniox-2.3.1/docs/soniox/types/types_common.md +0 -34
- soniox-2.3.1/docs/soniox/types/types_realtime.md +0 -112
- soniox-2.3.1/docs/soniox/types/types_webhooks.md +0 -30
- {soniox-2.3.1 → soniox-2.4.0}/LICENSE +0 -0
- {soniox-2.3.1 → soniox-2.4.0}/assets/coffee_shop.mp3 +0 -0
- {soniox-2.3.1 → soniox-2.4.0}/assets/coffee_shop.pcm_s16le +0 -0
- {soniox-2.3.1 → soniox-2.4.0}/assets/two_way_translation.mp3 +0 -0
- {soniox-2.3.1 → soniox-2.4.0}/assets/two_way_translation.pcm_s16le +0 -0
- {soniox-2.3.1 → soniox-2.4.0}/examples/async_soniox_client/api_example.py +0 -0
- {soniox-2.3.1 → soniox-2.4.0}/examples/async_soniox_client/realtime_example.py +0 -0
- {soniox-2.3.1 → soniox-2.4.0}/examples/async_soniox_client/tts_api_example.py +0 -0
- {soniox-2.3.1 → soniox-2.4.0}/examples/async_soniox_client/tts_realtime_example.py +0 -0
- {soniox-2.3.1 → soniox-2.4.0}/examples/soniox_client/api_example.py +0 -0
- {soniox-2.3.1 → soniox-2.4.0}/examples/soniox_client/realtime_example.py +0 -0
- {soniox-2.3.1 → soniox-2.4.0}/examples/soniox_client/tts_api_example.py +0 -0
- {soniox-2.3.1 → soniox-2.4.0}/examples/soniox_client/tts_realtime_example.py +0 -0
- {soniox-2.3.1 → soniox-2.4.0}/examples/soniox_client/tts_realtime_multiplexed_example.py +0 -0
- {soniox-2.3.1 → soniox-2.4.0}/src/soniox/__init__.py +0 -0
- {soniox-2.3.1 → soniox-2.4.0}/src/soniox/api/_utils.py +0 -0
- {soniox-2.3.1 → soniox-2.4.0}/src/soniox/api/async_models.py +0 -0
- {soniox-2.3.1 → soniox-2.4.0}/src/soniox/api/async_tts_models.py +0 -0
- {soniox-2.3.1 → soniox-2.4.0}/src/soniox/api/async_webhooks.py +0 -0
- {soniox-2.3.1 → soniox-2.4.0}/src/soniox/api/models.py +0 -0
- {soniox-2.3.1 → soniox-2.4.0}/src/soniox/api/tts_models.py +0 -0
- {soniox-2.3.1 → soniox-2.4.0}/src/soniox/api/webhooks.py +0 -0
- {soniox-2.3.1 → soniox-2.4.0}/src/soniox/realtime/__init__.py +0 -0
- {soniox-2.3.1 → soniox-2.4.0}/src/soniox/realtime/_constants.py +0 -0
- {soniox-2.3.1 → soniox-2.4.0}/src/soniox/realtime/_utils.py +0 -0
- {soniox-2.3.1 → soniox-2.4.0}/src/soniox/types/common.py +0 -0
- {soniox-2.3.1 → soniox-2.4.0}/src/soniox/types/webhooks.py +0 -0
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"permissions": {
|
|
3
|
+
"allow": [
|
|
4
|
+
"Bash(uv run *)",
|
|
5
|
+
"Bash(just test *)",
|
|
6
|
+
"Bash(/home/miha/workspace/soniox_python_sdk/.venv/bin/python *)",
|
|
7
|
+
"Bash(git apply *)",
|
|
8
|
+
"Bash(git add *)",
|
|
9
|
+
"Bash(sed -n '110,140p' tests/unit/test_client.py)",
|
|
10
|
+
"Bash(sed -n '85,120p' tests/unit/test_async_client.py)",
|
|
11
|
+
"Bash(/tmp/soniox-v240-test/.venv/bin/python -u test_schema_sync.py)",
|
|
12
|
+
"Bash(awk '/^class Transcription\\\\b/,/^class [A-Z]/' src/soniox/types/api.py)"
|
|
13
|
+
]
|
|
14
|
+
}
|
|
15
|
+
}
|
soniox-2.4.0/.gitignore
ADDED
|
@@ -21,12 +21,12 @@ The format is inspired by Keep a Changelog and this project follows Semantic Ver
|
|
|
21
21
|
|
|
22
22
|
Use the following categories when adding entries:
|
|
23
23
|
|
|
24
|
-
- **Added**
|
|
25
|
-
- **Changed**
|
|
26
|
-
- **Deprecated**
|
|
27
|
-
- **Removed**
|
|
28
|
-
- **Fixed**
|
|
29
|
-
- **Security**
|
|
24
|
+
- **Added** - new features or capabilities.
|
|
25
|
+
- **Changed** - updates to existing functionality.
|
|
26
|
+
- **Deprecated** - features that will be removed soon.
|
|
27
|
+
- **Removed** - features removed in this version.
|
|
28
|
+
- **Fixed** - bug fixes.
|
|
29
|
+
- **Security** - vulnerability fixes.
|
|
30
30
|
|
|
31
31
|
---
|
|
32
32
|
|
|
@@ -53,9 +53,9 @@ This project follows Semantic Versioning:
|
|
|
53
53
|
|
|
54
54
|
Examples:
|
|
55
55
|
|
|
56
|
-
- `1.0.0`
|
|
57
|
-
- `1.1.0`
|
|
58
|
-
- `1.1.1`
|
|
56
|
+
- `1.0.0` - stable API
|
|
57
|
+
- `1.1.0` - new features added
|
|
58
|
+
- `1.1.1` - bug fixes only
|
|
59
59
|
|
|
60
60
|
---
|
|
61
61
|
|
|
@@ -77,6 +77,40 @@ Examples:
|
|
|
77
77
|
|
|
78
78
|
---
|
|
79
79
|
|
|
80
|
+
## [2.4.0] - 13 may 2026
|
|
81
|
+
|
|
82
|
+
### Added
|
|
83
|
+
|
|
84
|
+
- `client.files.count()` and `client.stt.count()` endpoints (and async variants) returning the total count of files and transcriptions.
|
|
85
|
+
- `client.usage_logs.list()` and `list_all()` (and async variants) for retrieving per-request usage logs over a time window.
|
|
86
|
+
- `client.concurrency_limits.get()` (and async variant) returning current and configured concurrency limits for realtime STT and TTS, scoped to project and organization.
|
|
87
|
+
- `TtsVoice.description` and `TtsVoice.gender` (`"male" | "female" | "neutral"`) fields, exposing richer voice metadata from the server. Enables programmatic voice filtering.
|
|
88
|
+
- `RealtimeSTTAudioFormat`, `RealtimeSTTHeaderFormat`, `RealtimeSTTRawFormat` literal types covering the 30 audio formats accepted by realtime STT.
|
|
89
|
+
- `py.typed` marker (PEP 561): downstream type-checkers now consume the SDK's inline type annotations.
|
|
90
|
+
- `StructuredContext.general` and `StructuredContext.translation_terms` now accept a plain dict in addition to the typed item lists.
|
|
91
|
+
- `finalize: bool = True` keyword-only parameter on realtime STT `pause()` (sync and async). When `False`, pause without emitting a finalize.
|
|
92
|
+
- `TtsModel.languages` field listing the languages supported by the model. Defaults to an empty list for backward compatibility with direct construction.
|
|
93
|
+
- `Language` type exported from `soniox.types` (previously only reachable via `soniox.types.api`).
|
|
94
|
+
- `ApiError.more_info` field - optional URL pointing to documentation for resolving an error.
|
|
95
|
+
- `Model.supports_max_endpoint_delay` flag indicating whether a model supports the `max_endpoint_delay_ms` option.
|
|
96
|
+
- Internal test suite (pytest + respx + polyfactory) covering REST, realtime websocket, schema drift, and sync/async parity. Not shipped to users; runnable via `just test`.
|
|
97
|
+
|
|
98
|
+
### Changed
|
|
99
|
+
|
|
100
|
+
- `RealtimeSTTConfig.audio_format` is now typed as a Literal union instead of bare `str`. Passing an unrecognized value raises at validation time instead of failing on the wire.
|
|
101
|
+
- Raw realtime STT audio formats (`pcm_*`, `mulaw`, `alaw`) now require `sample_rate` and `num_channels` on `RealtimeSTTConfig`. Previously these were silently accepted client-side and rejected by the server.
|
|
102
|
+
|
|
103
|
+
---
|
|
104
|
+
|
|
105
|
+
## [2.3.2] - 4 may 2026
|
|
106
|
+
|
|
107
|
+
### Added
|
|
108
|
+
|
|
109
|
+
- `single_use` and `max_session_duration_seconds` parameters on `client.auth.create_temporary_api_key()` (and the async variant).
|
|
110
|
+
- `tts_rt` value for `TemporaryApiKeyUsageType`, allowing temporary API keys to be scoped to realtime TTS.
|
|
111
|
+
|
|
112
|
+
---
|
|
113
|
+
|
|
80
114
|
## [2.3.1] - 29 apr 2026
|
|
81
115
|
|
|
82
116
|
### Changed
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: soniox
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.4.0
|
|
4
4
|
Summary: The official Python SDK for the Soniox API (STT, REST)
|
|
5
|
-
Project-URL: Homepage, https://
|
|
5
|
+
Project-URL: Homepage, https://soniox.com
|
|
6
6
|
Project-URL: Documentation, https://soniox.com/docs
|
|
7
7
|
Project-URL: Repository, https://github.com/soniox/soniox-python
|
|
8
8
|
Author-email: Soniox <support@soniox.com>
|
|
@@ -31,13 +31,20 @@ Requires-Dist: pydantic>2
|
|
|
31
31
|
Requires-Dist: websockets>11.0
|
|
32
32
|
Provides-Extra: dev
|
|
33
33
|
Requires-Dist: griffe>=1.15.0; extra == 'dev'
|
|
34
|
-
Requires-Dist:
|
|
34
|
+
Requires-Dist: polyfactory>=2.15.0; extra == 'dev'
|
|
35
|
+
Requires-Dist: pyright>=1.1.409; extra == 'dev'
|
|
36
|
+
Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
|
|
37
|
+
Requires-Dist: pytest-cov>=5.0; extra == 'dev'
|
|
38
|
+
Requires-Dist: pytest-timeout>=2.3; extra == 'dev'
|
|
39
|
+
Requires-Dist: pytest>=8.0.0; extra == 'dev'
|
|
40
|
+
Requires-Dist: respx>=0.21.1; extra == 'dev'
|
|
35
41
|
Requires-Dist: ruff>=0.0.0; extra == 'dev'
|
|
36
42
|
Description-Content-Type: text/markdown
|
|
37
43
|
|
|
38
44
|
# Soniox Python SDK
|
|
39
45
|
|
|
40
46
|
The SDK exposes two clients: `SonioxClient` (sync) and `AsyncSonioxClient` (async). Each client supports:
|
|
47
|
+
|
|
41
48
|
- STT over REST (`client.stt`) and realtime WebSocket (`client.realtime.stt`)
|
|
42
49
|
- TTS over REST (`client.tts`) and realtime WebSocket (`client.realtime.tts`)
|
|
43
50
|
- auth, file uploads, model listing, webhooks, and typed request/response models
|
|
@@ -53,20 +60,23 @@ export SONIOX_API_KEY=<your-key>
|
|
|
53
60
|
|
|
54
61
|
Get your API key from the [Soniox Console](https://console.soniox.com) and inject it once per shell session. Both clients read `SONIOX_API_KEY` by default, but you can override it per-client if needed.
|
|
55
62
|
|
|
63
|
+
> **Avoid Python 3.13.6** - it has a regression in `ssl` that hangs realtime STT/TTS (CPython issue [#137583](https://github.com/python/cpython/issues/137583)). Use any other 3.10-3.13.x.
|
|
64
|
+
|
|
56
65
|
## Quick run (STT + TTS, REST + realtime)
|
|
57
66
|
|
|
58
|
-
1. **REST STT transcription**:
|
|
67
|
+
1. **REST STT transcription**: transcribe a local file end-to-end in one call. Full example: [`examples/soniox_client/api_example.py`](https://github.com/soniox/soniox-python/blob/main/examples/soniox_client/api_example.py).
|
|
59
68
|
|
|
60
69
|
```python
|
|
61
70
|
from soniox import SonioxClient
|
|
62
71
|
|
|
63
72
|
client = SonioxClient()
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
73
|
+
transcript = client.stt.transcribe_and_wait_with_tokens(
|
|
74
|
+
file="path/to/audio.mp3", # local file
|
|
75
|
+
# audio_url="https://example.com/audio.mp3", # or remote URL
|
|
76
|
+
delete_after=True, # auto-cleanup file + transcription
|
|
67
77
|
)
|
|
68
|
-
|
|
69
|
-
|
|
78
|
+
print(transcript.text)
|
|
79
|
+
client.close()
|
|
70
80
|
```
|
|
71
81
|
|
|
72
82
|
2. **REST TTS generation**: convert text to an audio file.
|
|
@@ -118,17 +128,19 @@ def realtime():
|
|
|
118
128
|
non_final_tokens.clear()
|
|
119
129
|
|
|
120
130
|
realtime()
|
|
131
|
+
client.close()
|
|
121
132
|
```
|
|
122
133
|
|
|
123
134
|
See [`examples/soniox_client/realtime_example.py`](https://github.com/soniox/soniox-python/blob/main/examples/soniox_client/realtime_example.py) for the full flow.
|
|
124
135
|
|
|
125
|
-
4. **Realtime TTS streaming**: send text chunks and
|
|
136
|
+
4. **Realtime TTS streaming**: send text chunks and write audio to a file as it arrives.
|
|
126
137
|
|
|
127
138
|
```python
|
|
128
139
|
from uuid import uuid4
|
|
129
140
|
|
|
130
141
|
from soniox import SonioxClient
|
|
131
142
|
from soniox.types import RealtimeTTSConfig
|
|
143
|
+
from soniox.utils import output_file_for_audio_format
|
|
132
144
|
|
|
133
145
|
client = SonioxClient()
|
|
134
146
|
config = RealtimeTTSConfig(
|
|
@@ -139,17 +151,18 @@ config = RealtimeTTSConfig(
|
|
|
139
151
|
audio_format="wav",
|
|
140
152
|
)
|
|
141
153
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
154
|
+
output_file = output_file_for_audio_format("wav", "tts_realtime_output")
|
|
155
|
+
bytes_written = 0
|
|
156
|
+
with client.realtime.tts.connect(config=config) as session, output_file.open("wb") as f:
|
|
145
157
|
session.send_text_chunks(
|
|
146
158
|
["Hello from realtime TTS. ", "This is the final chunk."],
|
|
147
159
|
text_end=True,
|
|
148
160
|
)
|
|
149
161
|
for chunk in session.receive_audio_chunks():
|
|
150
|
-
|
|
162
|
+
f.write(chunk)
|
|
163
|
+
bytes_written += len(chunk)
|
|
151
164
|
|
|
152
|
-
print(f"
|
|
165
|
+
print(f"Wrote {bytes_written} bytes to {output_file.resolve()}")
|
|
153
166
|
```
|
|
154
167
|
|
|
155
168
|
Run the full example at [`examples/soniox_client/tts_realtime_example.py`](https://github.com/soniox/soniox-python/blob/main/examples/soniox_client/tts_realtime_example.py) or async version at [`examples/async_soniox_client/tts_realtime_example.py`](https://github.com/soniox/soniox-python/blob/main/examples/async_soniox_client/tts_realtime_example.py).
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# Soniox Python SDK
|
|
2
2
|
|
|
3
3
|
The SDK exposes two clients: `SonioxClient` (sync) and `AsyncSonioxClient` (async). Each client supports:
|
|
4
|
+
|
|
4
5
|
- STT over REST (`client.stt`) and realtime WebSocket (`client.realtime.stt`)
|
|
5
6
|
- TTS over REST (`client.tts`) and realtime WebSocket (`client.realtime.tts`)
|
|
6
7
|
- auth, file uploads, model listing, webhooks, and typed request/response models
|
|
@@ -16,20 +17,23 @@ export SONIOX_API_KEY=<your-key>
|
|
|
16
17
|
|
|
17
18
|
Get your API key from the [Soniox Console](https://console.soniox.com) and inject it once per shell session. Both clients read `SONIOX_API_KEY` by default, but you can override it per-client if needed.
|
|
18
19
|
|
|
20
|
+
> **Avoid Python 3.13.6** - it has a regression in `ssl` that hangs realtime STT/TTS (CPython issue [#137583](https://github.com/python/cpython/issues/137583)). Use any other 3.10-3.13.x.
|
|
21
|
+
|
|
19
22
|
## Quick run (STT + TTS, REST + realtime)
|
|
20
23
|
|
|
21
|
-
1. **REST STT transcription**:
|
|
24
|
+
1. **REST STT transcription**: transcribe a local file end-to-end in one call. Full example: [`examples/soniox_client/api_example.py`](https://github.com/soniox/soniox-python/blob/main/examples/soniox_client/api_example.py).
|
|
22
25
|
|
|
23
26
|
```python
|
|
24
27
|
from soniox import SonioxClient
|
|
25
28
|
|
|
26
29
|
client = SonioxClient()
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
+
transcript = client.stt.transcribe_and_wait_with_tokens(
|
|
31
|
+
file="path/to/audio.mp3", # local file
|
|
32
|
+
# audio_url="https://example.com/audio.mp3", # or remote URL
|
|
33
|
+
delete_after=True, # auto-cleanup file + transcription
|
|
30
34
|
)
|
|
31
|
-
|
|
32
|
-
|
|
35
|
+
print(transcript.text)
|
|
36
|
+
client.close()
|
|
33
37
|
```
|
|
34
38
|
|
|
35
39
|
2. **REST TTS generation**: convert text to an audio file.
|
|
@@ -81,17 +85,19 @@ def realtime():
|
|
|
81
85
|
non_final_tokens.clear()
|
|
82
86
|
|
|
83
87
|
realtime()
|
|
88
|
+
client.close()
|
|
84
89
|
```
|
|
85
90
|
|
|
86
91
|
See [`examples/soniox_client/realtime_example.py`](https://github.com/soniox/soniox-python/blob/main/examples/soniox_client/realtime_example.py) for the full flow.
|
|
87
92
|
|
|
88
|
-
4. **Realtime TTS streaming**: send text chunks and
|
|
93
|
+
4. **Realtime TTS streaming**: send text chunks and write audio to a file as it arrives.
|
|
89
94
|
|
|
90
95
|
```python
|
|
91
96
|
from uuid import uuid4
|
|
92
97
|
|
|
93
98
|
from soniox import SonioxClient
|
|
94
99
|
from soniox.types import RealtimeTTSConfig
|
|
100
|
+
from soniox.utils import output_file_for_audio_format
|
|
95
101
|
|
|
96
102
|
client = SonioxClient()
|
|
97
103
|
config = RealtimeTTSConfig(
|
|
@@ -102,17 +108,18 @@ config = RealtimeTTSConfig(
|
|
|
102
108
|
audio_format="wav",
|
|
103
109
|
)
|
|
104
110
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
111
|
+
output_file = output_file_for_audio_format("wav", "tts_realtime_output")
|
|
112
|
+
bytes_written = 0
|
|
113
|
+
with client.realtime.tts.connect(config=config) as session, output_file.open("wb") as f:
|
|
108
114
|
session.send_text_chunks(
|
|
109
115
|
["Hello from realtime TTS. ", "This is the final chunk."],
|
|
110
116
|
text_end=True,
|
|
111
117
|
)
|
|
112
118
|
for chunk in session.receive_audio_chunks():
|
|
113
|
-
|
|
119
|
+
f.write(chunk)
|
|
120
|
+
bytes_written += len(chunk)
|
|
114
121
|
|
|
115
|
-
print(f"
|
|
122
|
+
print(f"Wrote {bytes_written} bytes to {output_file.resolve()}")
|
|
116
123
|
```
|
|
117
124
|
|
|
118
125
|
Run the full example at [`examples/soniox_client/tts_realtime_example.py`](https://github.com/soniox/soniox-python/blob/main/examples/soniox_client/tts_realtime_example.py) or async version at [`examples/async_soniox_client/tts_realtime_example.py`](https://github.com/soniox/soniox-python/blob/main/examples/async_soniox_client/tts_realtime_example.py).
|
|
@@ -47,6 +47,8 @@ AsyncSonioxClient(api_key: str | None = None, api_base_url: str | None = None, w
|
|
|
47
47
|
| `tts` | `AsyncTtsAPI` | Text-to-Speech API namespace |
|
|
48
48
|
| `models` | `AsyncModelsAPI` | List of available Text-to-Speech models. |
|
|
49
49
|
| `tts_models` | `AsyncTtsModelsAPI` | - |
|
|
50
|
+
| `usage_logs` | `AsyncUsageLogsAPI` | Per-request usage log entries ordered by end_time. |
|
|
51
|
+
| `concurrency_limits` | `AsyncConcurrencyLimitsAPI` | - |
|
|
50
52
|
| `auth` | `AsyncAuthAPI` | Authentication API namespace. |
|
|
51
53
|
| `webhooks` | `AsyncSonioxWebhooksAPI` | Webhook utilities API namespace. |
|
|
52
54
|
| `realtime` | `AsyncRealtimeAPI` | Entrypoint for async realtime helpers on AsyncSonioxClient. |
|
|
@@ -143,6 +145,28 @@ Performs a GET request to ``/files`` with optional pagination.
|
|
|
143
145
|
|
|
144
146
|
***
|
|
145
147
|
|
|
148
|
+
<a id="asyncfilesapi-count"></a>
|
|
149
|
+
|
|
150
|
+
### count()
|
|
151
|
+
|
|
152
|
+
```python
|
|
153
|
+
count() -> GetFilesCountResponse
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
Return a breakdown of uploaded file counts.
|
|
157
|
+
|
|
158
|
+
Performs a GET request to ``/files/count``.
|
|
159
|
+
|
|
160
|
+
**Returns**
|
|
161
|
+
|
|
162
|
+
`GetFilesCountResponse`
|
|
163
|
+
|
|
164
|
+
**Raises**
|
|
165
|
+
|
|
166
|
+
- `SonioxAPIError` When the API returns an error.
|
|
167
|
+
|
|
168
|
+
***
|
|
169
|
+
|
|
146
170
|
<a id="asyncfilesapi-list_all"></a>
|
|
147
171
|
|
|
148
172
|
### list_all()
|
|
@@ -390,6 +414,28 @@ Performs a GET request to ``/transcriptions`` with optional pagination.
|
|
|
390
414
|
|
|
391
415
|
***
|
|
392
416
|
|
|
417
|
+
<a id="asyncsttapi-count"></a>
|
|
418
|
+
|
|
419
|
+
### count()
|
|
420
|
+
|
|
421
|
+
```python
|
|
422
|
+
count() -> GetTranscriptionsCountResponse
|
|
423
|
+
```
|
|
424
|
+
|
|
425
|
+
Return a breakdown of transcription counts.
|
|
426
|
+
|
|
427
|
+
Performs a GET request to ``/transcriptions/count``.
|
|
428
|
+
|
|
429
|
+
**Returns**
|
|
430
|
+
|
|
431
|
+
`GetTranscriptionsCountResponse`
|
|
432
|
+
|
|
433
|
+
**Raises**
|
|
434
|
+
|
|
435
|
+
- `SonioxAPIError` When the API returns an error.
|
|
436
|
+
|
|
437
|
+
***
|
|
438
|
+
|
|
393
439
|
<a id="asyncsttapi-list_all"></a>
|
|
394
440
|
|
|
395
441
|
### list_all()
|
|
@@ -1129,7 +1175,7 @@ AsyncAuthAPI(client: AsyncSonioxClient)
|
|
|
1129
1175
|
### create_temporary_api_key()
|
|
1130
1176
|
|
|
1131
1177
|
```python
|
|
1132
|
-
create_temporary_api_key(*, usage_type: TemporaryApiKeyUsageType = 'transcribe_websocket', expires_in_seconds: int = 5 * 60, client_reference_id: str | None = None) -> CreateTemporaryApiKeyResponse
|
|
1178
|
+
create_temporary_api_key(*, usage_type: TemporaryApiKeyUsageType = 'transcribe_websocket', expires_in_seconds: int = 5 * 60, client_reference_id: str | None = None, single_use: bool | None = None, max_session_duration_seconds: int | None = None) -> CreateTemporaryApiKeyResponse
|
|
1133
1179
|
```
|
|
1134
1180
|
|
|
1135
1181
|
Create a temporary API key.
|
|
@@ -1143,6 +1189,8 @@ Performs a POST request to ``/auth/temporary-api-key``.
|
|
|
1143
1189
|
| `usage_type` | `TemporaryApiKeyUsageType` | Intended usage of the temporary API key. |
|
|
1144
1190
|
| `expires_in_seconds` | `int` | Duration in seconds until the temporary API key expires |
|
|
1145
1191
|
| `client_reference_id` | `str \| None` | Optional tracking identifier string. Does not need to be unique |
|
|
1192
|
+
| `single_use` | `bool \| None` | When true, restricts the temporary API key to a single use. |
|
|
1193
|
+
| `max_session_duration_seconds` | `int \| None` | Maximum connection duration in seconds for WebSocket and TTS HTTP streaming endpoints. |
|
|
1146
1194
|
|
|
1147
1195
|
**Returns**
|
|
1148
1196
|
|
|
@@ -184,10 +184,12 @@ is established when entering the context manager.
|
|
|
184
184
|
close() -> None
|
|
185
185
|
```
|
|
186
186
|
|
|
187
|
-
|
|
187
|
+
Close the realtime session and release the WebSocket.
|
|
188
188
|
|
|
189
|
-
|
|
190
|
-
|
|
189
|
+
Signals end-of-audio to the server and clears the underlying
|
|
190
|
+
connection. Subsequent calls are no-ops.
|
|
191
|
+
|
|
192
|
+
Called automatically when exiting the context manager.
|
|
191
193
|
|
|
192
194
|
**Returns**
|
|
193
195
|
|
|
@@ -234,17 +236,18 @@ send_bytes(chunks: bytes | Iterator[bytes], *, finish: bool = True) -> None
|
|
|
234
236
|
|
|
235
237
|
Send audio data to the realtime stream.
|
|
236
238
|
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
239
|
+
Accepts either a single bytes object or an iterator yielding byte
|
|
240
|
+
chunks (e.g. from `throttle_audio`). If `finish=True` (the default),
|
|
241
|
+
an end-of-audio signal is sent after the last chunk; pass
|
|
242
|
+
`finish=False` when you intend to send more audio later in the
|
|
243
|
+
same session.
|
|
241
244
|
|
|
242
245
|
**Parameters**
|
|
243
246
|
|
|
244
247
|
| Parameter | Type | Description |
|
|
245
248
|
| ------ | ------ | ------ |
|
|
246
|
-
| `chunks` | `bytes \| Iterator[bytes]` |
|
|
247
|
-
| `finish` | `bool` |
|
|
249
|
+
| `chunks` | `bytes \| Iterator[bytes]` | Raw bytes or an iterator of byte chunks. |
|
|
250
|
+
| `finish` | `bool` | If True (default), signal end-of-audio after the last chunk. |
|
|
248
251
|
|
|
249
252
|
**Returns**
|
|
250
253
|
|
|
@@ -289,7 +292,11 @@ end-of-audio or requesting finalization.
|
|
|
289
292
|
finish() -> None
|
|
290
293
|
```
|
|
291
294
|
|
|
292
|
-
Signal
|
|
295
|
+
Signal end-of-audio.
|
|
296
|
+
|
|
297
|
+
The server finalizes any pending tokens and closes the
|
|
298
|
+
connection. Continue iterating `receive_events()` to consume
|
|
299
|
+
the remaining tokens.
|
|
293
300
|
|
|
294
301
|
**Returns**
|
|
295
302
|
|
|
@@ -441,7 +448,7 @@ Receive realtime events and dispatch them to a handler callback.
|
|
|
441
448
|
### pause()
|
|
442
449
|
|
|
443
450
|
```python
|
|
444
|
-
pause() -> None
|
|
451
|
+
pause(*, finalize: bool = True) -> None
|
|
445
452
|
```
|
|
446
453
|
|
|
447
454
|
Pause the session, suppressing outgoing audio and starting a
|
|
@@ -454,6 +461,12 @@ timing out the session.
|
|
|
454
461
|
|
|
455
462
|
Calling `pause` on an already-paused session is a no-op.
|
|
456
463
|
|
|
464
|
+
**Parameters**
|
|
465
|
+
|
|
466
|
+
| Parameter | Type | Description |
|
|
467
|
+
| ------ | ------ | ------ |
|
|
468
|
+
| `finalize` | `bool` | If True (default), call `finalize()` before pausing. |
|
|
469
|
+
|
|
457
470
|
**Returns**
|
|
458
471
|
|
|
459
472
|
`None`
|
|
@@ -1246,10 +1259,12 @@ is established when entering the async context manager.
|
|
|
1246
1259
|
close() -> None
|
|
1247
1260
|
```
|
|
1248
1261
|
|
|
1249
|
-
|
|
1262
|
+
Close the realtime session and release the WebSocket.
|
|
1250
1263
|
|
|
1251
|
-
|
|
1252
|
-
|
|
1264
|
+
Signals end-of-audio to the server and clears the underlying
|
|
1265
|
+
connection. Subsequent calls are no-ops.
|
|
1266
|
+
|
|
1267
|
+
Called automatically when exiting the async context manager.
|
|
1253
1268
|
|
|
1254
1269
|
**Returns**
|
|
1255
1270
|
|
|
@@ -1296,17 +1311,18 @@ send_bytes(chunks: bytes | AsyncIterator[bytes], *, finish: bool = True) -> None
|
|
|
1296
1311
|
|
|
1297
1312
|
Send audio data to the realtime stream.
|
|
1298
1313
|
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1314
|
+
Accepts either a single bytes object or an async iterator yielding
|
|
1315
|
+
byte chunks (e.g. from `throttle_audio_async`). If `finish=True`
|
|
1316
|
+
(the default), an end-of-audio signal is sent after the last chunk;
|
|
1317
|
+
pass `finish=False` when you intend to send more audio later in the
|
|
1318
|
+
same session.
|
|
1303
1319
|
|
|
1304
1320
|
**Parameters**
|
|
1305
1321
|
|
|
1306
1322
|
| Parameter | Type | Description |
|
|
1307
1323
|
| ------ | ------ | ------ |
|
|
1308
|
-
| `chunks` | `bytes \| AsyncIterator[bytes]` |
|
|
1309
|
-
| `finish` | `bool` |
|
|
1324
|
+
| `chunks` | `bytes \| AsyncIterator[bytes]` | Raw bytes or an async iterator of byte chunks. |
|
|
1325
|
+
| `finish` | `bool` | If True (default), signal end-of-audio after the last chunk. |
|
|
1310
1326
|
|
|
1311
1327
|
**Returns**
|
|
1312
1328
|
|
|
@@ -1351,7 +1367,11 @@ end-of-audio or requesting finalization.
|
|
|
1351
1367
|
finish() -> None
|
|
1352
1368
|
```
|
|
1353
1369
|
|
|
1354
|
-
Signal
|
|
1370
|
+
Signal end-of-audio.
|
|
1371
|
+
|
|
1372
|
+
The server finalizes any pending tokens and closes the
|
|
1373
|
+
connection. Continue iterating `receive_events()` to consume
|
|
1374
|
+
the remaining tokens.
|
|
1355
1375
|
|
|
1356
1376
|
**Returns**
|
|
1357
1377
|
|
|
@@ -1503,7 +1523,7 @@ Receive realtime events and dispatch them to a handler callback.
|
|
|
1503
1523
|
### pause()
|
|
1504
1524
|
|
|
1505
1525
|
```python
|
|
1506
|
-
pause() -> None
|
|
1526
|
+
pause(*, finalize: bool = True) -> None
|
|
1507
1527
|
```
|
|
1508
1528
|
|
|
1509
1529
|
Pause the session, suppressing outgoing audio and starting a
|
|
@@ -1516,6 +1536,12 @@ timing out the session.
|
|
|
1516
1536
|
|
|
1517
1537
|
Calling `pause` on an already-paused session is a no-op.
|
|
1518
1538
|
|
|
1539
|
+
**Parameters**
|
|
1540
|
+
|
|
1541
|
+
| Parameter | Type | Description |
|
|
1542
|
+
| ------ | ------ | ------ |
|
|
1543
|
+
| `finalize` | `bool` | If True (default), call `finalize()` before pausing. |
|
|
1544
|
+
|
|
1519
1545
|
**Returns**
|
|
1520
1546
|
|
|
1521
1547
|
`None`
|