gl-speech-sdk 0.0.1b1__py3-none-any.whl
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_sdk/__init__.py +69 -0
- gl_speech_sdk/client.py +86 -0
- gl_speech_sdk/models.py +409 -0
- gl_speech_sdk/py.typed +0 -0
- gl_speech_sdk/stt.py +456 -0
- gl_speech_sdk/tts.py +449 -0
- gl_speech_sdk/webhooks.py +551 -0
- gl_speech_sdk-0.0.1b1.dist-info/METADATA +417 -0
- gl_speech_sdk-0.0.1b1.dist-info/RECORD +11 -0
- gl_speech_sdk-0.0.1b1.dist-info/WHEEL +4 -0
- gl_speech_sdk-0.0.1b1.dist-info/licenses/LICENSE +21 -0
|
@@ -0,0 +1,417 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: gl-speech-sdk
|
|
3
|
+
Version: 0.0.1b1
|
|
4
|
+
Summary: GL Speech Python Client - Language binding SDK for Prosa Speech API
|
|
5
|
+
Author-email: GDP Labs <jobs@gdplabs.id>
|
|
6
|
+
License-File: LICENSE
|
|
7
|
+
Requires-Python: >=3.13
|
|
8
|
+
Requires-Dist: httpx>=0.28.1
|
|
9
|
+
Requires-Dist: pydantic>=2.0.0
|
|
10
|
+
Description-Content-Type: text/markdown
|
|
11
|
+
|
|
12
|
+
# GL Speech SDK
|
|
13
|
+
|
|
14
|
+
A Python SDK for interacting with the Prosa Speech API, providing speech-to-text (STT), text-to-speech (TTS), and webhook management capabilities.
|
|
15
|
+
|
|
16
|
+
## Installation
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
pip install glspeech-sdk
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Or with uv:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
uv add glspeech-sdk
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Quick Start
|
|
29
|
+
|
|
30
|
+
```python
|
|
31
|
+
from gl_speech_sdk import SpeechClient
|
|
32
|
+
|
|
33
|
+
# Initialize the client
|
|
34
|
+
client = SpeechClient(api_key="your-api-key")
|
|
35
|
+
|
|
36
|
+
# Speech-to-Text
|
|
37
|
+
result = client.stt.transcribe(
|
|
38
|
+
data="<base64-encoded-audio>",
|
|
39
|
+
model="stt-general",
|
|
40
|
+
wait=True
|
|
41
|
+
)
|
|
42
|
+
print(result.result)
|
|
43
|
+
|
|
44
|
+
# Text-to-Speech
|
|
45
|
+
result = client.tts.synthesize(
|
|
46
|
+
text="Hello, world!",
|
|
47
|
+
model="tts-dimas-formal",
|
|
48
|
+
wait=True
|
|
49
|
+
)
|
|
50
|
+
print(result.result)
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Configuration
|
|
54
|
+
|
|
55
|
+
### Environment Variables
|
|
56
|
+
|
|
57
|
+
The SDK supports the following environment variables:
|
|
58
|
+
|
|
59
|
+
- `GLSPEECH_API_KEY`: API key for authentication
|
|
60
|
+
- `GLSPEECH_BASE_URL`: Base URL for the API (default: `https://api.prosa.ai/v2/speech/`)
|
|
61
|
+
|
|
62
|
+
### Client Initialization
|
|
63
|
+
|
|
64
|
+
```python
|
|
65
|
+
from gl_speech_sdk import SpeechClient
|
|
66
|
+
|
|
67
|
+
# Using explicit parameters
|
|
68
|
+
client = SpeechClient(
|
|
69
|
+
api_key="your-api-key",
|
|
70
|
+
base_url="https://api.prosa.ai/v2/speech/",
|
|
71
|
+
timeout=60.0,
|
|
72
|
+
default_headers={"X-Custom-Header": "value"}
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
# Using environment variables
|
|
76
|
+
import os
|
|
77
|
+
os.environ["GLSPEECH_API_KEY"] = "your-api-key"
|
|
78
|
+
client = SpeechClient()
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## Speech-to-Text (STT)
|
|
82
|
+
|
|
83
|
+
### List Available Models
|
|
84
|
+
|
|
85
|
+
```python
|
|
86
|
+
models = client.stt.list_models()
|
|
87
|
+
for model in models:
|
|
88
|
+
print(f"{model['name']}: {model['label']}")
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### Transcribe Audio
|
|
92
|
+
|
|
93
|
+
```python
|
|
94
|
+
# Synchronous (wait for result)
|
|
95
|
+
result = client.stt.transcribe(
|
|
96
|
+
model="stt-general",
|
|
97
|
+
wait=True,
|
|
98
|
+
data="<base64-encoded-audio>",
|
|
99
|
+
label="My audio file"
|
|
100
|
+
)
|
|
101
|
+
print(result.result)
|
|
102
|
+
|
|
103
|
+
# Asynchronous (get job_id, poll later)
|
|
104
|
+
result = client.stt.transcribe(
|
|
105
|
+
model="stt-general",
|
|
106
|
+
wait=False,
|
|
107
|
+
uri="https://example.com/audio.wav"
|
|
108
|
+
)
|
|
109
|
+
job_id = result.job_id
|
|
110
|
+
|
|
111
|
+
# Check status
|
|
112
|
+
status = client.stt.get_status(job_id)
|
|
113
|
+
print(f"Status: {status.status}, Progress: {status.progress}")
|
|
114
|
+
|
|
115
|
+
# Get result when complete
|
|
116
|
+
result = client.stt.get_job(job_id)
|
|
117
|
+
print(result.result)
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
### Advanced Configuration
|
|
121
|
+
|
|
122
|
+
```python
|
|
123
|
+
result = client.stt.transcribe(
|
|
124
|
+
model="stt-general",
|
|
125
|
+
wait=True,
|
|
126
|
+
data="<base64-encoded-audio>",
|
|
127
|
+
speaker_count=2, # Expected number of speakers
|
|
128
|
+
include_filler=True, # Include filler words
|
|
129
|
+
auto_punctuation=True, # Auto-add punctuation
|
|
130
|
+
enable_spoken_numerals=True, # Convert "one" to "1"
|
|
131
|
+
enable_speech_insights=True, # Speech analytics
|
|
132
|
+
enable_voice_insights=True, # Voice analytics
|
|
133
|
+
)
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### List and Manage Jobs
|
|
137
|
+
|
|
138
|
+
```python
|
|
139
|
+
# List jobs with filters
|
|
140
|
+
jobs = client.stt.list_jobs(
|
|
141
|
+
page=1,
|
|
142
|
+
per_page=10,
|
|
143
|
+
from_date="2024-01-01",
|
|
144
|
+
until_date="2024-01-31",
|
|
145
|
+
query_text="hello"
|
|
146
|
+
)
|
|
147
|
+
|
|
148
|
+
# Archive a job
|
|
149
|
+
client.stt.archive(job_id)
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
## Text-to-Speech (TTS)
|
|
153
|
+
|
|
154
|
+
### List Available Models
|
|
155
|
+
|
|
156
|
+
```python
|
|
157
|
+
models = client.tts.list_models()
|
|
158
|
+
for model in models:
|
|
159
|
+
print(f"{model['name']}: {model['voice']} ({model['gender']})")
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
### Synthesize Speech
|
|
163
|
+
|
|
164
|
+
```python
|
|
165
|
+
# Synchronous (wait for result)
|
|
166
|
+
result = client.tts.synthesize(
|
|
167
|
+
text="Hello, world!",
|
|
168
|
+
model="tts-dimas-formal",
|
|
169
|
+
wait=True
|
|
170
|
+
)
|
|
171
|
+
audio_data = result.result["data"] # Base64-encoded audio
|
|
172
|
+
|
|
173
|
+
# Get as signed URL instead
|
|
174
|
+
result = client.tts.synthesize(
|
|
175
|
+
text="Hello, world!",
|
|
176
|
+
model="tts-dimas-formal",
|
|
177
|
+
wait=True,
|
|
178
|
+
as_signed_url=True
|
|
179
|
+
)
|
|
180
|
+
audio_url = result.result["path"]
|
|
181
|
+
|
|
182
|
+
# Asynchronous
|
|
183
|
+
result = client.tts.synthesize(
|
|
184
|
+
text="Long text content...",
|
|
185
|
+
model="tts-dimas-formal",
|
|
186
|
+
wait=False
|
|
187
|
+
)
|
|
188
|
+
job_id = result.job_id
|
|
189
|
+
|
|
190
|
+
# Poll for completion
|
|
191
|
+
result = client.tts.get_job(job_id, as_signed_url=True)
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
### Advanced Configuration
|
|
195
|
+
|
|
196
|
+
```python
|
|
197
|
+
result = client.tts.synthesize(
|
|
198
|
+
text="Hello, world!",
|
|
199
|
+
model="tts-dimas-formal",
|
|
200
|
+
wait=True,
|
|
201
|
+
pitch=0.5, # Pitch adjustment (-1.0 to 1.0)
|
|
202
|
+
tempo=1.2, # Speed adjustment (0.5 to 2.0)
|
|
203
|
+
audio_format="mp3", # "opus", "mp3", or "wav"
|
|
204
|
+
label="My synthesis"
|
|
205
|
+
)
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
### List and Manage Jobs
|
|
209
|
+
|
|
210
|
+
```python
|
|
211
|
+
# List jobs
|
|
212
|
+
jobs = client.tts.list_jobs(page=1, per_page=10)
|
|
213
|
+
|
|
214
|
+
# Count jobs
|
|
215
|
+
count = client.tts.count_jobs(from_date="2024-01-01")
|
|
216
|
+
|
|
217
|
+
# Get job status
|
|
218
|
+
status = client.tts.get_status(job_id)
|
|
219
|
+
|
|
220
|
+
# Archive a job
|
|
221
|
+
client.tts.archive(job_id)
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
## Webhook Management
|
|
225
|
+
|
|
226
|
+
### Create a Webhook Endpoint
|
|
227
|
+
|
|
228
|
+
```python
|
|
229
|
+
endpoint = client.webhooks.create_endpoint(
|
|
230
|
+
url="https://your-server.com/webhook",
|
|
231
|
+
event_filters=["stt.jobs.completed", "tts.jobs.completed"],
|
|
232
|
+
ssl_verification=True
|
|
233
|
+
)
|
|
234
|
+
print(f"Endpoint ID: {endpoint.id}")
|
|
235
|
+
print(f"Secret Key: {endpoint.secrets[0].key}")
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
### List Endpoints
|
|
239
|
+
|
|
240
|
+
```python
|
|
241
|
+
endpoints = client.webhooks.list_endpoints()
|
|
242
|
+
for ep in endpoints:
|
|
243
|
+
print(f"{ep.id}: {ep.url}")
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
### Update and Delete Endpoints
|
|
247
|
+
|
|
248
|
+
```python
|
|
249
|
+
# Update
|
|
250
|
+
endpoint = client.webhooks.update_endpoint(
|
|
251
|
+
endpoint_id="endpoint-123",
|
|
252
|
+
url="https://your-server.com/new-webhook",
|
|
253
|
+
event_filters=[]
|
|
254
|
+
)
|
|
255
|
+
|
|
256
|
+
# Delete
|
|
257
|
+
client.webhooks.delete_endpoint("endpoint-123")
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
### Rotate Secrets
|
|
261
|
+
|
|
262
|
+
```python
|
|
263
|
+
endpoint = client.webhooks.rotate_secret(
|
|
264
|
+
endpoint_id="endpoint-123",
|
|
265
|
+
days=3, # Old secret valid for 3 days
|
|
266
|
+
hours=0
|
|
267
|
+
)
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
### Event Management
|
|
271
|
+
|
|
272
|
+
```python
|
|
273
|
+
# List events
|
|
274
|
+
events = client.webhooks.list_events(
|
|
275
|
+
from_date="2024-01-01",
|
|
276
|
+
to_date="2024-01-31"
|
|
277
|
+
)
|
|
278
|
+
|
|
279
|
+
# Get event details
|
|
280
|
+
event = client.webhooks.get_event("event-123")
|
|
281
|
+
print(event.data)
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
### Delivery Management
|
|
285
|
+
|
|
286
|
+
```python
|
|
287
|
+
# List deliveries
|
|
288
|
+
deliveries = client.webhooks.list_deliveries("endpoint-123")
|
|
289
|
+
|
|
290
|
+
# Replay a delivery
|
|
291
|
+
ticket = client.webhooks.replay_delivery("delivery-123")
|
|
292
|
+
|
|
293
|
+
# Replay all failed deliveries
|
|
294
|
+
tickets = client.webhooks.replay_failed_deliveries("endpoint-123")
|
|
295
|
+
|
|
296
|
+
# Test endpoint
|
|
297
|
+
ticket = client.webhooks.test_endpoint("endpoint-123")
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
## Error Handling
|
|
301
|
+
|
|
302
|
+
```python
|
|
303
|
+
import httpx
|
|
304
|
+
from gl_speech_sdk import SpeechClient
|
|
305
|
+
|
|
306
|
+
client = SpeechClient(api_key="your-api-key")
|
|
307
|
+
|
|
308
|
+
try:
|
|
309
|
+
result = client.stt.transcribe(data="invalid")
|
|
310
|
+
except httpx.HTTPStatusError as e:
|
|
311
|
+
print(f"HTTP Error: {e.response.status_code}")
|
|
312
|
+
print(f"Response: {e.response.text}")
|
|
313
|
+
except ValueError as e:
|
|
314
|
+
print(f"Validation Error: {e}")
|
|
315
|
+
```
|
|
316
|
+
|
|
317
|
+
## Development
|
|
318
|
+
|
|
319
|
+
### Install Development Dependencies
|
|
320
|
+
|
|
321
|
+
```bash
|
|
322
|
+
uv sync --group dev
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
### Running Unit Tests
|
|
326
|
+
|
|
327
|
+
The SDK uses `pytest` for unit testing. All test files are located in the `tests/` directory.
|
|
328
|
+
|
|
329
|
+
#### Run All Tests
|
|
330
|
+
|
|
331
|
+
```bash
|
|
332
|
+
uv run pytest
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
#### Run Tests with Coverage Report
|
|
336
|
+
|
|
337
|
+
```bash
|
|
338
|
+
uv run pytest --cov=gl_speech_sdk --cov-report=term-missing
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
This will show:
|
|
342
|
+
|
|
343
|
+
- Test coverage percentage
|
|
344
|
+
- Which lines are covered/missing
|
|
345
|
+
- Coverage report in the terminal
|
|
346
|
+
|
|
347
|
+
#### Run Specific Test Files
|
|
348
|
+
|
|
349
|
+
```bash
|
|
350
|
+
# Run only client tests
|
|
351
|
+
uv run pytest tests/test_client.py
|
|
352
|
+
|
|
353
|
+
# Run only STT tests
|
|
354
|
+
uv run pytest tests/test_stt.py
|
|
355
|
+
|
|
356
|
+
# Run only TTS tests
|
|
357
|
+
uv run pytest tests/test_tts.py
|
|
358
|
+
|
|
359
|
+
# Run only webhook tests
|
|
360
|
+
uv run pytest tests/test_webhooks.py
|
|
361
|
+
```
|
|
362
|
+
|
|
363
|
+
#### Run Specific Test Functions
|
|
364
|
+
|
|
365
|
+
```bash
|
|
366
|
+
# Run a specific test function
|
|
367
|
+
uv run pytest tests/test_client.py::test_client_initialization_required_only
|
|
368
|
+
|
|
369
|
+
# Run tests matching a pattern
|
|
370
|
+
uv run pytest -k "test_client"
|
|
371
|
+
```
|
|
372
|
+
|
|
373
|
+
#### Run Tests with Verbose Output
|
|
374
|
+
|
|
375
|
+
```bash
|
|
376
|
+
# Show detailed output for each test
|
|
377
|
+
uv run pytest -v
|
|
378
|
+
|
|
379
|
+
# Show even more details including print statements
|
|
380
|
+
uv run pytest -v -s
|
|
381
|
+
```
|
|
382
|
+
|
|
383
|
+
#### Run Tests in Parallel (if pytest-xdist is installed)
|
|
384
|
+
|
|
385
|
+
```bash
|
|
386
|
+
uv run pytest -n auto
|
|
387
|
+
```
|
|
388
|
+
|
|
389
|
+
#### Other Useful Options
|
|
390
|
+
|
|
391
|
+
```bash
|
|
392
|
+
# Stop on first failure
|
|
393
|
+
uv run pytest -x
|
|
394
|
+
|
|
395
|
+
# Show local variables on failure
|
|
396
|
+
uv run pytest -l
|
|
397
|
+
|
|
398
|
+
# Run tests matching a keyword
|
|
399
|
+
uv run pytest -k "stt" # Run all STT-related tests
|
|
400
|
+
```
|
|
401
|
+
|
|
402
|
+
### Run Linting
|
|
403
|
+
|
|
404
|
+
```bash
|
|
405
|
+
uv run ruff check .
|
|
406
|
+
uv run ruff format .
|
|
407
|
+
```
|
|
408
|
+
|
|
409
|
+
## API Reference
|
|
410
|
+
|
|
411
|
+
- [Prosa STT API Documentation](https://docs2.prosa.ai/speech/stt/rest/api/)
|
|
412
|
+
- [Prosa TTS API Documentation](https://docs2.prosa.ai/speech/tts/rest/api/)
|
|
413
|
+
- [Prosa Webhook API Documentation](https://docs2.prosa.ai/speech/webhook/rest/api/)
|
|
414
|
+
|
|
415
|
+
## License
|
|
416
|
+
|
|
417
|
+
MIT License - see LICENSE file for details.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
gl_speech_sdk/__init__.py,sha256=ENmGVx7-IUl5aOB2um-aFLlRQ00-9MQ_RcPzoroQhEM,1508
|
|
2
|
+
gl_speech_sdk/client.py,sha256=dn_zhDwQTAFa9llrFVaT3IlE7uFZ3H4saWlBwYOGIl8,3075
|
|
3
|
+
gl_speech_sdk/models.py,sha256=SGqZJsD35LBo5mxu0rfIPTUdZ9I0E1hf_dEgleG0Yls,9812
|
|
4
|
+
gl_speech_sdk/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
5
|
+
gl_speech_sdk/stt.py,sha256=IgEAI-1ghhWzsONaI-zOzUurQ-XGRFbAwuBzq9DAqVo,16420
|
|
6
|
+
gl_speech_sdk/tts.py,sha256=lfeldRiD3CxH4LMKTPuFxmu7rLL4Mgg2kj_EZo_y5Uk,14680
|
|
7
|
+
gl_speech_sdk/webhooks.py,sha256=_DJUHcdHAtvpB1sSww5kSaUAESsyegcI-VkO1cRr1TU,18966
|
|
8
|
+
gl_speech_sdk-0.0.1b1.dist-info/METADATA,sha256=Dz7CTCk0C_etW104lefkHWg95TYpigdUKcMrozI2sV0,8323
|
|
9
|
+
gl_speech_sdk-0.0.1b1.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
10
|
+
gl_speech_sdk-0.0.1b1.dist-info/licenses/LICENSE,sha256=GLqGo4o1hC8CcufoToJGtPfKsvPmLsVIk2x97xDBD3I,1065
|
|
11
|
+
gl_speech_sdk-0.0.1b1.dist-info/RECORD,,
|
|
@@ -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.
|