FonadaLabs SDK
Unified Python SDK for FonadaLabs Text-to-Speech (TTS), Automatic Speech Recognition (ASR), and Audio Denoising APIs.
Table of Contents
- Features
- Installation
- Quick Start
- Authentication
- Advanced Features
- Error Handling
- Security Features
- Documentation
- Examples
- Package Structure
- Importing
- Requirements
- License
- Support
Features
Text-to-Speech (TTS)
- 🎙️ Voice-clone speech with
klone_v2_flash(default) andklone_v2_pro - 🗂️ Catalog voices via
share_id(enterprise: your ownaudio_url/audio) - 🔊 Flash streaming over HTTPS and WebSocket (pcm, wav, mp3, opus, mulaw, alaw)
- 🌍 Multi-language support (Hindi, English, Telugu, Tamil, and more)
- ⚡ Async support for concurrent requests
- 🔒 Secure API key authentication
- ⚠️ Built-in error handling for rate limits and credit exhaustion
Automatic Speech Recognition (ASR)
- 🎤 Audio file transcription with ASR
v3(long audio, chunked server-side) - 🔄 Concurrent batch processing
- 🌍 Multi-language support (validated by the API)
- 🔒 Secure API key authentication
- ⚠️ Comprehensive error handling
Audio Denoising
- 🔇 High-quality audio denoising (DeepFilterNet + CMGAN)
- 🎯 Full audio and streaming chunk processing
- ⚡ Real-time WebSocket streaming with progress callbacks
- 📦 Batch processing support
- 🔒 Secure API key authentication
- ⚠️ Built-in rate limit and credit management
Installation
From PyPI (Recommended)
# Install with all dependencies for TTS, ASR, and Denoise
pip install fonadalabs
Note for Windows users: Make sure you have Python 3.9-3.12 and upgraded pip:
python -m pip install --upgrade pip setuptools wheel
pip install fonadalabs
From Source (Development)
git clone https://github.com/fonadalabs/fonadalabs-sdk.git
cd fonadalabs-sdk
pip install -e .
For Development
# Install with development tools (pytest, black, etc.)
pip install fonadalabs[dev]
Quick Start
Text-to-Speech (TTS)
from fonadalabs import TTSClient, TTSError, CreditsExhaustedError, RateLimitError
# Initialize with API key (or set FONADALABS_API_KEY env variable)
client = TTSClient(api_key="your-api-key-here")
try:
# Generate audio (model="klone_v2_flash" by default) with a catalog voice
audio_data = client.generate_audio(
text="नमस्ते! यह FonadaLabs TTS SDK का परीक्षण है।",
language="Hindi",
share_id="catalog-share-id",
output_file="output.wav"
)
print(f"✓ Generated {len(audio_data)} bytes")
except CreditsExhaustedError as e:
print(f"⚠️ API credits exhausted. Balance: {e.remaining_balance}")
except RateLimitError as e:
print(f"⚠️ Rate limit exceeded. Retry after: {e.retry_after_seconds}s")
except TTSError as e:
print(f"❌ TTS Error: {e}")
Automatic Speech Recognition (ASR)
from fonadalabs import (
ASRClient,
ASRSDKError,
AuthenticationError,
ASRCreditsExhaustedError,
ASRRateLimitError,
)
# Initialize with API key (or set FONADALABS_API_KEY env variable)
asr_client = ASRClient(api_key="your-api-key-here")
try:
# Transcribe audio file (model="v3" by default, POST /v3/asr/transcribe)
result = asr_client.transcribe_file(
"audio.wav",
language_id="hi",
)
print(f"✓ Transcription: {result.text}")
print(f"✓ Language: {result.language_id}")
print(f"✓ Credits: {result.credits_used}")
print(f"✓ Duration: {result.audio_duration_s}s")
except ASRCreditsExhaustedError as e:
print(f"⚠️ API credits exhausted. Usage: {e.current_usage}")
except ASRRateLimitError as e:
print(f"⚠️ Rate limit exceeded. Retry after: {e.retry_after_seconds}s")
except AuthenticationError as e:
print(f"❌ Authentication failed: {e}")
except ASRSDKError as e:
print(f"❌ ASR Error: {e}")
Audio Denoising
from fonadalabs import (
DenoiseHttpClient,
DenoiseStreamingClient,
DenoiseCreditsExhaustedError,
DenoiseRateLimitError
)
try:
# Full audio denoising (HTTP)
http_client = DenoiseHttpClient(api_key="your-api-key-here")
denoised = http_client.denoise_file("noisy.wav", "clean.wav")
print("✓ Denoised audio saved to clean.wav")
# Streaming denoising with progress
streaming_client = DenoiseStreamingClient(api_key="your-api-key-here")
def progress_callback(current, total):
percent = (current / total) * 100
print(f"Progress: {current}/{total} chunks ({percent:.1f}%)")
denoised = streaming_client.denoise_file(
"noisy.wav",
"clean.wav",
progress_callback=progress_callback
)
print("✓ Streaming denoising complete!")
except DenoiseCreditsExhaustedError:
print("⚠️ API credits exhausted. Please add more credits.")
except DenoiseRateLimitError:
print("⚠️ Rate limit exceeded. Please try again later.")
except Exception as e:
print(f"❌ Denoise Error: {e}")
Authentication
All FonadaLabs APIs require API key authentication. You can obtain your API key from the FonadaLabs Dashboard.
Method 1: Environment Variable (Recommended)
# Set environment variable
export FONADALABS_API_KEY=your-api-key-here
# Or add to .env file
echo "FONADALABS_API_KEY=your-api-key-here" >> .env
Then use the SDK without passing the key:
from fonadalabs import TTSClient, ASRClient, DenoiseHttpClient
# API key is automatically loaded from environment
tts_client = TTSClient()
asr_client = ASRClient()
denoise_client = DenoiseHttpClient()
Method 2: Pass Directly in Code
from fonadalabs import TTSClient, ASRClient, DenoiseHttpClient
tts_client = TTSClient(api_key="your-api-key")
asr_client = ASRClient(api_key="your-api-key")
denoise_client = DenoiseHttpClient(api_key="your-api-key")
⚠️ Security Note: Never hardcode API keys in your source code. Always use environment variables or secure key management systems.
Advanced Features
Retired: TTS v1 and ASR v1 / v2
These models are no longer served. The SDK raises an error before sending any request:
| Call | Raises |
|---|---|
TTSClient.generate_audio(..., model="v1") |
TTSError: TTS v1 model 'v1' has been retired. Use generate_audio(text, language=..., share_id='<catalog-share-id>') ... |
TTSClient.generate_audio(text, "Vaanee") (voice name, no share_id) |
TTSError: Voice names like 'Vaanee' were TTS v1, which has been retired. Pass a catalog share_id instead ... |
TTSClient.generate_audio_ws(...) |
TTSError: TTS v1 WebSocket streaming ... has been retired ... (use stream_session()) |
ASRClient.transcribe_file(..., model="v1") |
ValidationError: ASR model 'v1' has been retired. Use model='v3' (now the default) ... |
ASRClient.transcribe_file(..., model="v2") |
ValidationError: ASR model 'v2' has been retired and renamed to 'v3'. Use model='v3' ... |
ASRClient.stream_transcribe_file(...) / ASRWebSocketClient(...) |
ValidationError: ASR v1 real-time streaming (WebSocket) has been retired ... |
At the gateway, POST /v2/asr/transcribe is still proxied to /v3/asr/transcribe for
older SDK installs, but new code should use v3.
Languages
The SDK does not check languages; it sends language / language_id as given and the
API normalizes it (ISO codes like hi, names like Hindi, en-IN → en) and validates
it. An unsupported language comes back as a 400 whose body lists the supported
languages; the SDK raises it as ValidationError (ASR) or TTSError (TTS).
Context Manager Support
Use TTSClient with Python's context manager for automatic resource cleanup:
from fonadalabs import TTSClient
# Resources are automatically cleaned up after the block
with TTSClient(api_key="your-api-key") as client:
audio = client.generate_audio(
text="Testing context manager",
language="English",
share_id="catalog-share-id",
output_file="output.wav"
)
print(f"Generated: {len(audio)} bytes")
Async Operations (TTS)
Use async methods for concurrent requests:
import asyncio
from fonadalabs import TTSClient
client = TTSClient(api_key="your-api-key")
async def generate_multiple():
tasks = [
client.generate_audio_async("Text 1", language="Hindi", share_id="share-id-1"),
client.generate_audio_async("Text 2", language="English", share_id="share-id-2"),
client.generate_audio_async(
"Text 3", language="Telugu", share_id="share-id-3", model="klone_v2_pro"
),
]
return await asyncio.gather(*tasks)
audio_files = asyncio.run(generate_multiple())
Flash Streaming (TTS)
klone_v2_flash can stream audio while it is generated. The default output is raw
pcm (16-bit little-endian, 24 kHz, mono, no header); wav, mp3, opus, mulaw
and alaw (both 8 kHz) are also available. Text can be up to 5,000 characters.
from fonadalabs import TTSClient
client = TTSClient(api_key="your-api-key")
with open("out.pcm", "wb") as f:
for chunk in client.stream_audio(
"नमस्ते, आपका स्वागत है।",
language="Hindi",
share_id="catalog-share-id",
output_audio_codec="pcm",
speed=1.1, # 0.25–4.0
instruct="calm, friendly", # up to 500 characters
):
f.write(chunk)
print(client.last_stream_info) # codec, sample_rate, channels, credits_charged
stream_audio_async(...) takes the same arguments (async for chunk in ...).
For voice agents, keep one WebSocket open and send many utterances; a rejected
utterance raises VoiceCloneError and the connection stays open:
import asyncio
from fonadalabs import TTSClient
async def main():
client = TTSClient(api_key="your-api-key")
async with client.stream_session() as session:
for line in ["Hello!", "How can I help you today?"]:
async for chunk in session.speak(line, language="en", share_id="catalog-share-id"):
play(chunk)
print(session.last_end) # audio_bytes, first_audio_ms, total_ms
asyncio.run(main())
Flash options (all optional): speed (0.25–4.0), duration (0.1–60 s, overrides
speed), instruct (up to 500 characters), num_step (8–64, advanced). With
audio_url / audio (enterprise), audio_text can be omitted and the API transcribes
the reference clip (except Urdu). generate_audio(..., model="klone_v2_flash") also
applies these options; it then collects the streamed audio and returns it in one piece.
Only Flash streams; klone_v2_pro raises TTSError.
Batch Processing (ASR)
Process multiple audio files concurrently:
from fonadalabs import ASRClient
client = ASRClient(api_key="your-api-key")
# List of audio files to transcribe
file_paths = ["audio1.wav", "audio2.wav", "audio3.wav"]
# Batch transcribe with custom concurrency
results = client.batch_transcribe(
file_paths=file_paths,
language_id="en",
concurrency=3
)
# Process successful transcriptions
for result in results.successful:
print(f"✓ {result.file_path}: {result.text}")
# Handle failed transcriptions
for failed in results.failed:
print(f"✗ {failed.file_path}: {failed.error}")
Error Handling
The SDK provides specific exception types for different error scenarios:
TTS Exceptions
from fonadalabs import (
TTSError, # Base exception
CreditsExhaustedError, # Credits exhausted (402/429)
RateLimitError # Rate limit exceeded (429)
)
# Exception usage example
try:
audio = client.generate_audio("Text", language="Hindi", share_id="catalog-share-id")
except CreditsExhaustedError as e:
print(f"Credits exhausted. Balance: {e.remaining_balance}, Cost: {e.estimated_cost}")
except RateLimitError as e:
print(f"Rate limited. Limit: {e.rate_limit}, Retry after: {e.retry_after_seconds}s")
except TTSError as e:
print(f"TTS Error: {e}")
ASR Exceptions
from fonadalabs import (
ASRSDKError, # Base exception
AuthenticationError, # Invalid API key (401/403)
ValidationError, # Invalid parameters
HTTPRequestError, # HTTP request failed
ServerError, # Server error (500+)
ASRRateLimitError, # Rate limit exceeded (429)
ASRTimeoutError, # Request timeout
ASRCreditsExhaustedError # Credits exhausted (402/429)
)
# Exception usage example
try:
result = asr_client.transcribe_file("audio.wav", language_id="hi")
except ASRCreditsExhaustedError as e:
print(f"Credits exhausted. Usage: {e.current_usage}, Limit: {e.credit_limit}")
except ASRRateLimitError as e:
print(f"Rate limited. Limit: {e.rate_limit}, Reset at: {e.reset_at}")
except AuthenticationError as e:
print(f"Auth failed: {e}")
except ValidationError as e:
print(f"Invalid parameters: {e}")
except ASRSDKError as e:
print(f"ASR Error: {e}")
Denoise Exceptions
from fonadalabs import (
DenoiseError, # Base exception
DenoiseCreditsExhaustedError, # Credits exhausted
DenoiseRateLimitError # Rate limit exceeded
)
Security Features
🔒 Base URL Lockdown
All SDK clients use hardcoded, secure base URLs that cannot be overridden. This prevents:
- URL injection attacks
- Data exfiltration attempts
- Man-in-the-middle attacks
# ✅ SECURE: Base URLs are locked
client = TTSClient(api_key="your-key")
# ❌ PREVENTED: Cannot override base URL
# client = TTSClient(api_key="key", base_url="http://malicious.com") # Not allowed
Base URLs can only be configured via environment variables by authorized administrators:
export FONADALABS_API_URL=https://your-secure-endpoint.com
🔐 API Key Validation
All API requests are validated:
- API keys are required for all endpoints
- Invalid keys return
401 Unauthorized - Keys are transmitted securely via HTTPS
- Never logged or exposed in error messages
Documentation
- TTS Documentation: See TEXT_TO_SPEECH_QUICKSTART.md
- ASR Documentation: See ASR_AUTHENTICATION.md
- Denoise Documentation: See denoise_sdk/README.md
- Security Audit: See SECURITY_AUDIT_REPORT.md
Examples
TTS Examples
Located in tts_sdk/examples/:
basic_usage.py- Simple HTTP generationwebsocket_usage.py- WebSocket with progress trackingasync_usage.py- Concurrent requestsstreaming_usage.py- Audio chunk streamingauth_usage.py- Authentication examples
ASR Examples
Located in test/:
asr_test.py- Comprehensive test suite with all features- Tests include: HTTP POST, WebSocket, multiple languages, error handling
Run ASR Tests:
# Set API key
export FONADALABS_API_KEY="your_api_key_here"
# Run all tests
cd test
python asr_test.py --audio test_audio.wav
# Run specific test
python asr_test.py --test post # HTTP POST transcription
python asr_test.py --test ws # WebSocket transcription
python asr_test.py --test languages # Test multiple languages
python asr_test.py --test errors # Error handling
Denoise Examples
Located in denoise_sdk/:
sdk_test.py- Quick start examples for HTTP and WebSocket denoising
Package Structure
fonadalabs/
├── __init__.py # Unified package exports
├── tts/ # TTS submodule
│ ├── __init__.py
│ └── client.py # TTSClient
├── asr/ # ASR submodule
│ ├── __init__.py
│ ├── client.py # ASRClient
│ ├── ws_client.py # ASRWebSocketClient (retired stub)
│ ├── config.py # Configuration
│ ├── exceptions.py # ASR exceptions
│ ├── utils.py # Utility functions
│ └── models/ # Data models
│ └── types.py
└── denoise/ # Denoise submodule
├── __init__.py
├── http_client.py # DenoiseHttpClient
├── streaming_client.py # DenoiseStreamingClient
└── exceptions.py # Denoise exceptions
Importing
All Three SDKs
from fonadalabs import (
TTSClient,
ASRClient,
DenoiseHttpClient,
DenoiseStreamingClient
)
tts = TTSClient(api_key="your-key")
asr = ASRClient(api_key="your-key")
denoise = DenoiseHttpClient(api_key="your-key")
TTS Only
from fonadalabs import TTSClient, TTSError, CreditsExhaustedError, RateLimitError
# or explicitly from submodule
from fonadalabs.tts import TTSClient, TTSError
ASR Only
from fonadalabs import ASRClient
# or explicitly from submodule
from fonadalabs.asr import ASRClient
Denoise Only
from fonadalabs import DenoiseHttpClient, DenoiseStreamingClient
# or explicitly from submodule
from fonadalabs.denoise import DenoiseHttpClient, DenoiseStreamingClient
Requirements
Dependencies (Installed Automatically)
Python: >= 3.9 (3.9, 3.10, 3.11, 3.12 supported)
Core Libraries:
- httpx >= 0.24, < 1.0 (HTTP client)
- websockets >= 11, < 13 (WebSocket support)
- loguru >= 0.7, < 1.0 (Logging)
- requests >= 2.28, < 3.0 (HTTP requests)
Audio Processing (for all services):
- numpy >= 1.24.0, < 2.0 (Audio processing)
- soundfile >= 0.12, < 0.14 (Audio I/O)
- librosa >= 0.10, < 1.0 (Audio analysis - denoise)
- websocket-client >= 1.5, < 2.0 (WebSocket streaming)
Development (optional - pip install fonadalabs[dev]):
- pytest >= 7.0, < 8.0
- black >= 23.0, < 24.0
- isort >= 5.0, < 6.0
- python-dotenv >= 1.0, < 2.0
- nest-asyncio >= 1.5, < 2.0
- build >= 0.10.0
- twine >= 4.0.0
Contributing
We welcome contributions! Please see our contributing guidelines and feel free to submit pull requests.
License
MIT License - see LICENSE file for details.
Copyright (c) 2025 FonadaLabs
Support
- 📧 Email: support@fonadalabs.com
- 🐛 Issues: GitHub Issues
- 📖 Documentation:
- 🌐 Website: https://fonadalabs.com
- 💬 Community: Discord (if available)
Version
Current version: 3.0.0 (Unified SDK)
Version History
- v3.0.0 (2026-10-22): Retire TTS v1 and ASR v1 (breaking); Flash streaming
- TTS: default model is now
klone_v2_flash;model="v1", voice names withoutshare_idandgenerate_audio_wsraiseTTSError - TTS:
stream_audio/stream_audio_async(HTTPS) andstream_session(WebSocket) forklone_v2_flash; codecs pcm (default), wav, mp3, opus, mulaw, alaw - TTS: Flash now applies
speed,duration,instructand the newnum_step; Flashaudio_url/audiono longer requireaudio_text - ASR:
v3is the default and only model;model="v1"/"v2",stream_transcribe_fileandASRWebSocketClientraiseValidationError - Languages are validated by the API, not the SDK: removed
is_supported_language,normalize_language,prepare_language_id,SUPPORTED_LANGUAGESandSUPPORTED_LANGUAGES_V3 - Fixed
ASRClient.close()raising after async calls run viaasyncio.run()
- TTS: default model is now
- v2.0.0 (2025-12-05): Multi-language TTS support
- Added
languageparameter to all TTS methods - Supports 4 languages: Hindi, English, Tamil, Telugu
- Updated SDK documentation
- Added
- v1.0.0 (2025-10-16): Unified package with TTS, ASR, and Denoise
- Base URL security lockdown
- Required API key authentication for all endpoints
- Comprehensive error handling with specific exception types
- WebSocket streaming support for all services
- Async/await support
- Batch processing capabilities
Made with ❤️ by FonadaLabs
Metadata
Release files for fonadalabs 3.0.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| fonadalabs-3.0.0.tar.gz | 74.6 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| fonadalabs-3.0.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 128.7 kB
Release files / fonadalabs-3.0.0.tar.gz
| Download URL | fonadalabs-3.0.0.tar.gz |
|---|---|
| Size | 74.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
f62ce4a1d242142f8a1b3db8febe9d87b379775f9fb97367f1628b285d16c579
|
|
BLAKE2b-256 checksum How to use checksums |
9d7ab36a9b9dda2baefe77194c1da6123c31a0b56a4815e9e91e8604ea80f996
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.11
|
Release files / fonadalabs-3.0.0-py3-none-any.whl
| Download URL | fonadalabs-3.0.0-py3-none-any.whl |
|---|---|
| Size | 54.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
68776862bd705a375a134e2b9c6e18a8ba2e32be1106546f498208f6a6e427cf
|
|
BLAKE2b-256 checksum How to use checksums |
9bef14a9cea8144923ff5e77803c28341c889b45cd5ae04f850d6879df895725
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.11
|
Security for fonadalabs 3.0.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.