import os from fastapi import APIRouter from .. import database as db, config router = APIRouter(prefix="/api/settings", tags=["settings"]) # Settings are stored as flat key/value rows (see database.py / config.DEFAULT_SETTINGS). # This router is a thin pass-through over that table - it must not invent its own # schema, or the Settings/Setup pages will silently stop affecting the actual # transcription/summarization pipeline, which reads these same flat keys. # Env var overrides — set these in docker-compose.yml to prefill the setup wizard _ENV_OVERRIDES = { "onboarding_completed": "NAT20_ONBOARDING_COMPLETED", "hf_token": "NAT20_HF_TOKEN", "whisper_model": "NAT20_WHISPER_MODEL", "whisper_compute_type": "NAT20_WHISPER_COMPUTE_TYPE", "ollama_host": "NAT20_OLLAMA_HOST", "ollama_model": "NAT20_OLLAMA_MODEL", "api_base_url": "NAT20_API_BASE_URL", "api_key": "NAT20_API_KEY", "api_model": "NAT20_API_MODEL", "chunk_word_target": "NAT20_CHUNK_WORD_TARGET", "world_context": "NAT20_WORLD_CONTEXT", "world_context_path": "NAT20_WORLD_CONTEXT_PATH", "player_recap_style": "NAT20_PLAYER_RECAP_STYLE", "player_recap_custom_prompt": "NAT20_PLAYER_RECAP_CUSTOM_PROMPT", } _BOOL_KEYS = {"onboarding_completed"} def _coerce(key: str, value: str): if key in _BOOL_KEYS: return str(value).lower() in ("1", "true", "yes") return value def _merge_with_env(raw: dict) -> dict: """Priority: explicit user DB saves (non-default) > env vars > DEFAULT_SETTINGS.""" merged = {**config.DEFAULT_SETTINGS} for key, env_name in _ENV_OVERRIDES.items(): val = os.environ.get(env_name) if val is not None: merged[key] = val for key, val in raw.items(): db_val = val.strip() if db_val and db_val != config.DEFAULT_SETTINGS.get(key, ""): merged[key] = db_val return merged @router.get("") async def get_settings(): raw = db.get_settings() merged = _merge_with_env(raw) return {k: _coerce(k, v) for k, v in merged.items()} @router.post("") async def update_settings(patch: dict): clean = {k: str(v) for k, v in patch.items() if k in config.DEFAULT_SETTINGS} db.update_settings(clean) raw = db.get_settings() merged = _merge_with_env(raw) return {k: _coerce(k, v) for k, v in merged.items()}