import os from pathlib import Path from typing import List, ClassVar from pydantic import AnyHttpUrl, validator from pydantic_settings import BaseSettings, SettingsConfigDict # Set up DB_DIR outside the class to keep config cleaner def get_db_dir() -> Path: # Main database location - use absolute path for reliability db_dir = Path("/app/storage/db") # Fallback to project-relative path if /app is not available if not db_dir.exists() and not os.access("/app", os.W_OK): # Use project root-relative path as a fallback project_root = Path(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))) db_dir = project_root / "app" / "storage" / "db" # Create directory if it doesn't exist try: db_dir.mkdir(parents=True, exist_ok=True) print(f"Created database directory at: {db_dir}") except Exception as e: print(f"Warning: Could not create database directory: {e}") return db_dir class Settings(BaseSettings): model_config = SettingsConfigDict( env_file=".env", env_file_encoding="utf-8", case_sensitive=True, ) PROJECT_NAME: str = "Blogging API" API_V1_STR: str = "/api/v1" # JWT token settings SECRET_KEY: str = os.getenv("SECRET_KEY", "09d25e094faa6ca2556c818166b7a9563b93f7099f6f0f4caa6cf63b88e8d3e7") ALGORITHM: str = "HS256" ACCESS_TOKEN_EXPIRE_MINUTES: int = 60 * 24 * 8 # 8 days # SQLite settings # This is a class variable, not a field DB_DIR: ClassVar[Path] = get_db_dir() # Fallback to in-memory SQLite if file access fails USE_IN_MEMORY_DB: bool = os.getenv("USE_IN_MEMORY_DB", "").lower() in ("true", "1", "yes") if USE_IN_MEMORY_DB: SQLALCHEMY_DATABASE_URL: str = "sqlite://" # In-memory SQLite database print("Using in-memory SQLite database") else: SQLALCHEMY_DATABASE_URL: str = f"sqlite:///{DB_DIR}/db.sqlite" print(f"Using file-based SQLite database at: {SQLALCHEMY_DATABASE_URL}") # CORS settings BACKEND_CORS_ORIGINS: List[AnyHttpUrl] = [] @validator("BACKEND_CORS_ORIGINS", pre=True) def assemble_cors_origins(cls, v: str | List[str]) -> List[str] | str: if isinstance(v, str) and not v.startswith("["): return [i.strip() for i in v.split(",")] elif isinstance(v, (list, str)): return v raise ValueError(v) settings = Settings()