Metadata-Version: 2.4
Name: cheap-tts
Version: 0.2.0
Summary: Cheap TTS Python SDK with local ONNX voice inference
Author: Cheap TTS
License-Expression: MIT
Project-URL: Homepage, https://www.cheap-tts.com/api-docs/
Project-URL: Documentation, https://www.cheap-tts.com/api-docs/
Project-URL: Repository, https://github.com/supperking03/cheap-tts
Project-URL: Issues, https://github.com/supperking03/cheap-tts/issues
Keywords: text-to-speech,tts,onnx,voice,vietnamese
Classifier: Development Status :: 3 - Alpha
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Multimedia :: Sound/Audio :: Speech
Requires-Python: <3.14,>=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: numpy>=1.24
Requires-Dist: onnxruntime>=1.17
Dynamic: license-file

# Cheap TTS Python SDK

Generate multilingual speech with server-side text preparation and local ONNX inference. An active Cheap TTS subscription and a server secret key are required.

Requires Python 3.10–3.13. Create a project and server key in the [Cheap TTS dashboard](https://www.cheap-tts.com/dashboard/).

```bash
pip install cheap-tts
```

```python
from cheap_tts import CheapTTS

with CheapTTS(secret_key="sk_live_your_project") as tts:
    result = tts.synthesize(
        text="Xin chào từ Cheap TTS.",
        voice="vi-entertainment",
    )
    result.save("audio.wav")
```

Async usage:

```python
from cheap_tts import AsyncCheapTTS

async with AsyncCheapTTS(secret_key="sk_live_your_project") as tts:
    result = await tts.synthesize("Hello from Cheap TTS.", "en-narration")
    result.save("audio.wav")
```

## API

- `voices()` returns the available voices.
- `load_voice()` downloads, validates, caches, and loads one voice.
- `synthesize()` prepares text through API v1 and performs ONNX inference locally.
- `clear_cache()` removes locally cached voice assets.
- `close()` releases the active model.

`load_voice()` and `synthesize()` accept `on_progress` and a cancellation object with an `is_set()` method, such as `threading.Event`.

```python
from threading import Event

cancel = Event()
result = tts.synthesize(
    "A long document",
    "en-narration",
    rate=1.25,
    on_progress=lambda event: print(event.stage, event.progress),
    cancel_event=cancel,
)
```

Voice models are cached in `~/.cache/cheap-tts/models`. Set `cache_dir` or `CHEAP_TTS_CACHE_DIR` to change the location.

The SDK sends operational health telemetry containing success/failure stage, latency, character count, voice ID, and audio duration. It never sends TTS text or credentials through telemetry. Pass `telemetry=False` to disable it.

API errors are raised as `CheapTTSAPIError` with stable `status`, `code`, and `request_id` fields.

- [Full SDK documentation](https://www.cheap-tts.com/api-docs/#python)
- [Package on PyPI](https://pypi.org/project/cheap-tts/)
- [Developer dashboard](https://www.cheap-tts.com/dashboard/)

## Reading pauses

Pauses are left to the voice model by default. Pass `pauses` to insert real silence after a punctuation mark instead, in seconds (`0`-`2`):

```python
result = tts.synthesize(
    "Xin chào từ Cheap TTS.",
    "vi-entertainment",
    pauses={"sentence": 0.4, "paragraph": 0.8},
)
```

Keys: `sentence`, `comma`, `ellipsis`, `paragraph` (a blank line). Every key is optional and defaults to `0`, meaning the model's own pause — so omitting `pauses` keeps the audio you get today. Raising a value costs generation speed, because the audio has to be cut at that boundary for silence to follow it.
