import logging import os from pathlib import Path from typing import Optional from pydantic_settings import BaseSettings, SettingsConfigDict logger = logging.getLogger(__name__) class Settings(BaseSettings): PROJECT_NAME: str = "File Upload Download API" API_V1_STR: str = "/api/v1" # Base directory for storage - can be overridden by environment variable STORAGE_BASE_DIR: str = os.environ.get("STORAGE_BASE_DIR", "./storage") # File storage directory - derived from base dir but can be overridden FILE_STORAGE_DIR: Optional[str] = os.environ.get("FILE_STORAGE_DIR") # Database directory - derived from base dir but can be overridden DB_DIR: Optional[str] = os.environ.get("DB_DIR") # Database URL - derived from DB_DIR but can be overridden SQLALCHEMY_DATABASE_URL: Optional[str] = os.environ.get("SQLALCHEMY_DATABASE_URL") # Configure max file size (10MB by default) MAX_FILE_SIZE: int = int( os.environ.get("MAX_FILE_SIZE", 10 * 1024 * 1024) ) # 10MB in bytes model_config = SettingsConfigDict(case_sensitive=True, env_file=".env") # Create settings instance settings = Settings() # Resolve directory paths if not explicitly set via environment variables if not settings.FILE_STORAGE_DIR: settings.FILE_STORAGE_DIR = os.path.join(settings.STORAGE_BASE_DIR, "files") if not settings.DB_DIR: settings.DB_DIR = os.path.join(settings.STORAGE_BASE_DIR, "db") if not settings.SQLALCHEMY_DATABASE_URL: db_path = os.path.join(settings.DB_DIR, "db.sqlite") settings.SQLALCHEMY_DATABASE_URL = f"sqlite:///{db_path}" # Convert string paths to Path objects for easier manipulation storage_base_path = Path(settings.STORAGE_BASE_DIR) db_path = Path(settings.DB_DIR) file_storage_path = Path(settings.FILE_STORAGE_DIR) # Try to create directories with better error handling try: # Ensure base storage directory exists storage_base_path.mkdir(parents=True, exist_ok=True) logger.info(f"Base storage directory: {storage_base_path}") # Ensure DB directory exists db_path.mkdir(parents=True, exist_ok=True) logger.info(f"Database directory: {db_path}") # Ensure file storage directory exists file_storage_path.mkdir(parents=True, exist_ok=True) logger.info(f"File storage directory: {file_storage_path}") except PermissionError as e: logger.warning( f"Permission denied when creating directories: {e}. " f"The application may need to be run with appropriate permissions or " f"you should pre-create these directories with correct permissions." ) # We'll continue running, as the application might be able to function # if the directories already exist with correct permissions except Exception as e: logger.error(f"Error creating storage directories: {e}") # We'll still continue running in case the application can operate # without direct file access (e.g., if using external storage)