"""Application settings with JSON persistence. Provides runtime-configurable settings that persist across restarts. Defaults come from environment variables; UI changes override them and are saved to data/settings.json. """ import json import logging import os from pathlib import Path from typing import Any logger = logging.getLogger(__name__) SETTINGS_PATH = Path(__file__).resolve().parent.parent / "data" / "settings.json" DEFAULTS: dict[str, Any] = { "detection_backend": os.environ.get("DETECTION_BACKEND", "yolos"), } def load_settings() -> dict[str, Any]: """Load settings from disk, merged with defaults.""" settings = dict(DEFAULTS) if SETTINGS_PATH.exists(): try: with open(SETTINGS_PATH, "r", encoding="utf-8") as f: saved = json.load(f) settings.update(saved) except (json.JSONDecodeError, IOError) as e: logger.warning("Failed to load settings: %s", e) return settings def save_settings(settings: dict[str, Any]) -> None: """Write settings to disk.""" SETTINGS_PATH.parent.mkdir(parents=True, exist_ok=True) with open(SETTINGS_PATH, "w", encoding="utf-8") as f: json.dump(settings, f, indent=2, ensure_ascii=False) def get(key: str) -> Any: """Get a single setting value.""" settings = load_settings() return settings.get(key, DEFAULTS.get(key)) def update(key: str, value: Any) -> None: """Update a single setting and persist.""" settings = load_settings() settings[key] = value save_settings(settings) logger.info("Setting updated: %s = %s", key, value)