Transcribe audio files or stream live audio in Hindi and English with the Parrot STT Python SDK, with every parameter, event and error, and the STT dashboard.
The ringglabs Python SDK sends a complete audio file in one REST request, or streams live audio over a WebSocket and returns transcripts while the speaker talks; every feature works with both a synchronous Client and an AsyncClient.Parrot is in beta: SDK v0.1.x, MIT licence, Python 3.10 or later. Parameters and event fields can change before general availability.
Feature
Support
Languages
Hindi (hi, the default) and English (en)
File formats
WAV, MP3, FLAC, M4A
File size
Up to 10 MB per file
Streaming audio
Raw mono PCM, 8,000 to 48,000 Hz, int16, linear16, int32 or float32
Billing
A streaming rate per hour of audio, in your workspace currency; see the Pricing tab below
Sidebar → Labs → STT (page heading Speech To Text, marked BETA) transcribes without code and shows your usage. Its API docs button opens the SDK on PyPI. The page has four tabs:
Tab
What it holds
Quick start
The try-it panel and the install, key and first-call steps below
Logs
Every request, 50 per page
Usage
Total requests, Audio processed, Credits used, and Daily credit usage for the past 14 days
Pricing
Your Streaming rate per hour, the 30 included concurrent streams, and Contact sales for more
Logs lists Request ID, Timestamp, Duration, Mode, Credits and Status, filtered by Status (In progress, Done, Failed), Mode (Streaming, On Final, REST) and a date range. Click a row to open the STT Request drawer with the request’s Parameters and Latency.In the try-it panel, pick Language (English or Hindi; Hindi is the default), switch Punctuation on if you want capitalisation and punctuation (off by default here; the SDK defaults it to on), then Upload file (WAV, MP3, FLAC or M4A, up to 10 MB) or Transcribe live from your microphone. The result shows on Transcription; Code shows the same request as TypeScript, Python and cURL.
The video ends at the API key the SDK needs; the steps below start there.
A tour of the STT page: file upload, then the Logs, Usage and Pricing tabs and the API key
1
Install
Add the SDK to your environment:
pip install ringglabs
2
Get an API key
The SDK uses your workspace API key, generated under Settings → API key. Store it as RINGG_API_KEY.The workspace needs at least one minute of credit to start a transcription.
The key is shown once, when generated
3
First call
Transcribe a local audio file:
import osfrom ringglabs.stt import Clientwith Client(api_key=os.environ["RINGG_API_KEY"]) as client: result = client.transcribe("sample.wav", language="en") print(result.transcription)
Pick the example that matches your audio source and execution model. The streaming examples read a WAV file and send it in 20 ms chunks, using two helpers from Audio helpers; for live audio, send each chunk as it is captured instead (20 to 40 ms chunks work best).
Sync stream
Async stream
On-final
Offline
Bytes / IO
import osfrom ringglabs.stt import Client, TimeoutError as SdkTimeoutErrorfrom audio_helpers import load_wav_mono_int16_16k, iter_pcm_chunkssample_rate, audio = load_wav_mono_int16_16k("sample.wav")transcripts = []with Client(api_key=os.environ["RINGG_API_KEY"]) as client, client.stream( sample_rate=sample_rate, encoding="int16", language="en", mode="stream", enable_cap_punc=True,) as session: for chunk in iter_pcm_chunks(audio, sample_rate, 20): session.send_audio(chunk) session.end() try: for event in session.events(): if event.type == "transcript" and event.transcription.strip(): transcripts.append(event.transcription.strip()) except SdkTimeoutError: passprint(transcripts)
import asyncioimport osfrom ringglabs.stt import AsyncClient, TimeoutError as SdkTimeoutErrorfrom audio_helpers import load_wav_mono_int16_16k, iter_pcm_chunksasync def main(): sample_rate, audio = load_wav_mono_int16_16k("sample.wav") async with AsyncClient(api_key=os.environ["RINGG_API_KEY"]) as client, client.stream( sample_rate=sample_rate, encoding="int16", language="en", mode="stream", enable_cap_punc=True, ) as session: for chunk in iter_pcm_chunks(audio, sample_rate, 20): await session.send_audio(chunk) await session.end() try: async for event in session.events(): if event.type == "transcript": print(event.transcription) except SdkTimeoutError: passasyncio.run(main())
import osfrom ringglabs.stt import Client, TimeoutError as SdkTimeoutErrorfrom audio_helpers import load_wav_mono_int16_16k, iter_pcm_chunkssample_rate, audio = load_wav_mono_int16_16k("sample.wav")partials, finals = [], []with Client(api_key=os.environ["RINGG_API_KEY"]) as client, client.stream( sample_rate=sample_rate, encoding="int16", language="en", mode="on_final", accept_client_vad_events=True,) as session: session.start_speaking() for chunk in iter_pcm_chunks(audio, sample_rate, 20): session.send_audio(chunk) session.stop_speaking() session.end() try: for event in session.events(): if event.type != "transcript": continue text = event.transcription.strip() (finals if event.is_final else partials).append(text) except SdkTimeoutError: passprint(finals)
import osfrom ringglabs.stt import Clientwith Client(api_key=os.environ["RINGG_API_KEY"]) as client: result = client.transcribe( "sample.wav", language="en", enable_cap_punc=True, ) print(result.request_id, result.transcription)
Client(...) and AsyncClient(...) share the same constructor. Both can be used as context managers (with / async with), which close the underlying connections on exit.
Parameter
Default
Description
base_url
"prod-api.ringg.ai"
Host name.
api_key
None
Default API key for all requests; can be overridden per call.
Open a streaming session, send audio chunks, and receive transcript events. Use it as a context manager so the session is opened on entry and closed on exit.
Parameter
Default
Description
sample_rate
16000
Audio sample rate in Hz, from 8000 to 48000.
encoding
"int16"
int16, linear16, float32, or int32. Audio must be raw mono PCM with no file header.
language
"hi"
Language hint: "hi" or "en".
mode
"stream"
"stream" or "on_final". See below.
vad_tail_sil_ms
200
Server tail silence in ms: how long a pause ends a segment.
vad_confidence
0.55
Server VAD confidence threshold.
enable_cap_punc
True
Capitalization / punctuation.
accept_client_vad_events
False
Enables start_speaking() / stop_speaking(). Only applies in on_final mode.
stream: the server detects pauses with its own voice activity detection (VAD) and sends a final transcript event for each spoken segment. Join the segments to build the full transcript. The session’s closing transcript event can have an empty transcription, so skip blank ones.
on_final: you mark each turn with start_speaking() and stop_speaking() (requires accept_client_vad_events=True). The server sends partial transcripts (is_final=False) that grow as the turn continues, then one final transcript (is_final=True) after stop_speaking().
Once, when the session opens. Confirms the effective settings and the session’s request_id. The SDK reads it during the handshake and exposes it as session.ready_event.
transcript
A transcription result. See the fields below.
ack
Acknowledges a VAD event or end. ack_for names the message and state gives the result.
pong
Reply to ping(), with a server timestamp.
error
The server rejected a message or ended the session. Read code and detail.
All SDK exceptions are importable from ringglabs.stt and inherit from RinggLabsError.
Exception
Raised when
ValidationError
An argument is invalid, for example a file path that doesn’t exist.
ApiError
The server returns an error. Has message, status_code, code, and payload.
AuthenticationError
The API key is missing or invalid (401), or the workspace doesn’t have enough credit (402). Subclass of ApiError.
TransportError
A network failure.
TimeoutError
A request or receive exceeded its timeout. Subclass of TransportError.
ProtocolError
The server sent a malformed or unexpected message.
A file over 10 MB is rejected with an ApiError (status_code=413), and a file in another format with status_code=415 (codeUNSUPPORTED_AUDIO_FORMAT). A streaming session ends after one hour with the error code MAX_DURATION_EXCEEDED, and after 5 minutes without a message from the client with SESSION_TIMEOUT.