""" Configuration management for voice-server. Loads configuration from environment variables with sensible defaults. Uses pydantic-settings for type-safe configuration loading and validation. """ from functools import lru_cache from typing import Annotated, Literal from pydantic import Field, field_validator from pydantic_settings import BaseSettings, SettingsConfigDict # Valid log levels LogLevel = Literal["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"] class Settings(BaseSettings): """ Application settings loaded from environment variables. All settings have sensible defaults and can be overridden via environment variables or a .env file. """ model_config = SettingsConfigDict( env_file=".env", env_file_encoding="utf-8", case_sensitive=False, extra="ignore", ) # Server settings host: Annotated[str, Field(default="0.0.0.0", description="Host to bind to")] port: Annotated[ int, Field(default=8888, ge=1, le=65535, description="Port to listen on"), ] # TTS settings model_dir: Annotated[ str, Field(default="./models", description="Directory containing voice models"), ] default_voice: Annotated[ str, Field(default="en_US-ryan-high", description="Default voice model"), ] default_rate: Annotated[ int, Field(default=170, ge=50, le=400, description="Default speech rate (WPM)"), ] # Queue settings queue_max_size: Annotated[ int, Field(default=50, gt=0, description="Maximum TTS queue size"), ] request_timeout_seconds: Annotated[ int, Field(default=60, gt=0, description="Request processing timeout"), ] # Logging log_level: Annotated[ LogLevel, Field(default="INFO", description="Logging level"), ] log_file: Annotated[ str | None, Field(default=None, description="Log file path (None for stdout only)"), ] # Debug voice_enabled: Annotated[ bool, Field(default=True, description="Enable/disable TTS playback"), ] @field_validator("log_level", mode="before") @classmethod def uppercase_log_level(cls, v: str) -> str: """Ensure log level is uppercase.""" if isinstance(v, str): return v.upper() return v @lru_cache def get_settings() -> Settings: """ Get cached application settings. Returns the same Settings instance on subsequent calls for efficiency. The cache can be cleared by calling get_settings.cache_clear(). """ return Settings()