Spaces:
Sleeping
Sleeping
| """Load immutable runtime settings from environment variables. | |
| Settings are created once by the application factory and passed to services. | |
| """ | |
| from functools import lru_cache | |
| from pydantic import Field | |
| from pydantic_settings import BaseSettings, SettingsConfigDict | |
| APP_VERSION = "2.0.0" | |
| class Settings(BaseSettings): | |
| """Environment-backed application configuration.""" | |
| model_config = SettingsConfigDict( | |
| env_prefix="", | |
| case_sensitive=False, | |
| extra="ignore", | |
| ) | |
| app_password: str | None = None | |
| app_secret_key: str = Field(min_length=1) | |
| data_root: str = "/data/loop_logger" | |
| env: str = "prod" | |
| app_name: str = "Habit Journal" | |
| openrouter_api_key: str | None = None | |
| openrouter_model: str = "openrouter/free" | |
| openrouter_base_url: str = "https://openrouter.ai/api/v1" | |
| coach_timeout_sec: float = 25 | |
| coach_temperature: float = 0.3 | |
| coach_max_tokens: int = 400 | |
| coach_history_k: int = 10 | |
| coach_trace_limit: int = 200 | |
| min_stats_n: int = 5 | |
| stats_shrink_k: float = 3 | |
| match_alpha: float = 0.5 | |
| session_max_age_sec: int = 604800 | |
| debug_include_full_brief: bool = False | |
| login_rate_limit: int = 10 | |
| login_rate_window_sec: int = 900 | |
| max_body_bytes: int = 65536 | |
| agent_token: str | None = None | |
| reschedule_min_gap_min: int = 90 | |
| schedule_day_start: str = "06:00" | |
| schedule_day_end: str = "23:00" | |
| schedule_timezone: str = "Africa/Dar_es_Salaam" | |
| schedule_max_blocks: int = 20 | |
| def is_prod(self) -> bool: | |
| """Return whether production-only security behavior is enabled.""" | |
| return self.env.lower() == "prod" | |
| def get_settings() -> Settings: | |
| """Read and cache environment settings.""" | |
| return Settings() | |