gl-speech 0.0.1b9__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.
- gl_speech-0.0.1b9/LICENSE +21 -0
- gl_speech-0.0.1b9/MANIFEST.in +5 -0
- gl_speech-0.0.1b9/PKG-INFO +370 -0
- gl_speech-0.0.1b9/README.md +358 -0
- gl_speech-0.0.1b9/gl_speech.egg-info/PKG-INFO +370 -0
- gl_speech-0.0.1b9/gl_speech.egg-info/SOURCES.txt +17 -0
- gl_speech-0.0.1b9/gl_speech.egg-info/dependency_links.txt +1 -0
- gl_speech-0.0.1b9/gl_speech.egg-info/requires.txt +2 -0
- gl_speech-0.0.1b9/gl_speech.egg-info/top_level.txt +1 -0
- gl_speech-0.0.1b9/gl_speech_sdk/__init__.py +69 -0
- gl_speech-0.0.1b9/gl_speech_sdk/client.py +86 -0
- gl_speech-0.0.1b9/gl_speech_sdk/models.py +409 -0
- gl_speech-0.0.1b9/gl_speech_sdk/py.typed +0 -0
- gl_speech-0.0.1b9/gl_speech_sdk/stt.py +456 -0
- gl_speech-0.0.1b9/gl_speech_sdk/tts.py +449 -0
- gl_speech-0.0.1b9/gl_speech_sdk/webhooks.py +551 -0
- gl_speech-0.0.1b9/pyproject.toml +55 -0
- gl_speech-0.0.1b9/setup.cfg +4 -0
- gl_speech-0.0.1b9/setup.py +10 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 GDP Labs
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,370 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: gl-speech
|
|
3
|
+
Version: 0.0.1b9
|
|
4
|
+
Summary: GL Speech Python Client - Language binding SDK for Prosa Speech API
|
|
5
|
+
Author-email: GDP Labs <jobs@gdplabs.id>
|
|
6
|
+
Requires-Python: <3.13,>=3.11
|
|
7
|
+
Description-Content-Type: text/markdown
|
|
8
|
+
License-File: LICENSE
|
|
9
|
+
Requires-Dist: httpx>=0.28.1
|
|
10
|
+
Requires-Dist: pydantic>=2.0.0
|
|
11
|
+
Dynamic: license-file
|
|
12
|
+
|
|
13
|
+
# GL Speech SDK
|
|
14
|
+
|
|
15
|
+
A Python SDK for interacting with the GL Speech API, providing speech-to-text (STT), text-to-speech (TTS), and webhook management capabilities.
|
|
16
|
+
|
|
17
|
+
## Prerequisites
|
|
18
|
+
|
|
19
|
+
- **Python** ≥3.11,<3.13 (3.11 or 3.12)
|
|
20
|
+
|
|
21
|
+
## Installation
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
pip install gl-speech
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Or with uv:
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
uv add gl-speech
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Quick Start
|
|
34
|
+
|
|
35
|
+
STT and TTS use different API keys and base URLs. Create two clients. Webhooks for STT jobs use the STT client; webhooks for TTS jobs use the TTS client.
|
|
36
|
+
|
|
37
|
+
```python
|
|
38
|
+
from gl_speech_sdk import SpeechClient
|
|
39
|
+
|
|
40
|
+
stt_client = SpeechClient(api_key="your-stt-api-key", base_url="https://api.prosa.ai/v2/speech/")
|
|
41
|
+
tts_client = SpeechClient(api_key="your-tts-api-key", base_url="https://api.prosa.ai/v2/speech/")
|
|
42
|
+
|
|
43
|
+
# Speech-to-Text
|
|
44
|
+
result = stt_client.stt.transcribe(
|
|
45
|
+
data="<base64-encoded-audio>",
|
|
46
|
+
model="stt-general",
|
|
47
|
+
wait=True
|
|
48
|
+
)
|
|
49
|
+
print(result.result)
|
|
50
|
+
|
|
51
|
+
# Text-to-Speech
|
|
52
|
+
result = tts_client.tts.synthesize(
|
|
53
|
+
text="Hello, world!",
|
|
54
|
+
model="tts-dimas-formal",
|
|
55
|
+
wait=True
|
|
56
|
+
)
|
|
57
|
+
print(result.result)
|
|
58
|
+
|
|
59
|
+
# Webhooks: STT job events use STT client, TTS job events use TTS client
|
|
60
|
+
stt_endpoint = stt_client.webhooks.create_endpoint(
|
|
61
|
+
url="https://your-server.com/webhook-stt",
|
|
62
|
+
event_filters=["stt.job.completed"]
|
|
63
|
+
)
|
|
64
|
+
tts_endpoint = tts_client.webhooks.create_endpoint(
|
|
65
|
+
url="https://your-server.com/webhook-tts",
|
|
66
|
+
event_filters=["tts.job.completed"]
|
|
67
|
+
)
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## Configuration
|
|
71
|
+
|
|
72
|
+
### Environment Variables
|
|
73
|
+
|
|
74
|
+
Set separate credentials for STT and TTS:
|
|
75
|
+
|
|
76
|
+
- `GLSPEECH_STT_API_KEY`: API key for Speech-to-Text
|
|
77
|
+
- `GLSPEECH_STT_BASE_URL`: Base URL for STT (default: `https://api.prosa.ai/v2/speech/`)
|
|
78
|
+
- `GLSPEECH_TTS_API_KEY`: API key for Text-to-Speech
|
|
79
|
+
- `GLSPEECH_TTS_BASE_URL`: Base URL for TTS (default: `https://api.prosa.ai/v2/speech/`)
|
|
80
|
+
|
|
81
|
+
Webhook management is per job type: use the STT client for STT job webhooks, the TTS client for TTS job webhooks.
|
|
82
|
+
|
|
83
|
+
### Client Initialization
|
|
84
|
+
|
|
85
|
+
```python
|
|
86
|
+
from gl_speech_sdk import SpeechClient
|
|
87
|
+
|
|
88
|
+
# Two clients (STT and TTS have different keys)
|
|
89
|
+
stt_client = SpeechClient(
|
|
90
|
+
api_key="your-stt-api-key",
|
|
91
|
+
base_url="https://api.prosa.ai/v2/speech/",
|
|
92
|
+
timeout=60.0,
|
|
93
|
+
default_headers={"X-Custom-Header": "value"}
|
|
94
|
+
)
|
|
95
|
+
tts_client = SpeechClient(
|
|
96
|
+
api_key="your-tts-api-key",
|
|
97
|
+
base_url="https://api.prosa.ai/v2/speech/",
|
|
98
|
+
timeout=60.0,
|
|
99
|
+
default_headers={"X-Custom-Header": "value"}
|
|
100
|
+
)
|
|
101
|
+
|
|
102
|
+
# Or from environment variables
|
|
103
|
+
import os
|
|
104
|
+
os.environ["GLSPEECH_STT_API_KEY"] = "your-stt-api-key"
|
|
105
|
+
os.environ["GLSPEECH_STT_BASE_URL"] = "https://api.prosa.ai/v2/speech/"
|
|
106
|
+
os.environ["GLSPEECH_TTS_API_KEY"] = "your-tts-api-key"
|
|
107
|
+
os.environ["GLSPEECH_TTS_BASE_URL"] = "https://api.prosa.ai/v2/speech/"
|
|
108
|
+
stt_client = SpeechClient(api_key=os.getenv("GLSPEECH_STT_API_KEY"), base_url=os.getenv("GLSPEECH_STT_BASE_URL"))
|
|
109
|
+
tts_client = SpeechClient(api_key=os.getenv("GLSPEECH_TTS_API_KEY"), base_url=os.getenv("GLSPEECH_TTS_BASE_URL"))
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
## Speech-to-Text (STT)
|
|
113
|
+
|
|
114
|
+
Use `stt_client` for all STT operations.
|
|
115
|
+
|
|
116
|
+
### List Available Models
|
|
117
|
+
|
|
118
|
+
```python
|
|
119
|
+
models = stt_client.stt.list_models()
|
|
120
|
+
for model in models:
|
|
121
|
+
print(f"{model['name']}: {model['label']}")
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### Transcribe Audio
|
|
125
|
+
|
|
126
|
+
```python
|
|
127
|
+
# Synchronous (wait for result)
|
|
128
|
+
result = stt_client.stt.transcribe(
|
|
129
|
+
model="stt-general",
|
|
130
|
+
wait=True,
|
|
131
|
+
data="<base64-encoded-audio>",
|
|
132
|
+
label="My audio file"
|
|
133
|
+
)
|
|
134
|
+
print(result.result)
|
|
135
|
+
|
|
136
|
+
# Asynchronous (get job_id, poll later)
|
|
137
|
+
result = stt_client.stt.transcribe(
|
|
138
|
+
model="stt-general",
|
|
139
|
+
wait=False,
|
|
140
|
+
uri="https://example.com/audio.wav"
|
|
141
|
+
)
|
|
142
|
+
job_id = result.job_id
|
|
143
|
+
|
|
144
|
+
# Check status
|
|
145
|
+
status = stt_client.stt.get_status(job_id)
|
|
146
|
+
print(f"Status: {status.status}, Progress: {status.progress}")
|
|
147
|
+
|
|
148
|
+
# Get result when complete
|
|
149
|
+
result = stt_client.stt.get_job(job_id)
|
|
150
|
+
print(result.result)
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
### Advanced Configuration
|
|
154
|
+
|
|
155
|
+
```python
|
|
156
|
+
result = stt_client.stt.transcribe(
|
|
157
|
+
model="stt-general",
|
|
158
|
+
wait=True,
|
|
159
|
+
data="<base64-encoded-audio>",
|
|
160
|
+
speaker_count=2, # Expected number of speakers
|
|
161
|
+
include_filler=True, # Include filler words
|
|
162
|
+
auto_punctuation=True, # Auto-add punctuation
|
|
163
|
+
enable_spoken_numerals=True, # Convert "one" to "1"
|
|
164
|
+
enable_speech_insights=True, # Speech analytics
|
|
165
|
+
enable_voice_insights=True, # Voice analytics
|
|
166
|
+
)
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
### List and Manage Jobs
|
|
170
|
+
|
|
171
|
+
```python
|
|
172
|
+
# List jobs with filters
|
|
173
|
+
jobs = stt_client.stt.list_jobs(
|
|
174
|
+
page=1,
|
|
175
|
+
per_page=10,
|
|
176
|
+
from_date="2024-01-01",
|
|
177
|
+
until_date="2024-01-31",
|
|
178
|
+
query_text="hello"
|
|
179
|
+
)
|
|
180
|
+
|
|
181
|
+
# Archive a job
|
|
182
|
+
stt_client.stt.archive(job_id)
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
## Text-to-Speech (TTS)
|
|
186
|
+
|
|
187
|
+
Use `tts_client` for all TTS operations.
|
|
188
|
+
|
|
189
|
+
### List Available Models
|
|
190
|
+
|
|
191
|
+
```python
|
|
192
|
+
models = tts_client.tts.list_models()
|
|
193
|
+
for model in models:
|
|
194
|
+
print(f"{model['name']}: {model['voice']} ({model['gender']})")
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
### Synthesize Speech
|
|
198
|
+
|
|
199
|
+
```python
|
|
200
|
+
# Synchronous (wait for result)
|
|
201
|
+
result = tts_client.tts.synthesize(
|
|
202
|
+
text="Hello, world!",
|
|
203
|
+
model="tts-dimas-formal",
|
|
204
|
+
wait=True
|
|
205
|
+
)
|
|
206
|
+
audio_data = result.result["data"] # Base64-encoded audio
|
|
207
|
+
|
|
208
|
+
# Get as signed URL instead
|
|
209
|
+
result = tts_client.tts.synthesize(
|
|
210
|
+
text="Hello, world!",
|
|
211
|
+
model="tts-dimas-formal",
|
|
212
|
+
wait=True,
|
|
213
|
+
as_signed_url=True
|
|
214
|
+
)
|
|
215
|
+
audio_url = result.result["path"]
|
|
216
|
+
|
|
217
|
+
# Asynchronous
|
|
218
|
+
result = tts_client.tts.synthesize(
|
|
219
|
+
text="Long text content...",
|
|
220
|
+
model="tts-dimas-formal",
|
|
221
|
+
wait=False
|
|
222
|
+
)
|
|
223
|
+
job_id = result.job_id
|
|
224
|
+
|
|
225
|
+
# Poll for completion
|
|
226
|
+
result = tts_client.tts.get_job(job_id, as_signed_url=True)
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
### Advanced Configuration
|
|
230
|
+
|
|
231
|
+
```python
|
|
232
|
+
result = tts_client.tts.synthesize(
|
|
233
|
+
text="Hello, world!",
|
|
234
|
+
model="tts-dimas-formal",
|
|
235
|
+
wait=True,
|
|
236
|
+
pitch=0.5, # Pitch adjustment (-1.0 to 1.0)
|
|
237
|
+
tempo=1.2, # Speed adjustment (0.5 to 2.0)
|
|
238
|
+
audio_format="mp3", # "opus", "mp3", or "wav"
|
|
239
|
+
label="My synthesis"
|
|
240
|
+
)
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
### List and Manage Jobs
|
|
244
|
+
|
|
245
|
+
```python
|
|
246
|
+
# List jobs
|
|
247
|
+
jobs = tts_client.tts.list_jobs(page=1, per_page=10)
|
|
248
|
+
|
|
249
|
+
# Count jobs
|
|
250
|
+
count = tts_client.tts.count_jobs(from_date="2024-01-01")
|
|
251
|
+
|
|
252
|
+
# Get job status
|
|
253
|
+
status = tts_client.tts.get_status(job_id)
|
|
254
|
+
|
|
255
|
+
# Archive a job
|
|
256
|
+
tts_client.tts.archive(job_id)
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
## Webhook Management
|
|
260
|
+
|
|
261
|
+
### Webhooks and API keys
|
|
262
|
+
|
|
263
|
+
Webhook **management** is split by job type:
|
|
264
|
+
|
|
265
|
+
- **STT job webhooks** (e.g. `stt.job.completed`) use the **STT** API key and base URL → use `stt_client.webhooks`.
|
|
266
|
+
- **TTS job webhooks** (e.g. `tts.job.completed`) use the **TTS** API key and base URL → use `tts_client.webhooks`.
|
|
267
|
+
|
|
268
|
+
Create and manage endpoints on the client that matches the events you want to receive.
|
|
269
|
+
|
|
270
|
+
### Create a Webhook Endpoint
|
|
271
|
+
|
|
272
|
+
```python
|
|
273
|
+
# Endpoint for STT job events (uses STT key)
|
|
274
|
+
stt_endpoint = stt_client.webhooks.create_endpoint(
|
|
275
|
+
url="https://your-server.com/webhook-stt",
|
|
276
|
+
event_filters=["stt.job.completed"],
|
|
277
|
+
ssl_verification=True
|
|
278
|
+
)
|
|
279
|
+
|
|
280
|
+
# Endpoint for TTS job events (uses TTS key)
|
|
281
|
+
tts_endpoint = tts_client.webhooks.create_endpoint(
|
|
282
|
+
url="https://your-server.com/webhook-tts",
|
|
283
|
+
event_filters=["tts.job.completed"],
|
|
284
|
+
ssl_verification=True
|
|
285
|
+
)
|
|
286
|
+
print(f"STT Endpoint ID: {stt_endpoint.id}, Secret: {stt_endpoint.secrets[0].key}")
|
|
287
|
+
print(f"TTS Endpoint ID: {tts_endpoint.id}, Secret: {tts_endpoint.secrets[0].key}")
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
### List Endpoints
|
|
291
|
+
|
|
292
|
+
```python
|
|
293
|
+
# List STT webhook endpoints
|
|
294
|
+
stt_endpoints = stt_client.webhooks.list_endpoints()
|
|
295
|
+
|
|
296
|
+
# List TTS webhook endpoints
|
|
297
|
+
tts_endpoints = tts_client.webhooks.list_endpoints()
|
|
298
|
+
for ep in tts_endpoints:
|
|
299
|
+
print(f"{ep.id}: {ep.url}")
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
### Update and Delete Endpoints
|
|
303
|
+
|
|
304
|
+
```python
|
|
305
|
+
# Update/delete on the same client you used to create (STT or TTS)
|
|
306
|
+
stt_client.webhooks.update_endpoint(
|
|
307
|
+
endpoint_id="endpoint-123",
|
|
308
|
+
url="https://your-server.com/new-webhook",
|
|
309
|
+
event_filters=[]
|
|
310
|
+
)
|
|
311
|
+
stt_client.webhooks.delete_endpoint("endpoint-123")
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
### Rotate Secrets
|
|
315
|
+
|
|
316
|
+
```python
|
|
317
|
+
tts_client.webhooks.rotate_secret(
|
|
318
|
+
endpoint_id="endpoint-123",
|
|
319
|
+
days=3, # Old secret valid for 3 days
|
|
320
|
+
hours=0
|
|
321
|
+
)
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
### Event Management
|
|
325
|
+
|
|
326
|
+
```python
|
|
327
|
+
# List events (from the client whose webhooks you're querying)
|
|
328
|
+
events = tts_client.webhooks.list_events(
|
|
329
|
+
from_date="2024-01-01",
|
|
330
|
+
to_date="2024-01-31"
|
|
331
|
+
)
|
|
332
|
+
event = tts_client.webhooks.get_event("event-123")
|
|
333
|
+
print(event.data)
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
### Delivery Management
|
|
337
|
+
|
|
338
|
+
```python
|
|
339
|
+
deliveries = tts_client.webhooks.list_deliveries("endpoint-123")
|
|
340
|
+
ticket = tts_client.webhooks.replay_delivery("delivery-123")
|
|
341
|
+
tickets = tts_client.webhooks.replay_failed_deliveries("endpoint-123")
|
|
342
|
+
ticket = tts_client.webhooks.test_endpoint("endpoint-123")
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
## Error Handling
|
|
346
|
+
|
|
347
|
+
```python
|
|
348
|
+
import httpx
|
|
349
|
+
from gl_speech_sdk import SpeechClient
|
|
350
|
+
|
|
351
|
+
stt_client = SpeechClient(api_key="your-stt-api-key", base_url="https://api.prosa.ai/v2/speech/")
|
|
352
|
+
|
|
353
|
+
try:
|
|
354
|
+
result = stt_client.stt.transcribe(model="stt-general", data="invalid")
|
|
355
|
+
except httpx.HTTPStatusError as e:
|
|
356
|
+
print(f"HTTP Error: {e.response.status_code}")
|
|
357
|
+
print(f"Response: {e.response.text}")
|
|
358
|
+
except ValueError as e:
|
|
359
|
+
print(f"Validation Error: {e}")
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
## API Reference
|
|
363
|
+
|
|
364
|
+
- [STT API Documentation](https://gdplabs.gitbook.io/gl-speech/api-contract/speech-to-text-stt)
|
|
365
|
+
- [TTS API Documentation](https://gdplabs.gitbook.io/gl-speech/api-contract/text-to-speech-tts)
|
|
366
|
+
- [Webhook API Documentation](https://gdplabs.gitbook.io/gl-speech/api-contract/webhooks)
|
|
367
|
+
|
|
368
|
+
## License
|
|
369
|
+
|
|
370
|
+
MIT License.
|