# Configuration for the Aether FastAPI application. # All settings are read directly from environment variables (injected by Docker via .env). from pydantic import BaseSettings, Field from typing import Any, Dict, List class Settings(BaseSettings): # --- Application --- APP_NAME: str = "Aether API (FastAPI)" # --- Aether Shared Config (DB-driven bootstrap) --- AE_CFG_ID: int = Field(0, env='AE_CFG_ID') # --- JWT --- JWT_KEY: str = Field('EHmSXZFKfMEW65E8kxCKmQ', env='AE_API_JWT_KEY') # --- Database --- # These flat fields are mutated by the bootstrap process in main.py (lifespan), # which swaps in production credentials after reading from the cfg table. DB_SERVER: str = Field('mariadb', env='AE_DB_SERVER') DB_PORT: str = Field('3306', env='AE_DB_PORT') DB_NAME: str = Field('aether_dev', env='AE_DB_NAME') DB_USER: str = Field('aether_dev', env='AE_DB_USERNAME') DB_PASS: str = Field('', env='AE_DB_PASSWORD') # Connection tuning DB_CONNECT_TIMEOUT: int = Field(20, env='AE_DB_CONNECTION_TIMEOUT') DB_POOL_RECYCLE: int = Field(1800, env='AE_DB_POOL_RECYCLE') # --- Logging --- LOG_PATH_APP: str = Field('/logs/aether_api.log', env='AE_API_LOG_PATH') # --- Redis --- REDIS_SERVER: str = Field('redis', env='AE_REDIS_SERVER') REDIS_PORT: str = Field('6379', env='AE_REDIS_PORT') # --- SMTP --- SMTP_SERVER: str = Field('linode.oneskyit.com', env='AE_SMTP_SERVER') SMTP_PORT: str = Field('465', env='AE_SMTP_PORT') SMTP_USERNAME: str = Field('send_mail', env='AE_SMTP_USERNAME') SMTP_PASSWORD: str = Field('set-in-ae-sql-db-cnf-tbl', env='AE_SMTP_PASSWORD') # --- File Storage --- FILES_PATH_ROOT: str = Field('/srv/hosted_files', env='AE_FILES_PATH_ROOT') FILES_PATH_TMP: str = Field('/srv/hosted_tmp', env='AE_FILES_PATH_TMP') # --- CORS --- ORIGINS_REGEX: str = Field( r'(https://.*\.oneskyit\.com)|(https://.*\.oneskyit\.com:4443)', env='AE_API_ORIGINS_REGEX' ) ORIGINS: List[str] = ['https://oneskyit.com'] # ------------------------------------------------------------------------- # Computed properties — maintain backwards-compatible dict interface used # throughout the app (e.g. settings.DB['server'], settings.REDIS['port']). # ------------------------------------------------------------------------- @property def AETHER_CFG(self) -> Dict[str, Any]: return {'id': self.AE_CFG_ID} @property def SQLALCHEMY_DB_URI(self) -> str: return f"mysql://{self.DB_USER}:{self.DB_PASS}@{self.DB_SERVER}:{self.DB_PORT}/{self.DB_NAME}" @property def DB(self) -> Dict[str, Any]: return { 'server': self.DB_SERVER, 'port': self.DB_PORT, 'name': self.DB_NAME, 'username': self.DB_USER, 'password': self.DB_PASS, 'connect_timeout': self.DB_CONNECT_TIMEOUT, 'pool_recycle': self.DB_POOL_RECYCLE, } @property def LOG_PATH(self) -> Dict[str, str]: return {'app': self.LOG_PATH_APP} @property def REDIS(self) -> Dict[str, str]: return {'server': self.REDIS_SERVER, 'port': self.REDIS_PORT} @property def SMTP(self) -> Dict[str, str]: return { 'server': self.SMTP_SERVER, 'port': self.SMTP_PORT, 'username': self.SMTP_USERNAME, 'password': self.SMTP_PASSWORD, } @property def FILES_PATH(self) -> Dict[str, str]: return { 'hosted_files_root': self.FILES_PATH_ROOT, 'hosted_tmp_root': self.FILES_PATH_TMP, } class Config: case_sensitive = False settings = Settings()