GL Speech
A Python library for interacting with the GL Speech API, providing speech-to-text (STT), text-to-speech (TTS), and webhook management capabilities.
Prerequisites
- Python ≥3.11,<3.14 (3.11, 3.12, or 3.13)
Installation
pip install gl-speech
Or with uv:
uv add gl-speech
Quick Start
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.
from gl_speech import SpeechClient
stt_client = SpeechClient(api_key="your-stt-api-key", base_url="https://api.prosa.ai/v2/speech/")
tts_client = SpeechClient(api_key="your-tts-api-key", base_url="https://api.prosa.ai/v2/speech/")
# Speech-to-Text
result = stt_client.stt.transcribe(
data="<base64-encoded-audio>",
model="stt-general",
wait=True
)
print(result.result)
# Text-to-Speech
result = tts_client.tts.synthesize(
text="Hello, world!",
model="tts-dimas-formal",
wait=True
)
print(result.result)
# Webhooks: STT job events use STT client, TTS job events use TTS client
stt_endpoint = stt_client.webhooks.create_endpoint(
url="https://your-server.com/webhook-stt",
event_filters=["stt.job.completed"]
)
tts_endpoint = tts_client.webhooks.create_endpoint(
url="https://your-server.com/webhook-tts",
event_filters=["tts.job.completed"]
)
Configuration
Environment Variables
Set separate credentials for STT and TTS:
GLSPEECH_STT_API_KEY: API key for Speech-to-TextGLSPEECH_STT_BASE_URL: Base URL for STT (default:https://api.prosa.ai/v2/speech/)GLSPEECH_TTS_API_KEY: API key for Text-to-SpeechGLSPEECH_TTS_BASE_URL: Base URL for TTS (default:https://api.prosa.ai/v2/speech/)
Webhook management is per job type: use the STT client for STT job webhooks, the TTS client for TTS job webhooks.
Client Initialization
from gl_speech import SpeechClient
# Two clients (STT and TTS have different keys)
stt_client = SpeechClient(
api_key="your-stt-api-key",
base_url="https://api.prosa.ai/v2/speech/",
timeout=60.0,
default_headers={"X-Custom-Header": "value"}
)
tts_client = SpeechClient(
api_key="your-tts-api-key",
base_url="https://api.prosa.ai/v2/speech/",
timeout=60.0,
default_headers={"X-Custom-Header": "value"}
)
# Or from environment variables
import os
os.environ["GLSPEECH_STT_API_KEY"] = "your-stt-api-key"
os.environ["GLSPEECH_STT_BASE_URL"] = "https://api.prosa.ai/v2/speech/"
os.environ["GLSPEECH_TTS_API_KEY"] = "your-tts-api-key"
os.environ["GLSPEECH_TTS_BASE_URL"] = "https://api.prosa.ai/v2/speech/"
stt_client = SpeechClient(api_key=os.getenv("GLSPEECH_STT_API_KEY"), base_url=os.getenv("GLSPEECH_STT_BASE_URL"))
tts_client = SpeechClient(api_key=os.getenv("GLSPEECH_TTS_API_KEY"), base_url=os.getenv("GLSPEECH_TTS_BASE_URL"))
Speech-to-Text (STT)
Use stt_client for all STT operations.
List Available Models
models = stt_client.stt.list_models()
for model in models:
print(f"{model['name']}: {model['label']}")
Transcribe Audio
# Synchronous (wait for result)
result = stt_client.stt.transcribe(
model="stt-general",
wait=True,
data="<base64-encoded-audio>",
label="My audio file"
)
print(result.result)
# Asynchronous (get job_id, poll later)
result = stt_client.stt.transcribe(
model="stt-general",
wait=False,
uri="https://example.com/audio.wav"
)
job_id = result.job_id
# Check status
status = stt_client.stt.get_status(job_id)
print(f"Status: {status.status}, Progress: {status.progress}")
# Get result when complete
result = stt_client.stt.get_job(job_id)
print(result.result)
Advanced Configuration
result = stt_client.stt.transcribe(
model="stt-general",
wait=True,
data="<base64-encoded-audio>",
speaker_count=2, # Expected number of speakers
include_filler=True, # Include filler words
auto_punctuation=True, # Auto-add punctuation
enable_spoken_numerals=True, # Convert "one" to "1"
enable_speech_insights=True, # Speech analytics
enable_voice_insights=True, # Voice analytics
)
List and Manage Jobs
# List jobs with filters
jobs = stt_client.stt.list_jobs(
page=1,
per_page=10,
from_date="2024-01-01",
until_date="2024-01-31",
query_text="hello"
)
# Archive a job
stt_client.stt.archive(job_id)
Text-to-Speech (TTS)
Use tts_client for all TTS operations.
List Available Models
models = tts_client.tts.list_models()
for model in models:
print(f"{model['name']}: {model['voice']} ({model['gender']})")
Synthesize Speech
# Synchronous (wait for result)
result = tts_client.tts.synthesize(
text="Hello, world!",
model="tts-dimas-formal",
wait=True
)
audio_data = result.result["data"] # Base64-encoded audio
# Get as signed URL instead
result = tts_client.tts.synthesize(
text="Hello, world!",
model="tts-dimas-formal",
wait=True,
as_signed_url=True
)
audio_url = result.result["path"]
# Asynchronous
result = tts_client.tts.synthesize(
text="Long text content...",
model="tts-dimas-formal",
wait=False
)
job_id = result.job_id
# Poll for completion
result = tts_client.tts.get_job(job_id, as_signed_url=True)
Advanced Configuration
result = tts_client.tts.synthesize(
text="Hello, world!",
model="tts-dimas-formal",
wait=True,
pitch=0.5, # Pitch adjustment (-1.0 to 1.0)
tempo=1.2, # Speed adjustment (0.5 to 2.0)
audio_format="mp3", # "opus", "mp3", or "wav"
label="My synthesis"
)
List and Manage Jobs
# List jobs
jobs = tts_client.tts.list_jobs(page=1, per_page=10)
# Count jobs
count = tts_client.tts.count_jobs(from_date="2024-01-01")
# Get job status
status = tts_client.tts.get_status(job_id)
# Archive a job
tts_client.tts.archive(job_id)
Webhook Management
Webhooks and API keys
Webhook management is split by job type:
- STT job webhooks (e.g.
stt.job.completed) use the STT API key and base URL → usestt_client.webhooks. - TTS job webhooks (e.g.
tts.job.completed) use the TTS API key and base URL → usetts_client.webhooks.
Create and manage endpoints on the client that matches the events you want to receive.
Create a Webhook Endpoint
# Endpoint for STT job events (uses STT key)
stt_endpoint = stt_client.webhooks.create_endpoint(
url="https://your-server.com/webhook-stt",
event_filters=["stt.job.completed"],
ssl_verification=True
)
# Endpoint for TTS job events (uses TTS key)
tts_endpoint = tts_client.webhooks.create_endpoint(
url="https://your-server.com/webhook-tts",
event_filters=["tts.job.completed"],
ssl_verification=True
)
print(f"STT Endpoint ID: {stt_endpoint.id}, Secret: {stt_endpoint.secrets[0].key}")
print(f"TTS Endpoint ID: {tts_endpoint.id}, Secret: {tts_endpoint.secrets[0].key}")
List Endpoints
# List STT webhook endpoints
stt_endpoints = stt_client.webhooks.list_endpoints()
# List TTS webhook endpoints
tts_endpoints = tts_client.webhooks.list_endpoints()
for ep in tts_endpoints:
print(f"{ep.id}: {ep.url}")
Update and Delete Endpoints
# Update/delete on the same client you used to create (STT or TTS)
stt_client.webhooks.update_endpoint(
endpoint_id="endpoint-123",
url="https://your-server.com/new-webhook",
event_filters=[]
)
stt_client.webhooks.delete_endpoint("endpoint-123")
Rotate Secrets
tts_client.webhooks.rotate_secret(
endpoint_id="endpoint-123",
days=3, # Old secret valid for 3 days
hours=0
)
Event Management
# List events (from the client whose webhooks you're querying)
events = tts_client.webhooks.list_events(
from_date="2024-01-01",
to_date="2024-01-31"
)
event = tts_client.webhooks.get_event("event-123")
print(event.data)
Delivery Management
deliveries = tts_client.webhooks.list_deliveries("endpoint-123")
ticket = tts_client.webhooks.replay_delivery("delivery-123")
tickets = tts_client.webhooks.replay_failed_deliveries("endpoint-123")
ticket = tts_client.webhooks.test_endpoint("endpoint-123")
LiveKit Integration
GL Speech provides LiveKit agent plugins for real-time STT and TTS via WebSocket. Install the extra dependency first:
pip install "gl-speech[livekit]"
# or
uv add "gl-speech[livekit]"
STT Plugin
from gl_speech.livekit import STT
stt = STT(
api_key="your-stt-api-key",
wss_url="wss://your-stt-websocket-url",
model="stt-general-online", # default
language="id-ID", # default
)
TTS Plugin
from gl_speech.livekit import TTS
tts = TTS(
api_key="your-tts-api-key",
wss_url="wss://your-tts-websocket-url",
model="tts-dimas-formal", # default
)
Voice Agent Example
Use both plugins together in a LiveKit VoicePipelineAgent:
import asyncio
from livekit import rtc
from livekit.agents import AutoSubscribe, JobContext, WorkerOptions, cli
from livekit.agents.pipeline import VoicePipelineAgent
from livekit.plugins import openai # or any LLM plugin
from gl_speech.livekit import STT, TTS
stt = STT(
api_key="your-stt-api-key",
wss_url="wss://your-stt-websocket-url",
)
tts = TTS(
api_key="your-tts-api-key",
wss_url="wss://your-tts-websocket-url",
)
async def entrypoint(ctx: JobContext):
await ctx.connect(auto_subscribe=AutoSubscribe.AUDIO_ONLY)
agent = VoicePipelineAgent(
stt=stt,
llm=openai.LLM(),
tts=tts,
)
agent.start(ctx.room)
await asyncio.sleep(float("inf"))
if __name__ == "__main__":
cli.run_app(WorkerOptions(entrypoint_fnc=entrypoint))
Run the agent with:
python agent.py start
Error Handling
import httpx
from gl_speech import SpeechClient
stt_client = SpeechClient(api_key="your-stt-api-key", base_url="https://api.prosa.ai/v2/speech/")
try:
result = stt_client.stt.transcribe(model="stt-general", data="invalid")
except httpx.HTTPStatusError as e:
print(f"HTTP Error: {e.response.status_code}")
print(f"Response: {e.response.text}")
except ValueError as e:
print(f"Validation Error: {e}")
Testing
Unit tests
cd libs/gl-speech
uv sync --group dev
uv run pytest tests/unit_tests/ -v
Integration tests (live)
The integration tests exercise a real Prosa Speech instance. They carry the
integration marker and are excluded from the default run, so uv run pytest
never touches the network. Copy .env.example to .env, fill in your Prosa Speech
API keys, then select them explicitly with -m integration:
uv run pytest tests/integration_tests/ -m integration -v
STT and TTS are gated independently on GLSPEECH_STT_API_KEY / GLSPEECH_TTS_API_KEY,
so each service's live tests are skipped unless its key is present. Read-only calls
(list_models, list_jobs, count_jobs) run by default; set
GLSPEECH_TEST_CREATE_JOBS=1 to also exercise the transcription/synthesis endpoints
that create real jobs. For a scheduled live job that must fail rather than skip when
credentials are missing, set GLSPEECH_TEST_REQUIRE_LIVE=1.
For a one-off manual check of every endpoint (including archive and the webhooks
surface, which the pytest suite does not cover), run the standalone acceptance
script instead:
python examples/verify_sdk.py
API Reference
License
MIT License.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
File details
Details for the file gl_speech-0.0.2.tar.gz.
File metadata
- Download URL: gl_speech-0.0.2.tar.gz
- Upload date:
- Size: 21.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
uv/0.8.24
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
31cce3863ed68b430645c53a145489b5adf5f403b8652919860481a803b5532b
|
|
| MD5 |
ab973155fc4fca3eab4954bbee69bc80
|
|
| BLAKE2b-256 |
db414ca8e146cc2572d3509f04a341c84d31c1578b8e9117d755144bfc58d7e0
|