from functools import lru_cache import os from pathlib import Path from pydantic import Field from pydantic import BaseModel class Settings(BaseModel): app_name: str = "ElevenClip.AI" demo_mode: bool = True storage_dir: Path = Path("data") frontend_origin: str = "http://localhost:5173" whisper_model_id: str = "openai/whisper-large-v3" qwen_text_model_id: str = "Qwen/Qwen2.5-7B-Instruct" qwen_vl_model_id: str = "Qwen/Qwen2-VL-7B-Instruct" hf_token: str | None = None preferred_torch_dtype: str = "bfloat16" target_clip_count: int = Field(default=5, ge=1, le=20) max_clips: int = Field(default=10, ge=1, le=50) ffmpeg_binary: str = "ffmpeg" ffprobe_binary: str = "ffprobe" ffmpeg_video_codec: str = "h264_amf" ffmpeg_cpu_codec: str = "libx264" redis_url: str = "redis://redis:6379/0" celery_enabled: bool = False @lru_cache def get_settings() -> Settings: settings = Settings( demo_mode=_bool_env("DEMO_MODE", True), storage_dir=Path(os.getenv("STORAGE_DIR", "data")), frontend_origin=os.getenv("FRONTEND_ORIGIN", "http://localhost:5173"), whisper_model_id=os.getenv("WHISPER_MODEL_ID", "openai/whisper-large-v3"), qwen_text_model_id=os.getenv("QWEN_TEXT_MODEL_ID", "Qwen/Qwen2.5-7B-Instruct"), qwen_vl_model_id=os.getenv("QWEN_VL_MODEL_ID", "Qwen/Qwen2-VL-7B-Instruct"), hf_token=os.getenv("HF_TOKEN") or None, preferred_torch_dtype=os.getenv("TORCH_DTYPE", "bfloat16"), target_clip_count=_int_env("TARGET_CLIP_COUNT", 5), max_clips=_int_env("MAX_CLIPS", 10), ffmpeg_binary=os.getenv("FFMPEG_BINARY", "ffmpeg"), ffprobe_binary=os.getenv("FFPROBE_BINARY", "ffprobe"), ffmpeg_video_codec=os.getenv("FFMPEG_VIDEO_CODEC", "h264_amf"), ffmpeg_cpu_codec=os.getenv("FFMPEG_CPU_CODEC", "libx264"), redis_url=os.getenv("REDIS_URL", "redis://redis:6379/0"), celery_enabled=_bool_env("CELERY_ENABLED", False), ) settings.storage_dir.mkdir(parents=True, exist_ok=True) return settings def _bool_env(name: str, default: bool) -> bool: value = os.getenv(name) if value is None: return default return value.strip().lower() in {"1", "true", "yes", "on"} def _int_env(name: str, default: int) -> int: value = os.getenv(name) if value is None: return default return int(value)