from pydantic_settings import BaseSettings from typing import Optional import os import tempfile class Settings(BaseSettings): # API Configuration API_V1_STR: str = "/api/v1" PROJECT_NAME: str = "PDF Q&A Chatbot" # Security SECRET_KEY: str = "your-secret-key-here" ACCESS_TOKEN_EXPIRE_MINUTES: int = 60 * 24 * 8 # 8 days # Database DATABASE_URL: str = "sqlite:///./pdf_chatbot.db" # Vector Database CHROMA_PERSIST_DIRECTORY: str = "chroma_db" # AI Providers OPENROUTER_API_KEY: Optional[str] = None ANTHROPIC_API_KEY: Optional[str] = None # File Storage UPLOAD_DIR: str = "uploads" MAX_FILE_SIZE: int = 10 * 1024 * 1024 # 10MB ALLOWED_EXTENSIONS: list = [".pdf"] # CORS BACKEND_CORS_ORIGINS: list = [ "http://localhost:3000", "http://localhost:3001", "http://127.0.0.1:3000", "http://127.0.0.1:3001", ] class Config: env_file = ".env" case_sensitive = True settings = Settings() # Ensure upload and persistence directories exist, falling back to system temporary for attr, fallback_subdir in [("UPLOAD_DIR", "uploads"), ("CHROMA_PERSIST_DIRECTORY", "chroma_db")]: dir_path = getattr(settings, attr) try: os.makedirs(dir_path, exist_ok=True) except PermissionError: # Fall back to a path inside the system temporary directory where writes are usually allowed temp_dir = os.path.join(tempfile.gettempdir(), fallback_subdir) os.makedirs(temp_dir, exist_ok=True) setattr(settings, attr, temp_dir) # Additional safety: ensure CHROMA_PERSIST_DIRECTORY is writable (fallback to temp dir if not) try: _test_chroma = os.path.join(settings.CHROMA_PERSIST_DIRECTORY, '.write_test') with open(_test_chroma, 'w') as _f: _f.write('') os.remove(_test_chroma) except (PermissionError, OSError): temp_chroma = os.path.join(tempfile.gettempdir(), 'chroma_db') os.makedirs(temp_chroma, exist_ok=True) settings.CHROMA_PERSIST_DIRECTORY = temp_chroma # Ensure SQLite database path is writable (fallback to temp dir if not) if settings.DATABASE_URL.startswith("sqlite"): db_uri_prefix = "sqlite:///" db_path = settings.DATABASE_URL[len(db_uri_prefix):] abs_db_path = os.path.abspath(db_path) db_dir = os.path.dirname(abs_db_path) try: os.makedirs(db_dir, exist_ok=True) # Try creating a temporary file to check write access test_path = os.path.join(db_dir, ".write_test") with open(test_path, "w") as _f: _f.write("") os.remove(test_path) except (PermissionError, OSError): # Fallback temp_db_path = os.path.join(tempfile.gettempdir(), "pdf_chatbot.db") settings.DATABASE_URL = f"sqlite:///{temp_db_path}"