from functools import lru_cache from urllib.parse import quote_plus from pydantic import Field from pydantic_settings import BaseSettings, SettingsConfigDict class Settings(BaseSettings): model_config = SettingsConfigDict( env_file=".env", env_file_encoding="utf-8", extra="ignore", ) app_name: str = Field(default="mini-program-api", validation_alias="APP_NAME") app_version: str = Field(default="0.1.0", validation_alias="APP_VERSION") app_description: str = Field( default="Backend service for mini program", validation_alias="APP_DESCRIPTION", ) host: str = Field(default="0.0.0.0", validation_alias="HOST") port: int = Field(default=8001, validation_alias="PORT") db_host: str = Field(default="127.0.0.1", validation_alias="DB_HOST") db_port: int = Field(default=3306, validation_alias="DB_PORT") db_user: str = Field(default="root", validation_alias="DB_USER") db_password: str = Field(default="", validation_alias="DB_PASSWORD") db_name: str = Field(default="mini_program", validation_alias="DB_NAME") jwt_secret: str = Field( default="dev_only_change_jwt_secret", validation_alias="JWT_SECRET", ) jwt_algorithm: str = Field(default="HS256", validation_alias="JWT_ALGORITHM") jwt_access_token_expire_minutes: int = Field( default=60, validation_alias="JWT_ACCESS_TOKEN_EXPIRE_MINUTES", ) log_level: str = Field(default="INFO", validation_alias="LOG_LEVEL") log_json: bool = Field(default=False, validation_alias="LOG_JSON") slow_sql_ms: int = Field(default=200, validation_alias="SLOW_SQL_MS") @property def mysql_dsn(self) -> str: user = quote_plus(self.db_user) password = quote_plus(self.db_password) auth = f"{user}:{password}" if password else user return ( f"mysql+pymysql://{auth}@{self.db_host}:{self.db_port}/" f"{self.db_name}?charset=utf8mb4" ) @lru_cache(maxsize=1) def get_settings() -> Settings: return Settings() settings = get_settings()