"""Application configuration.""" from functools import lru_cache from typing import Any from pydantic import PostgresDsn, field_validator from pydantic_settings import BaseSettings, SettingsConfigDict class Settings(BaseSettings): """Application settings.""" model_config = SettingsConfigDict( env_file=".env", env_file_encoding="utf-8", case_sensitive=False, extra="ignore", ) # Application APP_NAME: str = "Reference Board Viewer" APP_VERSION: str = "1.0.0" DEBUG: bool = False API_V1_PREFIX: str = "/api/v1" # Database DATABASE_URL: PostgresDsn DATABASE_POOL_SIZE: int = 20 DATABASE_MAX_OVERFLOW: int = 0 # JWT Authentication SECRET_KEY: str ALGORITHM: str = "HS256" ACCESS_TOKEN_EXPIRE_MINUTES: int = 30 # MinIO Storage MINIO_ENDPOINT: str MINIO_ACCESS_KEY: str MINIO_SECRET_KEY: str MINIO_BUCKET: str = "webref" MINIO_SECURE: bool = False # CORS CORS_ORIGINS: list[str] = ["http://localhost:5173", "http://localhost:3000"] @field_validator("CORS_ORIGINS", mode="before") @classmethod def parse_cors_origins(cls, v: Any) -> list[str]: """Parse CORS origins from string or list.""" if isinstance(v, str): return [origin.strip() for origin in v.split(",")] return v # File Upload MAX_FILE_SIZE: int = 52428800 # 50MB MAX_BATCH_SIZE: int = 524288000 # 500MB ALLOWED_MIME_TYPES: list[str] = [ "image/jpeg", "image/png", "image/gif", "image/webp", "image/svg+xml", ] @field_validator("ALLOWED_MIME_TYPES", mode="before") @classmethod def parse_mime_types(cls, v: Any) -> list[str]: """Parse MIME types from string or list.""" if isinstance(v, str): return [mime.strip() for mime in v.split(",")] return v # Performance REQUEST_TIMEOUT: int = 30 MAX_CONCURRENT_UPLOADS: int = 10 # Security BCRYPT_ROUNDS: int = 12 PASSWORD_MIN_LENGTH: int = 8 # Logging LOG_LEVEL: str = "INFO" @lru_cache def get_settings() -> Settings: """Get cached application settings.""" return Settings() # Export settings instance settings = get_settings()