fonadalabs


Namefonadalabs JSON
Version 2.0.2 PyPI version JSON
download
home_pagehttps://github.com/fonadalabs/fonadalabs-sdk
SummaryUnified Python SDK for FonadaLabs Text-to-Speech, Automatic Speech Recognition, and Audio Denoising APIs
upload_time2025-11-03 09:40:47
maintainerNone
docs_urlNone
authorFonadaLabs
requires_python>=3.9
licenseMIT
keywords text-to-speech speech-recognition audio-denoising tts asr denoise fonadalabs speech audio ai machine-learning
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # FonadaLabs SDK

[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![Python 3.9+](https://img.shields.io/badge/python-3.9+-blue.svg)](https://www.python.org/downloads/)
[![Version 1.0.0](https://img.shields.io/badge/version-1.0.0-green.svg)](https://github.com/fonadalabs/fonadalabs-sdk)

Unified Python SDK for FonadaLabs **Text-to-Speech (TTS)**, **Automatic Speech Recognition (ASR)**, and **Audio Denoising** APIs.

## Table of Contents

- [Features](#features)
- [Installation](#installation)
- [Quick Start](#quick-start)
  - [Text-to-Speech (TTS)](#text-to-speech-tts)
  - [Automatic Speech Recognition (ASR)](#automatic-speech-recognition-asr)
  - [Audio Denoising](#audio-denoising)
- [Authentication](#authentication)
- [Advanced Features](#advanced-features)
- [Error Handling](#error-handling)
- [Security Features](#security-features)
- [Documentation](#documentation)
- [Examples](#examples)
- [Package Structure](#package-structure)
- [Importing](#importing)
- [Requirements](#requirements)
- [License](#license)
- [Support](#support)

## Features

### Text-to-Speech (TTS)
- ๐ŸŽ™๏ธ High-quality text-to-speech generation with multiple voices
- ๐Ÿš€ HTTP POST and WebSocket support
- ๐Ÿ“Š Real-time progress tracking
- โšก Async support for concurrent requests
- ๐ŸŽต Audio streaming with chunk callbacks
- ๐Ÿ”’ Secure API key authentication
- โš ๏ธ Built-in error handling for rate limits and credit exhaustion

### Automatic Speech Recognition (ASR)
- ๐ŸŽค Audio file transcription
- ๐ŸŒ WebSocket streaming for real-time transcription
- ๐Ÿ”„ Concurrent batch processing
- ๐ŸŒ Multi-language support (50+ languages)
- ๐Ÿ”’ 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)

```bash
pip install fonadalabs
```

### From Source (Development)

```bash
git clone https://github.com/fonadalabs/fonadalabs-sdk.git
cd fonadalabs-sdk
pip install -e .
```

### With Optional Dependencies

```bash
# For WebSocket support (TTS + ASR streaming)
pip install fonadalabs[ws]

# For audio denoising features
pip install fonadalabs[denoise]

# Install everything
pip install fonadalabs[all]

# For development
pip install fonadalabs[dev]
```

## Quick Start

### Text-to-Speech (TTS)

```python
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
    audio_data = client.generate_audio(
        text="เคจเคฎเคธเฅเคคเฅ‡! เคฏเคน FonadaLabs TTS SDK เค•เคพ เคชเคฐเฅ€เค•เฅเคทเคฃ เคนเฅˆเฅค",
        voice="Pravaha",
        output_file="output.wav"
    )
    print(f"โœ“ Generated {len(audio_data)} bytes")
    
except CreditsExhaustedError as e:
    print(f"โš ๏ธ API credits exhausted. Balance: {e.current_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)

```python
from fonadalabs import (
    ASRClient, 
    ASRSDKError,
    AuthenticationError,
    ASRCreditsExhaustedError,
    ASRRateLimitError,
    is_supported_language
)

# Initialize with API key (or set FONADALABS_API_KEY env variable)
asr_client = ASRClient(api_key="your-api-key-here")

try:
    # Check if language is supported
    if is_supported_language("hi"):
        print("โœ“ Hindi is supported!")
    
    # Transcribe audio file
    result = asr_client.transcribe_file(
        audio_path="audio.wav",
        language_id="hi"  # Hindi
    )
    print(f"โœ“ Transcription: {result.text}")
    print(f"โœ“ Language: {result.language_id}")
    print(f"โœ“ File: {result.file_path}")
    
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

```python
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](https://fonadalabs.com/dashboard).

### Method 1: Environment Variable (Recommended)

```bash
# 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:

```python
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

```python
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

### Available TTS Voices

FonadaLabs TTS supports multiple high-quality Hindi voices:

| Voice Name | Description | Gender | Best For |
|-----------|-------------|--------|----------|
| **Pravaha** | Clear, professional | Female | Business, formal content |
| **Shruti** | Warm, friendly | Female | Casual conversation, storytelling |
| **Aabha** | Energetic, bright | Female | Educational, upbeat content |
| **Svara** | Melodious, soft | Female | Audiobooks, meditation |
| **Vaanee** | Strong, confident | Female | News, announcements |

**Usage:**
```python
from fonadalabs import TTSClient

client = TTSClient(api_key="your-api-key")

# Test different voices
for voice in ["Pravaha", "Shruti", "Aabha", "Svara", "Vaanee"]:
    audio = client.generate_audio(
        text="เคฏเคน เคเค• เค†เคตเคพเคœเคผ เค•เคพ เคชเคฐเฅ€เค•เฅเคทเคฃ เคนเฅˆเฅค",
        voice=voice,
        output_file=f"test_{voice.lower()}.wav"
    )
    print(f"โœ“ Generated audio with {voice} voice")
```

### Context Manager Support

Use TTSClient with Python's context manager for automatic resource cleanup:

```python
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",
        voice="Pravaha",
        output_file="output.wav"
    )
    print(f"Generated: {len(audio)} bytes")

# Client is automatically closed here
print("Resources cleaned up automatically!")
```

### WebSocket Streaming (TTS)

Stream audio with real-time progress updates and callbacks:

```python
from fonadalabs import TTSClient

client = TTSClient(api_key="your-api-key")

# Define callbacks for streaming events
def on_chunk(chunk_num, chunk_bytes):
    print(f"๐Ÿ“ฆ Chunk {chunk_num} received: {len(chunk_bytes)} bytes")

def on_complete(stats):
    print(f"โœ… Complete! Chunks: {stats.get('chunks_sent')}, Bytes: {stats.get('bytes_sent')}")

def on_error(error_msg):
    print(f"โŒ Error: {error_msg}")

# Generate audio via WebSocket with callbacks
audio = client.generate_audio_ws(
    text="Hello! This is a WebSocket streaming test.",
    voice="Shruti",
    output_file="output.wav",
    on_chunk=on_chunk,
    on_complete=on_complete,
    on_error=on_error
)
```

### Async Operations (TTS)

Use async methods for concurrent requests:

```python
import asyncio
from fonadalabs import TTSClient

client = TTSClient(api_key="your-api-key")

async def generate_multiple():
    tasks = [
        client.generate_audio_async("Text 1", "Pravaha", "output1.wav"),
        client.generate_audio_async("Text 2", "Shruti", "output2.wav"),
        client.generate_audio_async("Text 3", "Aabha", "output3.wav"),
    ]
    results = await asyncio.gather(*tasks)
    return results

audio_files = asyncio.run(generate_multiple())
```

### WebSocket Streaming (ASR)

Real-time transcription with WebSocket - **2x faster than HTTP** for batch processing:

```python
from fonadalabs import ASRWebSocketClient, ASRSDKError

# Initialize WebSocket client (API key from env or parameter)
ws_client = ASRWebSocketClient(api_key="your-api-key")

try:
    # Transcribe using WebSocket (persistent connection)
    result = ws_client.transcribe(
        audio_path="audio.wav",
        language_id="hi"  # Hindi
    )
    
    # Result is a dict
    print(f"โœ“ Transcription: {result.get('text')}")
    print(f"โœ“ Status: {result.get('status')}")
    
except ASRSDKError as e:
    print(f"โŒ WebSocket transcription failed: {e}")

# Benefits:
# - Authenticate once, transcribe multiple files
# - 2x faster latency (190ms vs 382ms)
# - 95% less auth overhead
```

### Multiple Languages (ASR)

ASR supports **50+ languages** including all major Indian languages:

```python
from fonadalabs import ASRClient, is_supported_language, SUPPORTED_LANGUAGES

client = ASRClient(api_key="your-api-key")

# Check if a language is supported
if is_supported_language("hi"):
    print("โœ“ Hindi is supported!")

# Test multiple languages
languages = ["hi", "en", "ta", "te", "bn", "gu", "mr", "kn", "ml", "pa"]

for lang in languages:
    if is_supported_language(lang):
        result = client.transcribe_file("audio.wav", language_id=lang)
        print(f"{lang}: {result.text}")

# View all supported languages
print(f"Total languages: {len(SUPPORTED_LANGUAGES)}")
```

**Popular Indian Languages:**
- Hindi (`hi`), English (`en`), Tamil (`ta`), Telugu (`te`)
- Bengali (`bn`), Gujarati (`gu`), Marathi (`mr`), Kannada (`kn`)
- Malayalam (`ml`), Punjabi (`pa`), Odia (`or`), Assamese (`as`)
- Urdu (`ur`), Nepali (`ne`), Sanskrit (`sa`), and more!

### Batch Processing (ASR)

Process multiple audio files concurrently:

```python
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

```python
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", "Pravaha")
except CreditsExhaustedError as e:
    print(f"Credits exhausted. Balance: {e.current_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

```python
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

```python
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

```python
# โœ… 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:
```bash
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](tts_sdk/TEXT_TO_SPEECH_QUICKSTART.md)
- **ASR Documentation:** See [ASR_AUTHENTICATION.md](ASR_AUTHENTICATION.md)
- **Denoise Documentation:** See [denoise_sdk/README.md](denoise_sdk/README.md)
- **Security Audit:** See [SECURITY_AUDIT_REPORT.md](SECURITY_AUDIT_REPORT.md)

## Examples

### TTS Examples
Located in `tts_sdk/examples/`:
- `basic_usage.py` - Simple HTTP generation
- `websocket_usage.py` - WebSocket with progress tracking
- `async_usage.py` - Concurrent requests
- `streaming_usage.py` - Audio chunk streaming
- `auth_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:**
```bash
# 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
โ”‚   โ”œโ”€โ”€ config.py                 # Configuration
โ”‚   โ”œโ”€โ”€ exceptions.py             # ASR exceptions
โ”‚   โ”œโ”€โ”€ languages.py              # Language utilities
โ”‚   โ”œโ”€โ”€ 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
```python
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
```python
from fonadalabs import TTSClient, TTSError, CreditsExhaustedError, RateLimitError
# or explicitly from submodule
from fonadalabs.tts import TTSClient, TTSError
```

### ASR Only
```python
from fonadalabs import ASRClient, ASRWebSocketClient
# or explicitly from submodule
from fonadalabs.asr import ASRClient, ASRWebSocketClient
```

### Denoise Only
```python
from fonadalabs import DenoiseHttpClient, DenoiseStreamingClient
# or explicitly from submodule
from fonadalabs.denoise import DenoiseHttpClient, DenoiseStreamingClient
```

## Requirements

### Core Dependencies
- **Python** >= 3.9
- **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)
- **numpy** >= 1.21, < 2.0 (Audio processing)

### Optional Dependencies

**For WebSocket features (`pip install fonadalabs[ws]`):**
- soundfile >= 0.12, < 0.14
- websocket-client >= 1.5, < 2.0

**For Audio Denoising (`pip install fonadalabs[denoise]`):**
- soundfile >= 0.12, < 0.14
- librosa >= 0.10, < 1.0
- websocket-client >= 1.5, < 2.0

**For Development (`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

## Contributing

We welcome contributions! Please see our contributing guidelines and feel free to submit pull requests.

## License

MIT License - see [LICENSE](LICENSE) file for details.

Copyright (c) 2025 FonadaLabs

## Support

- ๐Ÿ“ง **Email:** support@fonadalabs.com
- ๐Ÿ› **Issues:** [GitHub Issues](https://github.com/fonadalabs/fonadalabs-sdk/issues)
- ๐Ÿ“– **Documentation:** 
  - [TTS Quickstart](tts_sdk/TEXT_TO_SPEECH_QUICKSTART.md)
  - [ASR Authentication](ASR_AUTHENTICATION.md)
  - [Denoise SDK](denoise_sdk/README.md)
- ๐ŸŒ **Website:** https://fonadalabs.com
- ๐Ÿ’ฌ **Community:** [Discord](https://discord.gg/fonadalabs) (if available)

## Version

**Current version:** 1.0.0 (Unified SDK)

### Version History
- **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**



            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/fonadalabs/fonadalabs-sdk",
    "name": "fonadalabs",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.9",
    "maintainer_email": null,
    "keywords": "text-to-speech, speech-recognition, audio-denoising, tts, asr, denoise, fonadalabs, speech, audio, ai, machine-learning",
    "author": "FonadaLabs",
    "author_email": "FonadaLabs <support@fonadalabs.com>",
    "download_url": "https://files.pythonhosted.org/packages/91/db/ff1a6bc11cf225686c2422557d4cf6adb27dcdeabe7f58d1c69e28b140ff/fonadalabs-2.0.2.tar.gz",
    "platform": null,
    "description": "# FonadaLabs SDK\n\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n[![Python 3.9+](https://img.shields.io/badge/python-3.9+-blue.svg)](https://www.python.org/downloads/)\n[![Version 1.0.0](https://img.shields.io/badge/version-1.0.0-green.svg)](https://github.com/fonadalabs/fonadalabs-sdk)\n\nUnified Python SDK for FonadaLabs **Text-to-Speech (TTS)**, **Automatic Speech Recognition (ASR)**, and **Audio Denoising** APIs.\n\n## Table of Contents\n\n- [Features](#features)\n- [Installation](#installation)\n- [Quick Start](#quick-start)\n  - [Text-to-Speech (TTS)](#text-to-speech-tts)\n  - [Automatic Speech Recognition (ASR)](#automatic-speech-recognition-asr)\n  - [Audio Denoising](#audio-denoising)\n- [Authentication](#authentication)\n- [Advanced Features](#advanced-features)\n- [Error Handling](#error-handling)\n- [Security Features](#security-features)\n- [Documentation](#documentation)\n- [Examples](#examples)\n- [Package Structure](#package-structure)\n- [Importing](#importing)\n- [Requirements](#requirements)\n- [License](#license)\n- [Support](#support)\n\n## Features\n\n### Text-to-Speech (TTS)\n- \ud83c\udf99\ufe0f High-quality text-to-speech generation with multiple voices\n- \ud83d\ude80 HTTP POST and WebSocket support\n- \ud83d\udcca Real-time progress tracking\n- \u26a1 Async support for concurrent requests\n- \ud83c\udfb5 Audio streaming with chunk callbacks\n- \ud83d\udd12 Secure API key authentication\n- \u26a0\ufe0f Built-in error handling for rate limits and credit exhaustion\n\n### Automatic Speech Recognition (ASR)\n- \ud83c\udfa4 Audio file transcription\n- \ud83c\udf10 WebSocket streaming for real-time transcription\n- \ud83d\udd04 Concurrent batch processing\n- \ud83c\udf0d Multi-language support (50+ languages)\n- \ud83d\udd12 Secure API key authentication\n- \u26a0\ufe0f Comprehensive error handling\n\n### Audio Denoising\n- \ud83d\udd07 High-quality audio denoising (DeepFilterNet + CMGAN)\n- \ud83c\udfaf Full audio and streaming chunk processing\n- \u26a1 Real-time WebSocket streaming with progress callbacks\n- \ud83d\udce6 Batch processing support\n- \ud83d\udd12 Secure API key authentication\n- \u26a0\ufe0f Built-in rate limit and credit management\n\n## Installation\n\n### From PyPI (Recommended)\n\n```bash\npip install fonadalabs\n```\n\n### From Source (Development)\n\n```bash\ngit clone https://github.com/fonadalabs/fonadalabs-sdk.git\ncd fonadalabs-sdk\npip install -e .\n```\n\n### With Optional Dependencies\n\n```bash\n# For WebSocket support (TTS + ASR streaming)\npip install fonadalabs[ws]\n\n# For audio denoising features\npip install fonadalabs[denoise]\n\n# Install everything\npip install fonadalabs[all]\n\n# For development\npip install fonadalabs[dev]\n```\n\n## Quick Start\n\n### Text-to-Speech (TTS)\n\n```python\nfrom fonadalabs import TTSClient, TTSError, CreditsExhaustedError, RateLimitError\n\n# Initialize with API key (or set FONADALABS_API_KEY env variable)\nclient = TTSClient(api_key=\"your-api-key-here\")\n\ntry:\n    # Generate audio\n    audio_data = client.generate_audio(\n        text=\"\u0928\u092e\u0938\u094d\u0924\u0947! \u092f\u0939 FonadaLabs TTS SDK \u0915\u093e \u092a\u0930\u0940\u0915\u094d\u0937\u0923 \u0939\u0948\u0964\",\n        voice=\"Pravaha\",\n        output_file=\"output.wav\"\n    )\n    print(f\"\u2713 Generated {len(audio_data)} bytes\")\n    \nexcept CreditsExhaustedError as e:\n    print(f\"\u26a0\ufe0f API credits exhausted. Balance: {e.current_balance}\")\nexcept RateLimitError as e:\n    print(f\"\u26a0\ufe0f Rate limit exceeded. Retry after: {e.retry_after_seconds}s\")\nexcept TTSError as e:\n    print(f\"\u274c TTS Error: {e}\")\n```\n\n### Automatic Speech Recognition (ASR)\n\n```python\nfrom fonadalabs import (\n    ASRClient, \n    ASRSDKError,\n    AuthenticationError,\n    ASRCreditsExhaustedError,\n    ASRRateLimitError,\n    is_supported_language\n)\n\n# Initialize with API key (or set FONADALABS_API_KEY env variable)\nasr_client = ASRClient(api_key=\"your-api-key-here\")\n\ntry:\n    # Check if language is supported\n    if is_supported_language(\"hi\"):\n        print(\"\u2713 Hindi is supported!\")\n    \n    # Transcribe audio file\n    result = asr_client.transcribe_file(\n        audio_path=\"audio.wav\",\n        language_id=\"hi\"  # Hindi\n    )\n    print(f\"\u2713 Transcription: {result.text}\")\n    print(f\"\u2713 Language: {result.language_id}\")\n    print(f\"\u2713 File: {result.file_path}\")\n    \nexcept ASRCreditsExhaustedError as e:\n    print(f\"\u26a0\ufe0f API credits exhausted. Usage: {e.current_usage}\")\nexcept ASRRateLimitError as e:\n    print(f\"\u26a0\ufe0f Rate limit exceeded. Retry after: {e.retry_after_seconds}s\")\nexcept AuthenticationError as e:\n    print(f\"\u274c Authentication failed: {e}\")\nexcept ASRSDKError as e:\n    print(f\"\u274c ASR Error: {e}\")\n```\n\n### Audio Denoising\n\n```python\nfrom fonadalabs import (\n    DenoiseHttpClient, \n    DenoiseStreamingClient,\n    DenoiseCreditsExhaustedError,\n    DenoiseRateLimitError\n)\n\ntry:\n    # Full audio denoising (HTTP)\n    http_client = DenoiseHttpClient(api_key=\"your-api-key-here\")\n    denoised = http_client.denoise_file(\"noisy.wav\", \"clean.wav\")\n    print(\"\u2713 Denoised audio saved to clean.wav\")\n    \n    # Streaming denoising with progress\n    streaming_client = DenoiseStreamingClient(api_key=\"your-api-key-here\")\n    \n    def progress_callback(current, total):\n        percent = (current / total) * 100\n        print(f\"Progress: {current}/{total} chunks ({percent:.1f}%)\")\n    \n    denoised = streaming_client.denoise_file(\n        \"noisy.wav\", \n        \"clean.wav\",\n        progress_callback=progress_callback\n    )\n    print(\"\u2713 Streaming denoising complete!\")\n    \nexcept DenoiseCreditsExhaustedError:\n    print(\"\u26a0\ufe0f API credits exhausted. Please add more credits.\")\nexcept DenoiseRateLimitError:\n    print(\"\u26a0\ufe0f Rate limit exceeded. Please try again later.\")\nexcept Exception as e:\n    print(f\"\u274c Denoise Error: {e}\")\n```\n\n## Authentication\n\nAll FonadaLabs APIs require API key authentication. You can obtain your API key from the [FonadaLabs Dashboard](https://fonadalabs.com/dashboard).\n\n### Method 1: Environment Variable (Recommended)\n\n```bash\n# Set environment variable\nexport FONADALABS_API_KEY=your-api-key-here\n\n# Or add to .env file\necho \"FONADALABS_API_KEY=your-api-key-here\" >> .env\n```\n\nThen use the SDK without passing the key:\n\n```python\nfrom fonadalabs import TTSClient, ASRClient, DenoiseHttpClient\n\n# API key is automatically loaded from environment\ntts_client = TTSClient()\nasr_client = ASRClient()\ndenoise_client = DenoiseHttpClient()\n```\n\n### Method 2: Pass Directly in Code\n\n```python\nfrom fonadalabs import TTSClient, ASRClient, DenoiseHttpClient\n\ntts_client = TTSClient(api_key=\"your-api-key\")\nasr_client = ASRClient(api_key=\"your-api-key\")\ndenoise_client = DenoiseHttpClient(api_key=\"your-api-key\")\n```\n\n**\u26a0\ufe0f Security Note:** Never hardcode API keys in your source code. Always use environment variables or secure key management systems.\n\n## Advanced Features\n\n### Available TTS Voices\n\nFonadaLabs TTS supports multiple high-quality Hindi voices:\n\n| Voice Name | Description | Gender | Best For |\n|-----------|-------------|--------|----------|\n| **Pravaha** | Clear, professional | Female | Business, formal content |\n| **Shruti** | Warm, friendly | Female | Casual conversation, storytelling |\n| **Aabha** | Energetic, bright | Female | Educational, upbeat content |\n| **Svara** | Melodious, soft | Female | Audiobooks, meditation |\n| **Vaanee** | Strong, confident | Female | News, announcements |\n\n**Usage:**\n```python\nfrom fonadalabs import TTSClient\n\nclient = TTSClient(api_key=\"your-api-key\")\n\n# Test different voices\nfor voice in [\"Pravaha\", \"Shruti\", \"Aabha\", \"Svara\", \"Vaanee\"]:\n    audio = client.generate_audio(\n        text=\"\u092f\u0939 \u090f\u0915 \u0906\u0935\u093e\u091c\u093c \u0915\u093e \u092a\u0930\u0940\u0915\u094d\u0937\u0923 \u0939\u0948\u0964\",\n        voice=voice,\n        output_file=f\"test_{voice.lower()}.wav\"\n    )\n    print(f\"\u2713 Generated audio with {voice} voice\")\n```\n\n### Context Manager Support\n\nUse TTSClient with Python's context manager for automatic resource cleanup:\n\n```python\nfrom fonadalabs import TTSClient\n\n# Resources are automatically cleaned up after the block\nwith TTSClient(api_key=\"your-api-key\") as client:\n    audio = client.generate_audio(\n        text=\"Testing context manager\",\n        voice=\"Pravaha\",\n        output_file=\"output.wav\"\n    )\n    print(f\"Generated: {len(audio)} bytes\")\n\n# Client is automatically closed here\nprint(\"Resources cleaned up automatically!\")\n```\n\n### WebSocket Streaming (TTS)\n\nStream audio with real-time progress updates and callbacks:\n\n```python\nfrom fonadalabs import TTSClient\n\nclient = TTSClient(api_key=\"your-api-key\")\n\n# Define callbacks for streaming events\ndef on_chunk(chunk_num, chunk_bytes):\n    print(f\"\ud83d\udce6 Chunk {chunk_num} received: {len(chunk_bytes)} bytes\")\n\ndef on_complete(stats):\n    print(f\"\u2705 Complete! Chunks: {stats.get('chunks_sent')}, Bytes: {stats.get('bytes_sent')}\")\n\ndef on_error(error_msg):\n    print(f\"\u274c Error: {error_msg}\")\n\n# Generate audio via WebSocket with callbacks\naudio = client.generate_audio_ws(\n    text=\"Hello! This is a WebSocket streaming test.\",\n    voice=\"Shruti\",\n    output_file=\"output.wav\",\n    on_chunk=on_chunk,\n    on_complete=on_complete,\n    on_error=on_error\n)\n```\n\n### Async Operations (TTS)\n\nUse async methods for concurrent requests:\n\n```python\nimport asyncio\nfrom fonadalabs import TTSClient\n\nclient = TTSClient(api_key=\"your-api-key\")\n\nasync def generate_multiple():\n    tasks = [\n        client.generate_audio_async(\"Text 1\", \"Pravaha\", \"output1.wav\"),\n        client.generate_audio_async(\"Text 2\", \"Shruti\", \"output2.wav\"),\n        client.generate_audio_async(\"Text 3\", \"Aabha\", \"output3.wav\"),\n    ]\n    results = await asyncio.gather(*tasks)\n    return results\n\naudio_files = asyncio.run(generate_multiple())\n```\n\n### WebSocket Streaming (ASR)\n\nReal-time transcription with WebSocket - **2x faster than HTTP** for batch processing:\n\n```python\nfrom fonadalabs import ASRWebSocketClient, ASRSDKError\n\n# Initialize WebSocket client (API key from env or parameter)\nws_client = ASRWebSocketClient(api_key=\"your-api-key\")\n\ntry:\n    # Transcribe using WebSocket (persistent connection)\n    result = ws_client.transcribe(\n        audio_path=\"audio.wav\",\n        language_id=\"hi\"  # Hindi\n    )\n    \n    # Result is a dict\n    print(f\"\u2713 Transcription: {result.get('text')}\")\n    print(f\"\u2713 Status: {result.get('status')}\")\n    \nexcept ASRSDKError as e:\n    print(f\"\u274c WebSocket transcription failed: {e}\")\n\n# Benefits:\n# - Authenticate once, transcribe multiple files\n# - 2x faster latency (190ms vs 382ms)\n# - 95% less auth overhead\n```\n\n### Multiple Languages (ASR)\n\nASR supports **50+ languages** including all major Indian languages:\n\n```python\nfrom fonadalabs import ASRClient, is_supported_language, SUPPORTED_LANGUAGES\n\nclient = ASRClient(api_key=\"your-api-key\")\n\n# Check if a language is supported\nif is_supported_language(\"hi\"):\n    print(\"\u2713 Hindi is supported!\")\n\n# Test multiple languages\nlanguages = [\"hi\", \"en\", \"ta\", \"te\", \"bn\", \"gu\", \"mr\", \"kn\", \"ml\", \"pa\"]\n\nfor lang in languages:\n    if is_supported_language(lang):\n        result = client.transcribe_file(\"audio.wav\", language_id=lang)\n        print(f\"{lang}: {result.text}\")\n\n# View all supported languages\nprint(f\"Total languages: {len(SUPPORTED_LANGUAGES)}\")\n```\n\n**Popular Indian Languages:**\n- Hindi (`hi`), English (`en`), Tamil (`ta`), Telugu (`te`)\n- Bengali (`bn`), Gujarati (`gu`), Marathi (`mr`), Kannada (`kn`)\n- Malayalam (`ml`), Punjabi (`pa`), Odia (`or`), Assamese (`as`)\n- Urdu (`ur`), Nepali (`ne`), Sanskrit (`sa`), and more!\n\n### Batch Processing (ASR)\n\nProcess multiple audio files concurrently:\n\n```python\nfrom fonadalabs import ASRClient\n\nclient = ASRClient(api_key=\"your-api-key\")\n\n# List of audio files to transcribe\nfile_paths = [\"audio1.wav\", \"audio2.wav\", \"audio3.wav\"]\n\n# Batch transcribe with custom concurrency\nresults = client.batch_transcribe(\n    file_paths=file_paths,\n    language_id=\"en\",\n    concurrency=3\n)\n\n# Process successful transcriptions\nfor result in results.successful:\n    print(f\"\u2713 {result.file_path}: {result.text}\")\n\n# Handle failed transcriptions\nfor failed in results.failed:\n    print(f\"\u2717 {failed.file_path}: {failed.error}\")\n```\n\n## Error Handling\n\nThe SDK provides specific exception types for different error scenarios:\n\n### TTS Exceptions\n\n```python\nfrom fonadalabs import (\n    TTSError,                 # Base exception\n    CreditsExhaustedError,    # Credits exhausted (402/429)\n    RateLimitError            # Rate limit exceeded (429)\n)\n\n# Exception usage example\ntry:\n    audio = client.generate_audio(\"Text\", \"Pravaha\")\nexcept CreditsExhaustedError as e:\n    print(f\"Credits exhausted. Balance: {e.current_balance}, Cost: {e.estimated_cost}\")\nexcept RateLimitError as e:\n    print(f\"Rate limited. Limit: {e.rate_limit}, Retry after: {e.retry_after_seconds}s\")\nexcept TTSError as e:\n    print(f\"TTS Error: {e}\")\n```\n\n### ASR Exceptions\n\n```python\nfrom fonadalabs import (\n    ASRSDKError,                 # Base exception\n    AuthenticationError,         # Invalid API key (401/403)\n    ValidationError,             # Invalid parameters\n    HTTPRequestError,            # HTTP request failed\n    ServerError,                 # Server error (500+)\n    ASRRateLimitError,           # Rate limit exceeded (429)\n    ASRTimeoutError,             # Request timeout\n    ASRCreditsExhaustedError     # Credits exhausted (402/429)\n)\n\n# Exception usage example\ntry:\n    result = asr_client.transcribe_file(\"audio.wav\", language_id=\"hi\")\nexcept ASRCreditsExhaustedError as e:\n    print(f\"Credits exhausted. Usage: {e.current_usage}, Limit: {e.credit_limit}\")\nexcept ASRRateLimitError as e:\n    print(f\"Rate limited. Limit: {e.rate_limit}, Reset at: {e.reset_at}\")\nexcept AuthenticationError as e:\n    print(f\"Auth failed: {e}\")\nexcept ValidationError as e:\n    print(f\"Invalid parameters: {e}\")\nexcept ASRSDKError as e:\n    print(f\"ASR Error: {e}\")\n```\n\n### Denoise Exceptions\n\n```python\nfrom fonadalabs import (\n    DenoiseError,                    # Base exception\n    DenoiseCreditsExhaustedError,    # Credits exhausted\n    DenoiseRateLimitError            # Rate limit exceeded\n)\n```\n\n## Security Features\n\n### \ud83d\udd12 Base URL Lockdown\n\nAll SDK clients use **hardcoded, secure base URLs** that cannot be overridden. This prevents:\n- URL injection attacks\n- Data exfiltration attempts\n- Man-in-the-middle attacks\n\n```python\n# \u2705 SECURE: Base URLs are locked\nclient = TTSClient(api_key=\"your-key\")\n\n# \u274c PREVENTED: Cannot override base URL\n# client = TTSClient(api_key=\"key\", base_url=\"http://malicious.com\")  # Not allowed\n```\n\nBase URLs can only be configured via environment variables by authorized administrators:\n```bash\nexport FONADALABS_API_URL=https://your-secure-endpoint.com\n```\n\n### \ud83d\udd10 API Key Validation\n\nAll API requests are validated:\n- API keys are required for all endpoints\n- Invalid keys return `401 Unauthorized`\n- Keys are transmitted securely via HTTPS\n- Never logged or exposed in error messages\n\n## Documentation\n\n- **TTS Documentation:** See [TEXT_TO_SPEECH_QUICKSTART.md](tts_sdk/TEXT_TO_SPEECH_QUICKSTART.md)\n- **ASR Documentation:** See [ASR_AUTHENTICATION.md](ASR_AUTHENTICATION.md)\n- **Denoise Documentation:** See [denoise_sdk/README.md](denoise_sdk/README.md)\n- **Security Audit:** See [SECURITY_AUDIT_REPORT.md](SECURITY_AUDIT_REPORT.md)\n\n## Examples\n\n### TTS Examples\nLocated in `tts_sdk/examples/`:\n- `basic_usage.py` - Simple HTTP generation\n- `websocket_usage.py` - WebSocket with progress tracking\n- `async_usage.py` - Concurrent requests\n- `streaming_usage.py` - Audio chunk streaming\n- `auth_usage.py` - Authentication examples\n\n### ASR Examples\nLocated in `test/`:\n- `asr_test.py` - Comprehensive test suite with all features\n- Tests include: HTTP POST, WebSocket, multiple languages, error handling\n\n**Run ASR Tests:**\n```bash\n# Set API key\nexport FONADALABS_API_KEY=\"your_api_key_here\"\n\n# Run all tests\ncd test\npython asr_test.py --audio test_audio.wav\n\n# Run specific test\npython asr_test.py --test post         # HTTP POST transcription\npython asr_test.py --test ws           # WebSocket transcription\npython asr_test.py --test languages    # Test multiple languages\npython asr_test.py --test errors       # Error handling\n```\n\n### Denoise Examples\nLocated in `denoise_sdk/`:\n- `sdk_test.py` - Quick start examples for HTTP and WebSocket denoising\n\n## Package Structure\n\n```\nfonadalabs/\n\u251c\u2500\u2500 __init__.py                    # Unified package exports\n\u251c\u2500\u2500 tts/                           # TTS submodule\n\u2502   \u251c\u2500\u2500 __init__.py\n\u2502   \u2514\u2500\u2500 client.py                 # TTSClient\n\u251c\u2500\u2500 asr/                           # ASR submodule\n\u2502   \u251c\u2500\u2500 __init__.py\n\u2502   \u251c\u2500\u2500 client.py                 # ASRClient\n\u2502   \u251c\u2500\u2500 ws_client.py              # ASRWebSocketClient\n\u2502   \u251c\u2500\u2500 config.py                 # Configuration\n\u2502   \u251c\u2500\u2500 exceptions.py             # ASR exceptions\n\u2502   \u251c\u2500\u2500 languages.py              # Language utilities\n\u2502   \u251c\u2500\u2500 utils.py                  # Utility functions\n\u2502   \u2514\u2500\u2500 models/                   # Data models\n\u2502       \u2514\u2500\u2500 types.py\n\u2514\u2500\u2500 denoise/                       # Denoise submodule\n    \u251c\u2500\u2500 __init__.py\n    \u251c\u2500\u2500 http_client.py            # DenoiseHttpClient\n    \u251c\u2500\u2500 streaming_client.py       # DenoiseStreamingClient\n    \u2514\u2500\u2500 exceptions.py             # Denoise exceptions\n```\n\n## Importing\n\n### All Three SDKs\n```python\nfrom fonadalabs import (\n    TTSClient,\n    ASRClient,\n    DenoiseHttpClient,\n    DenoiseStreamingClient\n)\n\ntts = TTSClient(api_key=\"your-key\")\nasr = ASRClient(api_key=\"your-key\")\ndenoise = DenoiseHttpClient(api_key=\"your-key\")\n```\n\n### TTS Only\n```python\nfrom fonadalabs import TTSClient, TTSError, CreditsExhaustedError, RateLimitError\n# or explicitly from submodule\nfrom fonadalabs.tts import TTSClient, TTSError\n```\n\n### ASR Only\n```python\nfrom fonadalabs import ASRClient, ASRWebSocketClient\n# or explicitly from submodule\nfrom fonadalabs.asr import ASRClient, ASRWebSocketClient\n```\n\n### Denoise Only\n```python\nfrom fonadalabs import DenoiseHttpClient, DenoiseStreamingClient\n# or explicitly from submodule\nfrom fonadalabs.denoise import DenoiseHttpClient, DenoiseStreamingClient\n```\n\n## Requirements\n\n### Core Dependencies\n- **Python** >= 3.9\n- **httpx** >= 0.24, < 1.0 (HTTP client)\n- **websockets** >= 11, < 13 (WebSocket support)\n- **loguru** >= 0.7, < 1.0 (Logging)\n- **requests** >= 2.28, < 3.0 (HTTP requests)\n- **numpy** >= 1.21, < 2.0 (Audio processing)\n\n### Optional Dependencies\n\n**For WebSocket features (`pip install fonadalabs[ws]`):**\n- soundfile >= 0.12, < 0.14\n- websocket-client >= 1.5, < 2.0\n\n**For Audio Denoising (`pip install fonadalabs[denoise]`):**\n- soundfile >= 0.12, < 0.14\n- librosa >= 0.10, < 1.0\n- websocket-client >= 1.5, < 2.0\n\n**For Development (`pip install fonadalabs[dev]`):**\n- pytest >= 7.0, < 8.0\n- black >= 23.0, < 24.0\n- isort >= 5.0, < 6.0\n- python-dotenv >= 1.0, < 2.0\n- nest-asyncio >= 1.5, < 2.0\n\n## Contributing\n\nWe welcome contributions! Please see our contributing guidelines and feel free to submit pull requests.\n\n## License\n\nMIT License - see [LICENSE](LICENSE) file for details.\n\nCopyright (c) 2025 FonadaLabs\n\n## Support\n\n- \ud83d\udce7 **Email:** support@fonadalabs.com\n- \ud83d\udc1b **Issues:** [GitHub Issues](https://github.com/fonadalabs/fonadalabs-sdk/issues)\n- \ud83d\udcd6 **Documentation:** \n  - [TTS Quickstart](tts_sdk/TEXT_TO_SPEECH_QUICKSTART.md)\n  - [ASR Authentication](ASR_AUTHENTICATION.md)\n  - [Denoise SDK](denoise_sdk/README.md)\n- \ud83c\udf10 **Website:** https://fonadalabs.com\n- \ud83d\udcac **Community:** [Discord](https://discord.gg/fonadalabs) (if available)\n\n## Version\n\n**Current version:** 1.0.0 (Unified SDK)\n\n### Version History\n- **v1.0.0** (2025-10-16): Unified package with TTS, ASR, and Denoise\n  - Base URL security lockdown\n  - Required API key authentication for all endpoints\n  - Comprehensive error handling with specific exception types\n  - WebSocket streaming support for all services\n  - Async/await support\n  - Batch processing capabilities\n\n---\n\n**Made with \u2764\ufe0f by FonadaLabs**\n\n\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "Unified Python SDK for FonadaLabs Text-to-Speech, Automatic Speech Recognition, and Audio Denoising APIs",
    "version": "2.0.2",
    "project_urls": {
        "Bug Tracker": "https://github.com/fonadalabs/fonadalabs-sdk/issues",
        "Documentation": "https://github.com/fonadalabs/fonadalabs-sdk#readme",
        "Homepage": "https://github.com/fonadalabs/fonadalabs-sdk",
        "Repository": "https://github.com/fonadalabs/fonadalabs-sdk"
    },
    "split_keywords": [
        "text-to-speech",
        " speech-recognition",
        " audio-denoising",
        " tts",
        " asr",
        " denoise",
        " fonadalabs",
        " speech",
        " audio",
        " ai",
        " machine-learning"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "0fa0e2445b93a1626a3fb96bf2040e8912b21fd99376776845ce40b4e51e393d",
                "md5": "83ace73d6cd0bbb4a6cb915e3d29da8f",
                "sha256": "d4472681a00f50dc9637f8f840db1089cb67c698a02f2f23e98b7a5e345c45c5"
            },
            "downloads": -1,
            "filename": "fonadalabs-2.0.2-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "83ace73d6cd0bbb4a6cb915e3d29da8f",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.9",
            "size": 34017,
            "upload_time": "2025-11-03T09:40:46",
            "upload_time_iso_8601": "2025-11-03T09:40:46.068158Z",
            "url": "https://files.pythonhosted.org/packages/0f/a0/e2445b93a1626a3fb96bf2040e8912b21fd99376776845ce40b4e51e393d/fonadalabs-2.0.2-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "91dbff1a6bc11cf225686c2422557d4cf6adb27dcdeabe7f58d1c69e28b140ff",
                "md5": "42dc1ad90d52d81bfaaaa83a216886b4",
                "sha256": "8335302f694253c47db60d89126532da1b3515b9e4b5522aefa526ebbbb1c95a"
            },
            "downloads": -1,
            "filename": "fonadalabs-2.0.2.tar.gz",
            "has_sig": false,
            "md5_digest": "42dc1ad90d52d81bfaaaa83a216886b4",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.9",
            "size": 33619,
            "upload_time": "2025-11-03T09:40:47",
            "upload_time_iso_8601": "2025-11-03T09:40:47.841533Z",
            "url": "https://files.pythonhosted.org/packages/91/db/ff1a6bc11cf225686c2422557d4cf6adb27dcdeabe7f58d1c69e28b140ff/fonadalabs-2.0.2.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-11-03 09:40:47",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "fonadalabs",
    "github_project": "fonadalabs-sdk",
    "github_not_found": true,
    "lcname": "fonadalabs"
}
        
Elapsed time: 1.76477s