from pydantic_settings import BaseSettings, SettingsConfigDict from typing import Optional import os class Settings(BaseSettings): APP_NAME: str = "xiaoxia-saas" APP_VERSION: str = "0.1.0" ENVIRONMENT: str = "development" DEBUG: bool = True API_HOST: str = "0.0.0.0" API_PORT: int = 8000 API_PREFIX: str = "/api/v1" DATABASE_URL: str = "postgresql+psycopg://postgres:postgres@localhost:5432/xiaoxia_saas" DATABASE_POOL_SIZE: int = 20 DATABASE_MAX_OVERFLOW: int = 40 DATABASE_POOL_TIMEOUT: int = 30 DATABASE_POOL_RECYCLE: int = 3600 USE_IN_MEMORY_DB: bool = False REDIS_URL: str = "redis://localhost:6379/0" REDIS_MAX_CONNECTIONS: int = 50 CELERY_BROKER_URL: str = "redis://localhost:6379/0" CELERY_RESULT_BACKEND: str = "redis://localhost:6379/1" MINIO_ENDPOINT: str = "localhost:9000" MINIO_ACCESS_KEY: str = "admin" MINIO_SECRET_KEY: str = "xiaoxia2026" MINIO_BUCKET: str = "xiaoxia-assets" MINIO_SECURE: bool = False MINIO_PUBLIC_URL: str = "http://localhost:9000" LOG_LEVEL: str = "INFO" CORS_ORIGINS_RAW: str = "http://localhost:3000,http://localhost:5173,http://localhost:8000" model_config = SettingsConfigDict( env_file=".env", env_file_encoding="utf-8", case_sensitive=False, extra="ignore", ) @property def CORS_ORIGINS(self) -> list[str]: return [origin.strip() for origin in self.CORS_ORIGINS_RAW.split(",") if origin.strip()] @property def database_url(self) -> str: return self.DATABASE_URL @property def redis_url(self) -> str: return self.REDIS_URL @property def celery_broker_url(self) -> str: return self.CELERY_BROKER_URL @property def celery_result_backend(self) -> str: return self.CELERY_RESULT_BACKEND @property def minio_endpoint(self) -> str: return self.MINIO_ENDPOINT @property def minio_access_key(self) -> str: return self.MINIO_ACCESS_KEY @property def minio_secret_key(self) -> str: return self.MINIO_SECRET_KEY @property def minio_bucket(self) -> str: return self.MINIO_BUCKET @property def minio_secure(self) -> bool: return self.MINIO_SECURE @property def minio_public_url(self) -> str: return self.MINIO_PUBLIC_URL _settings: Optional[Settings] = None def get_settings() -> Settings: global _settings if _settings is None: env = os.getenv("APP_ENV", "development") env_file = f".env.{env}" if env != "development" else ".env" if os.path.exists(env_file): _settings = Settings(_env_file=env_file) else: _settings = Settings() return _settings settings = get_settings()