Metadata-Version: 2.4
Name: leanvox
Version: 0.5.0
Summary: Official Python SDK for the Leanvox TTS API
Project-URL: Homepage, https://leanvox.com
Project-URL: Documentation, https://leanvox.com/docs
Project-URL: Repository, https://github.com/leanvox/leanvox-python
Project-URL: Issues, https://github.com/leanvox/leanvox-python/issues
Author-email: Leanvox <junowest@proton.me>
License-Expression: MIT
License-File: LICENSE
Keywords: audio,leanvox,text-to-speech,tts,voice
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Typing :: Typed
Requires-Python: >=3.9
Requires-Dist: httpx>=0.24.0
Requires-Dist: tomli>=1.0.0; python_version < '3.11'
Provides-Extra: dev
Requires-Dist: mypy>=1.0; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.21; extra == 'dev'
Requires-Dist: pytest>=7.0; extra == 'dev'
Requires-Dist: respx>=0.20; extra == 'dev'
Description-Content-Type: text/markdown

# Leanvox Python SDK

Official Python SDK for the [Leanvox](https://leanvox.com) TTS API.

## Install

```bash
pip install leanvox
```

## Quick Start

```python
from leanvox import Leanvox

client = Leanvox(api_key="lv_live_...")
# or set LEANVOX_API_KEY env var

# Generate speech
result = client.generate(text="Hello from Leanvox!", model="standard")
print(result.audio_url)

# Download audio
result.save("hello.mp3")
```

## Streaming

```python
with client.stream(text="Long narration...", voice="af_heart") as stream:
    with open("output.mp3", "wb") as f:
        for chunk in stream:
            f.write(chunk)
```

## Max (Instruction-Based Voice)

```python
# Describe any voice in natural language
result = client.generate(
    text="Welcome to our podcast!",
    model="max",
    voice_instructions="A warm, confident female narrator with a slight British accent",
)
print(result.generated_voice_id)  # Reuse this ID for consistent voice
```

## Dialogue

```python
result = client.dialogue(
    model="pro",
    lines=[
        {"text": "Welcome to the show!", "voice": "narrator_warm_male", "language": "en"},
        {"text": "Thanks for having me.", "voice": "assistant_pro_female", "language": "en"},
    ],
    gap_ms=500,
)
```

## Async

```python
from leanvox import AsyncLeanvox

async with AsyncLeanvox() as client:
    result = await client.generate(text="Hello async!")
```

## Voice Management

```python
# List voices
voices = client.voices.list(model="pro")

# Clone a voice ($3 to unlock)
voice = client.voices.clone(name="My Voice", audio=open("ref.wav", "rb"))
client.voices.unlock(voice.voice_id)

# Design a voice ($1)
voice = client.voices.design(name="Narrator", prompt="Deep warm male voice")
```

## Error Handling

```python
from leanvox import LeanvoxError, InsufficientBalanceError, RateLimitError

try:
    result = client.generate(text="Hello")
except InsufficientBalanceError as e:
    print(f"Need credits: balance={e.balance_cents}")
except RateLimitError as e:
    print(f"Rate limited, retry after: {e.retry_after}")
except LeanvoxError as e:
    print(f"API error: {e.code} - {e.message}")
```

## Auth Priority

1. Constructor param: `Leanvox(api_key="...")`
2. Environment variable: `LEANVOX_API_KEY`
3. Config file: `~/.lvox/config.toml`

## Requirements

- Python 3.9+
- httpx
