PAR CLI TTS - Command line text-to-speech tool using ElevenLabs with voice caching and name resolution
Project description
PAR CLI TTS
A powerful command-line text-to-speech tool supporting multiple TTS providers (ElevenLabs, OpenAI, and Kokoro ONNX) with intelligent voice caching, name resolution, and flexible output options.
๐ What's New in v0.1.0
โจ Initial Release: Multi-provider TTS with ElevenLabs, OpenAI, and Kokoro ONNX support
- ๐ญ Multiple Providers - Seamless switching between ElevenLabs, OpenAI, and Kokoro ONNX
- ๐ฏ Voice Name Resolution - Use friendly names instead of IDs
- โก Smart Caching - 7-day voice cache for ElevenLabs
- ๐จ Rich Terminal Output - Beautiful colored output with progress
- ๐ Flexible Audio Output - Play directly or save to file
- ๐ Offline Support - Kokoro ONNX runs locally without API requirements
Features
- ๐ญ Multiple TTS Providers - Support for ElevenLabs, OpenAI, and Kokoro ONNX with easy provider switching
- ๐ฏ Voice Name Support - Use voice names like "Rachel" or "nova" instead of cryptic IDs
- โก Smart Voice Caching - ElevenLabs voice data cached for 7 days for faster lookups
- ๐ Partial Name Matching - Type "char" to match "Charlotte" (ElevenLabs)
- ๐พ XDG-Compliant Cache - Proper cache directory management across platforms
- ๐จ Rich Terminal Output - Beautiful colored output with progress indicators
- ๐ Flexible Audio Output - Play directly or save to file with custom locations
- ๐๏ธ Provider-Specific Options - Stability/similarity for ElevenLabs, speed/format for OpenAI
- ๐ ๏ธ Debug Mode - Comprehensive debugging with --debug and --dump options
- ๐ Smart File Management - Automatic cleanup or preservation of audio files
Technology Stack
- Python 3.11+ - Modern Python with type hints and async support
- ElevenLabs SDK - Official ElevenLabs API client for high-quality voices
- OpenAI SDK - Official OpenAI API client for TTS
- Kokoro ONNX - Offline TTS with ONNX Runtime for fast inference
- Typer - Modern CLI framework with automatic help generation
- Rich - Terminal formatting and beautiful output
- Pydantic - Data validation and settings management
- Platformdirs - Cross-platform directory management
- Python-dotenv - Environment variable management
Prerequisites
To install PAR CLI TTS, make sure you have Python 3.11+ installed.
uv is recommended
Linux and Mac
curl -LsSf https://astral.sh/uv/install.sh | sh
Windows
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
Installation
Installation from PyPI (Recommended)
Install the latest stable version using uv:
uv tool install par-cli-tts
Or using pip:
pip install par-cli-tts
After installation, you can run the tool directly:
# Simple text-to-speech
par-tts "Hello, world!"
# Show help
par-tts --help
Installation From Source
For development or to get the latest features:
-
Clone the repository:
git clone https://github.com/paulrobello/par-cli-tts.git cd par-cli-tts
-
Install the package dependencies using uv:
uv sync -
Run using uv:
uv run par-tts "Hello, world!"
Kokoro ONNX Setup
Kokoro ONNX models are automatically downloaded on first use! The models are stored in an XDG-compliant data directory:
- macOS:
~/Library/Application Support/par-tts/par-tts-kokoro/ - Linux:
~/.local/share/par-tts-kokoro/ - Windows:
%LOCALAPPDATA%\par-tts\par-tts-kokoro\
Automatic Download
When you first use the Kokoro ONNX provider, it will automatically download the required models (~106 MB total using quantized model):
# Models download automatically on first use
par-tts "Hello" --provider kokoro-onnx
Manual Model Management
You can also manage models manually using the par-tts-kokoro command:
# Download models manually
par-tts-kokoro download
# Show model information
par-tts-kokoro info
# Show model storage paths
par-tts-kokoro path
# Clear downloaded models
par-tts-kokoro clear
# Force re-download models
par-tts-kokoro download --force
Using Custom Model Paths
If you prefer to use models from a custom location, set environment variables:
export KOKORO_MODEL_PATH=/path/to/kokoro-v1.0.onnx
export KOKORO_VOICE_PATH=/path/to/voices-v1.0.bin
When these environment variables are set, automatic download is disabled.
Configuration
Create a .env file in your project directory with your API keys:
# Required API keys (at least one for cloud providers)
ELEVENLABS_API_KEY=your_elevenlabs_key_here
OPENAI_API_KEY=your_openai_key_here
# Optional: Kokoro ONNX model paths (auto-downloads if not set)
# Set these only if you want to use custom model locations
# KOKORO_MODEL_PATH=/path/to/kokoro-v1.0.onnx
# KOKORO_VOICE_PATH=/path/to/voices-v1.0.bin
# Optional: Default provider (elevenlabs, openai, or kokoro-onnx)
TTS_PROVIDER=elevenlabs
# Optional: Default voices
ELEVENLABS_VOICE_ID=Rachel # or use voice ID
OPENAI_VOICE_ID=nova # alloy, echo, fable, onyx, nova, shimmer
KOKORO_VOICE_ID=af_sarah # See available voices with --list
# Optional: General voice (overrides provider-specific)
TTS_VOICE_ID=Rachel
Usage
Quick Start
If installed from PyPI:
# Simple text-to-speech with default provider
par-tts "Hello, world!"
# Use OpenAI provider
par-tts "Hello" --provider openai --voice nova
# Use ElevenLabs with voice by name
par-tts "Hello" --voice Rachel
# Use Kokoro ONNX (offline, auto-downloads models on first use)
par-tts "Hello" --provider kokoro-onnx --voice af_sarah
# Save to file
par-tts "Save this" --output audio.mp3
If running from source:
# Simple text-to-speech with default provider
uv run par-tts "Hello, world!"
# Use OpenAI provider
uv run par-tts "Hello" --provider openai --voice nova
# Use ElevenLabs with voice by name
uv run par-tts "Hello" --voice Rachel
# Use Kokoro ONNX (offline, auto-downloads models on first use)
uv run par-tts "Hello" --provider kokoro-onnx --voice af_sarah
# Save to file
uv run par-tts "Save this" --output audio.mp3
Basic Examples
# Simple text-to-speech with default provider (ElevenLabs)
par-tts "Hello, world!"
# Use OpenAI provider
par-tts "Hello from OpenAI" --provider openai --voice nova
# Use ElevenLabs with voice by name
par-tts "Hello from ElevenLabs" --provider elevenlabs --voice Rachel
# Use Kokoro ONNX with language specification
par-tts "Hello from Kokoro" --provider kokoro-onnx --voice af_sarah --lang en-us
# Use partial name matching (ElevenLabs)
par-tts "Hello" --voice char # matches Charlotte
# Save to file without playing
par-tts "Save this audio" --output audio.mp3 --no-play
# Adjust ElevenLabs voice settings
par-tts "Stable voice" --stability 0.8 --similarity 0.7
# Adjust OpenAI speech speed
par-tts "Fast speech" --provider openai --speed 1.5
# Keep temp files after playback
par-tts "Keep this" --keep-temp
# Specify custom temp directory (files are kept)
par-tts "Custom location" --temp-dir ./my_audio
# Combine output filename with temp directory
par-tts "Save here" --output my_file.mp3 --temp-dir ./audio_files
Advanced Usage
Provider Management
# List available providers
par-tts "dummy" --list-providers
# List voices for a specific provider
par-tts "dummy" --provider openai --list
par-tts "dummy" --provider elevenlabs --list
par-tts "dummy" --provider kokoro-onnx --list
# Show debug information
par-tts "Test" --debug
# Show configuration
par-tts "Test" --dump
Output File Behavior
- With
--output full/path.mp3: Saves to exact path specified - With
--output filename.mp3 --temp-dir dir: Saves todir/filename.mp3 - With
--temp-dir dironly: Saves todir/tts_TIMESTAMP.mp3(kept) - With
--keep-temp: Temporary files are not deleted after playback - Default behavior: Temp files are auto-deleted after playback
Command Line Options
Core Options
| Option | Short | Description | Default |
|---|---|---|---|
text |
Text to convert to speech (required) | ||
--provider |
-P |
TTS provider to use (elevenlabs, openai, kokoro-onnx) | elevenlabs |
--voice |
-v |
Voice name or ID to use | Provider default |
--output |
-o |
Output file path | None (temp file) |
--model |
-m |
Model to use (provider-specific) | Provider default |
--play/--no-play |
-p |
Play audio after generation | --play |
ElevenLabs Options
| Option | Short | Description | Default |
|---|---|---|---|
--stability |
-s |
Voice stability (0.0 to 1.0) | 0.5 |
--similarity |
-S |
Voice similarity boost (0.0 to 1.0) | 0.5 |
OpenAI Options
| Option | Short | Description | Default |
|---|---|---|---|
--speed |
Speech speed (0.25 to 4.0) | 1.0 | |
--format |
-f |
Audio format (mp3, opus, aac, flac, wav) | mp3 |
Kokoro ONNX Options
| Option | Short | Description | Default |
|---|---|---|---|
--lang |
Language code (e.g., en-us) | en-us | |
--speed |
Speech speed multiplier | 1.0 |
File Management
| Option | Short | Description | Default |
|---|---|---|---|
--keep-temp |
-k |
Keep temporary audio files after playback | False |
--temp-dir |
-t |
Directory for temporary audio files | System temp |
Utility Options
| Option | Short | Description | Default |
|---|---|---|---|
--debug |
-d |
Show debug information | False |
--dump |
-D |
Dump configuration and exit | False |
--list |
-l |
List available voices for provider | False |
--list-providers |
-L |
List available TTS providers | False |
Providers
ElevenLabs
- Models: eleven_monolingual_v1, eleven_multilingual_v1, eleven_multilingual_v2
- Voices: 25+ voices with different accents and styles
- Features: Voice cloning, stability control, similarity boost
- Caching: Automatic 7-day cache for voice listings
- API Key: Set
ELEVENLABS_API_KEYin your .env file
OpenAI
- Models: tts-1 (optimized for speed), tts-1-hd (optimized for quality)
- Voices:
- alloy - Neutral and balanced
- echo - Smooth and articulate
- fable - Expressive and animated
- onyx - Deep and authoritative
- nova - Warm and friendly (default)
- shimmer - Soft and gentle
- Features: Speed control (0.25x to 4x), multiple output formats
- Output Formats: mp3, opus, aac, flac, wav, pcm
- API Key: Set
OPENAI_API_KEYin your .env file
Kokoro ONNX
- Models: kokoro-v1.0 (ONNX format, runs locally)
- Voices: Multiple voices including af_sarah (default) and others
- Features:
- Offline operation - no API key required
- Fast CPU/GPU inference with ONNX Runtime
- Language support with phoneme-based synthesis
- Speed control
- Output Formats: wav, flac, ogg
- Requirements:
- Models auto-download on first use (~106 MB)
- Uses int8 quantized model for efficiency
- Stored in XDG-compliant data directory
- No API key needed - runs entirely locally
- Manual download available via
par-tts-kokoro download
Cache Locations
The ElevenLabs voice cache is stored in platform-specific directories:
- macOS:
~/Library/Caches/par-tts-elevenlabs/voice_cache.yaml - Linux:
~/.cache/par-tts-elevenlabs/voice_cache.yaml - Windows:
%LOCALAPPDATA%\par-tts-elevenlabs\Cache\voice_cache.yaml
Cache entries expire after 7 days and are automatically refreshed when needed.
Development
Setup Development Environment
# Clone repository
git clone https://github.com/paulrobello/par-cli-tts.git
cd par-cli-tts
# Install dependencies
uv sync
# Run tests
uv run pytest
# Run linting and formatting
make checkall
Development Commands
# Format, lint, and type check
make checkall
# Individual commands
make format # Format with ruff
make lint # Lint with ruff
make typecheck # Type check with pyright
# Run the app
make run # Run with test message
make app_help # Show app help
# Voice management
make list-voices # List available voices
make update-cache # Update voice cache
make clear-cache # Clear voice cache
# Kokoro ONNX model management
make kokoro-download # Download Kokoro models
make kokoro-info # Show model information
make kokoro-clear # Clear Kokoro models
make kokoro-path # Show model paths
# Build and package
make package # Build distribution packages
make clean # Clean build artifacts
Project Structure
par-cli-tts/
โโโ src/
โ โโโ __init__.py
โ โโโ tts_cli.py # Main CLI application
โ โโโ voice_cache.py # Voice caching system
โ โโโ providers/ # TTS provider implementations
โ โโโ __init__.py
โ โโโ base.py # Abstract base provider
โ โโโ elevenlabs.py # ElevenLabs implementation
โ โโโ openai.py # OpenAI implementation
โโโ .env.example # Example environment file
โโโ pyproject.toml # Project configuration
โโโ Makefile # Development commands
โโโ README.md # This file
Troubleshooting
Common Issues
-
API Key Not Found
- Ensure your
.envfile contains the correct API keys - Check that the
.envfile is in the current directory - Verify environment variable names match exactly
- Ensure your
-
Voice Not Found
- Use
--listto see available voices for your provider - Check spelling and capitalization of voice names
- For ElevenLabs, wait for cache to update or run
make update-cache
- Use
-
Audio Not Playing
- Ensure you have audio output devices connected
- Check system volume settings
- On Linux, verify audio subsystem (ALSA/PulseAudio) is working
-
Slow Response Times
- ElevenLabs voice cache may be updating (happens every 7 days)
- Network connection may be slow
- Try using
--debugto see detailed timing information
-
File Not Saved
- Check write permissions for the output directory
- Ensure the path exists or parent directories can be created
- Use absolute paths to avoid confusion
Debug Mode
Enable debug mode for detailed information:
# Show debug information during execution
par-tts "Test message" --debug
# Dump configuration without executing
par-tts "Test" --dump
Contributing
Contributions are welcome! Please feel free to submit issues, feature requests, or pull requests.
How to Contribute
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Make your changes
- Run tests and checks (
make checkall) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
Development Guidelines
- Use type hints for all function parameters and returns
- Follow Google-style docstrings
- Ensure all tests pass before submitting PR
- Update documentation for new features
- Keep commits atomic and well-described
License
This project is licensed under the MIT License - see the LICENSE file for details.
Author
Paul Robello
Email: probello@gmail.com
GitHub: @paulrobello
Acknowledgments
- ElevenLabs for their excellent TTS API
- OpenAI for their TTS capabilities
- Typer for the elegant CLI framework
- Rich for beautiful terminal formatting
Support
If you find this tool useful, consider:
- โญ Starring the repository
- ๐ Reporting bugs or requesting features
- ๐ Improving documentation
- โ Buying me a coffee
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file par_cli_tts-0.1.0.tar.gz.
File metadata
- Download URL: par_cli_tts-0.1.0.tar.gz
- Upload date:
- Size: 21.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
72d857df3ec033dd20b68596c1683934b317c23f3d6d47d6bbcc2ffc80b10913
|
|
| MD5 |
c9a57a0d6ec2b64411486553bf3f1831
|
|
| BLAKE2b-256 |
bcb5d2eed78c7347411614a07010e9137d92ece1ee45d6ebd416cf3ed7792964
|
Provenance
The following attestation bundles were made for par_cli_tts-0.1.0.tar.gz:
Publisher:
publish.yml on paulrobello/par-cli-tts
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
par_cli_tts-0.1.0.tar.gz -
Subject digest:
72d857df3ec033dd20b68596c1683934b317c23f3d6d47d6bbcc2ffc80b10913 - Sigstore transparency entry: 409273442
- Sigstore integration time:
-
Permalink:
paulrobello/par-cli-tts@79d62da1f01e59262c714df0a204f26fe6b3b03c -
Branch / Tag:
refs/heads/main - Owner: https://github.com/paulrobello
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@79d62da1f01e59262c714df0a204f26fe6b3b03c -
Trigger Event:
workflow_run
-
Statement type:
File details
Details for the file par_cli_tts-0.1.0-py3-none-any.whl.
File metadata
- Download URL: par_cli_tts-0.1.0-py3-none-any.whl
- Upload date:
- Size: 27.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7eb87486c2ac71f1f12bbc821563975a550ff05bb975f06455716b5a482f4cc1
|
|
| MD5 |
d97b91ec2105fec8f41ea9467808ce43
|
|
| BLAKE2b-256 |
dde96d11616d381d8a91bbb328a3b34576361e61f6d4a9d660a79a777aaeab5d
|
Provenance
The following attestation bundles were made for par_cli_tts-0.1.0-py3-none-any.whl:
Publisher:
publish.yml on paulrobello/par-cli-tts
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
par_cli_tts-0.1.0-py3-none-any.whl -
Subject digest:
7eb87486c2ac71f1f12bbc821563975a550ff05bb975f06455716b5a482f4cc1 - Sigstore transparency entry: 409273443
- Sigstore integration time:
-
Permalink:
paulrobello/par-cli-tts@79d62da1f01e59262c714df0a204f26fe6b3b03c -
Branch / Tag:
refs/heads/main - Owner: https://github.com/paulrobello
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@79d62da1f01e59262c714df0a204f26fe6b3b03c -
Trigger Event:
workflow_run
-
Statement type: