from functools import lru_cache from typing import Literal from pydantic import AnyUrl, field_validator from pydantic_settings import BaseSettings, SettingsConfigDict class Settings(BaseSettings): model_config = SettingsConfigDict( env_file=".env", env_file_encoding="utf-8", case_sensitive=False, extra="ignore", ) # App APP_NAME: str = "Arkan API" ENV: Literal["development", "staging", "production"] = "development" DEBUG: bool = False # Security JWT_SECRET: str JWT_ALGORITHM: str = "HS256" JWT_EXPIRE_MINUTES: int = 60 * 24 # 24h # Admin seed ADMIN_USERNAME: str ADMIN_PASSWORD: str # Database DATABASE_URL: str # sync (for Alembic) ASYNC_DATABASE_URL: str = "" @field_validator("ASYNC_DATABASE_URL", mode="before") @classmethod def build_async_url(cls, v: str, info) -> str: if v: return v sync = info.data.get("DATABASE_URL", "") return sync.replace("postgresql://", "postgresql+asyncpg://", 1) # Redis REDIS_URL: str = "redis://localhost:6379/0" # CORS ALLOWED_ORIGINS: str = "http://localhost:3000" @property def allowed_origins_list(self) -> list[str]: return [o.strip() for o in self.ALLOWED_ORIGINS.split(",")] # Rate limiting RATE_LIMIT_DEFAULT: str = "100/minute" RATE_LIMIT_AUTH: str = "10/minute" # تقييد أشد على تسجيل الدخول # DB pool DB_POOL_SIZE: int = 10 DB_MAX_OVERFLOW: int = 20 @lru_cache def get_settings() -> Settings: return Settings() settings = get_settings()