"""Configuration module using pydantic_settings for environment-based configuration.""" from secrets import token_urlsafe from typing import List, Union from pydantic import field_validator from pydantic_settings import BaseSettings, SettingsConfigDict class Settings(BaseSettings): """Application settings loaded from environment variables.""" # Security SECRET_KEY: str = "dev_secret_key_fixed_for_persistence_change_in_prod" ALGORITHM: str = "HS256" ACCESS_TOKEN_EXPIRE_MINUTES: int = 30 REFRESH_TOKEN_EXPIRE_MINUTES: int = 43200 # 30 days # Database DATABASE_URL: str = "sqlite:///./data/habitforge.db" # CORS CORS_ORIGINS: Union[List[str], str] = ["http://localhost:8000", "http://localhost:3000"] CORS_ALLOW_CREDENTIALS: bool = True CORS_ALLOW_METHODS: Union[List[str], str] = ["*"] CORS_ALLOW_HEADERS: Union[List[str], str] = ["*"] # Google OAuth GOOGLE_CLIENT_ID: str = "" GOOGLE_CLIENT_SECRET: str = "" GOOGLE_REDIRECT_URI: str = "http://localhost:8000/api/google/callback" # Rate Limiting RATE_LIMIT_ENABLED: bool = True RATE_LIMIT_TIMES: int = 60 RATE_LIMIT_SECONDS: int = 60 # Application APP_NAME: str = "HabitForge API" APP_VERSION: str = "1.0.0" DEBUG: bool = True # Health Data Provider Selection # Options: "health_connect" HEALTH_PROVIDER: str = "health_connect" @field_validator("CORS_ORIGINS", "CORS_ALLOW_METHODS", "CORS_ALLOW_HEADERS", mode="before") @classmethod def assemble_cors_list(cls, v: Union[str, List[str]]) -> List[str]: """Convert a comma-separated string into a list of strings if necessary.""" if isinstance(v, str) and not v.startswith("["): return [i.strip() for i in v.split(",") if i.strip()] return v model_config = SettingsConfigDict( env_file=".env", env_file_encoding="utf-8", case_sensitive=True, extra="ignore" ) # Global settings instance settings = Settings()