Spaces:
Sleeping
Sleeping
File size: 1,778 Bytes
990895d c6253b2 cc4e53a c6253b2 990895d | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 | """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
@property
def is_prod(self) -> bool:
"""Return whether production-only security behavior is enabled."""
return self.env.lower() == "prod"
@lru_cache
def get_settings() -> Settings:
"""Read and cache environment settings."""
return Settings()
|