Skip to main content

Text-to-speech library bridging to Orpheus TTS model - bringing text to life

Project description

Eurydice 🎵

Named after Orpheus's wife in Greek mythology. Like Orpheus who tried to bring Eurydice back from the underworld, this library brings text to life through speech.

PyPI version Python Versions License: MIT Tests

A Python library for text-to-speech using the Orpheus TTS model, featuring audio caching and provider abstraction.

Features

  • 🎤 8 High-Quality Voices - tara, leah, jess, leo, dan, mia, zac, zoe
  • Audio Caching - Memory and filesystem caching to avoid regenerating audio
  • 🔌 Provider Abstraction - Support for LM Studio (Ollama and embedded coming soon)
  • 🔄 Async-First - Built for async/await with sync wrappers for convenience
  • 📦 Type Hints - Full type annotations throughout
  • 🧪 Well Tested - Comprehensive test suite

Installation

# Basic installation (requires external LM Studio server)
uv add eurydice-tts

# With audio decoding support (recommended)
uv add eurydice-tts[audio]

# For development
uv add eurydice-tts[dev]

# All extras
uv add eurydice-tts[all]

Quick Start

Prerequisites

  1. Install LM Studio
  2. Download and load the Orpheus TTS model (orpheus-3b-0.1-ft)
  3. Start the LM Studio server (default: http://localhost:1234)

Basic Usage

from eurydice import Eurydice, Voice

# Async usage (recommended)
async with Eurydice() as tts:
    audio = await tts.generate("Hello, world!", voice=Voice.LEO)
    audio.save("hello.wav")
    print(f"Generated {audio.duration:.2f}s of audio")

# Sync usage
tts = Eurydice()
audio = tts.generate_sync("Hello, world!")
audio.save("hello.wav")

With Caching

from eurydice import Eurydice, TTSConfig, FilesystemCache

# Configure with filesystem cache for persistence
config = TTSConfig(cache_enabled=True)
cache = FilesystemCache("~/.eurydice/cache")

async with Eurydice(config, cache=cache) as tts:
    # First call generates audio
    audio1 = await tts.generate("Hello!")
    print(f"Cached: {audio1.cached}")  # False

    # Second call returns cached audio instantly
    audio2 = await tts.generate("Hello!")
    print(f"Cached: {audio2.cached}")  # True

Custom Configuration

from eurydice import Eurydice, TTSConfig, GenerationParams, Voice

config = TTSConfig(
    provider="lmstudio",
    server_url="http://localhost:1234/v1",
    model="orpheus-3b-0.1-ft",
    default_voice=Voice.TARA,
    cache_enabled=True,
    generation=GenerationParams(
        temperature=0.7,
        top_p=0.9,
        repetition_penalty=1.1,
    ),
)

async with Eurydice(config) as tts:
    audio = await tts.generate("Custom configuration example!")
    print(f"Duration: {audio.duration:.2f}s")

Available Voices

Voice ID Description
Tara tara Female voice
Leah leah Female voice
Jess jess Female voice
Leo leo Male voice (default)
Dan dan Male voice
Mia mia Female voice
Zac zac Male voice
Zoe zoe Female voice

API Reference

Eurydice

Main client class for text-to-speech generation.

class Eurydice:
    def __init__(
        self,
        config: Optional[TTSConfig] = None,
        provider: Optional[Provider] = None,
        cache: Optional[Cache] = None,
    ) -> None: ...

    async def generate(
        self,
        text: str,
        voice: Optional[Voice] = None,
        params: Optional[GenerationParams] = None,
        format: AudioFormat = AudioFormat.WAV,
        use_cache: bool = True,
    ) -> AudioResult: ...

    def generate_sync(self, text: str, **kwargs) -> AudioResult: ...

    async def generate_to_file(
        self, text: str, path: str, **kwargs
    ) -> AudioResult: ...

    async def is_available(self) -> bool: ...

    @staticmethod
    def available_voices() -> list[Voice]: ...

AudioResult

Result object containing generated audio.

@dataclass
class AudioResult:
    audio_data: bytes      # Raw audio bytes
    duration: float        # Duration in seconds
    format: AudioFormat    # WAV or RAW
    sample_rate: int       # Sample rate (24000 Hz)
    voice: Voice           # Voice used
    cached: bool           # Whether result came from cache

    def save(self, path: str) -> None: ...
    def to_base64(self) -> str: ...

TTSConfig

Configuration for the TTS client.

@dataclass
class TTSConfig:
    provider: str = "lmstudio"
    server_url: Optional[str] = None
    model: str = "orpheus-3b-0.1-ft"
    default_voice: Voice = Voice.LEO
    generation: GenerationParams = GenerationParams()
    cache_enabled: bool = True
    cache_ttl_seconds: Optional[int] = None
    sample_rate: int = 24000
    timeout: float = 120.0

Caching

Eurydice supports two caching backends:

MemoryCache

In-memory LRU cache (default when caching is enabled):

from eurydice import MemoryCache

cache = MemoryCache(
    max_size=100,              # Maximum items to store
    default_ttl_seconds=3600,  # 1 hour TTL (optional)
)

FilesystemCache

Persistent disk-based cache:

from eurydice import FilesystemCache

cache = FilesystemCache(
    cache_dir="~/.eurydice/cache",
    default_ttl_seconds=86400,  # 24 hour TTL (optional)
)

Cache Keys

Cache keys are content-addressed using SHA256 of:

  • Input text
  • Voice selection
  • Generation parameters (temperature, top_p, etc.)
  • Model identifier

This ensures that different configurations produce different cache entries.

Providers

LM Studio (Default)

Uses the OpenAI-compatible API provided by LM Studio:

from eurydice import LMStudioProvider

provider = LMStudioProvider(
    server_url="http://localhost:1234/v1",
    model="orpheus-3b-0.1-ft",
    timeout=120.0,
)

Coming Soon

  • Ollama Provider - For Ollama-hosted models
  • Embedded Provider - Run models locally without external servers

Examples

See the examples/ directory for more usage examples:

  • basic_usage.py - Simple text-to-speech generation
  • with_caching.py - Using the caching system
  • batch_generation.py - Generating audio for multiple texts
  • sync_usage.py - Synchronous API usage

Development

Setup

git clone https://github.com/mustafazidan/eurydice.git
cd eurydice
uv venv
source .venv/bin/activate
uv sync --all-extras

Running Tests

# Run all tests
uv run pytest tests/ -v

# With coverage
uv run pytest tests/ --cov=eurydice --cov-report=html

# Run specific test
uv run pytest tests/test_types.py -v

Linting

uv run ruff check .
uv run ruff format .

Contributing

Contributions are welcome! Please see CONTRIBUTING.md for guidelines.

License

This project is licensed under the MIT License - see the LICENSE file for details.

Acknowledgments


Made with ❤️ by Mustafa Abuelfadl

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

eurydice_tts-0.0.1.tar.gz (22.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

eurydice_tts-0.0.1-py3-none-any.whl (20.8 kB view details)

Uploaded Python 3

File details

Details for the file eurydice_tts-0.0.1.tar.gz.

File metadata

  • Download URL: eurydice_tts-0.0.1.tar.gz
  • Upload date:
  • Size: 22.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for eurydice_tts-0.0.1.tar.gz
Algorithm Hash digest
SHA256 c94aaed0f9852291cbc3866f1385ff878ef7b33777822eb8ce01e6f3333b014f
MD5 0c2fadaf8433923a93c59cce0cf416f5
BLAKE2b-256 a1c3cf5ecae615408e292cae652cb6c75254da161f71a4bde1a6b17cb379bd30

See more details on using hashes here.

Provenance

The following attestation bundles were made for eurydice_tts-0.0.1.tar.gz:

Publisher: release.yml on mustafa-zidan/eurydice

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file eurydice_tts-0.0.1-py3-none-any.whl.

File metadata

  • Download URL: eurydice_tts-0.0.1-py3-none-any.whl
  • Upload date:
  • Size: 20.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for eurydice_tts-0.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 ccd95f7462956a66236a18e4a7a1653679770a28c9edaf71023dfc0804a38756
MD5 46248bab6485d56a9573aa6c4e897eae
BLAKE2b-256 7597a53aa2e8e0b45b2f9531024d537608b3e79a8b888d2d5f7b683f57f3edbe

See more details on using hashes here.

Provenance

The following attestation bundles were made for eurydice_tts-0.0.1-py3-none-any.whl:

Publisher: release.yml on mustafa-zidan/eurydice

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page