import os import json from sqlalchemy import create_engine from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.orm import sessionmaker from pydantic_settings import BaseSettings from typing import Optional def _resolve_db_url(env_url: str) -> str: """Read DB config from wizard config volume if available, else use env.""" config_dir = os.getenv("CONFIG_DIR", "/config") config_file = os.getenv("CONFIG_FILE", "harborforge.json") config_path = os.path.join(config_dir, config_file) if os.path.exists(config_path): try: with open(config_path, "r") as f: cfg = json.load(f) db_cfg = cfg.get("database") if db_cfg: host = db_cfg.get("host", "mysql") port = db_cfg.get("port", 3306) user = db_cfg.get("user", "harborforge") password = db_cfg.get("password", "harborforge_pass") database = db_cfg.get("database", "harborforge") return f"mysql+pymysql://{user}:{password}@{host}:{port}/{database}" except Exception: pass return env_url class Settings(BaseSettings): DATABASE_URL: str = "mysql+pymysql://harborforge:harborforge_pass@mysql:3306/harborforge" SECRET_KEY: str = "change-me-in-production" LOG_LEVEL: str = "INFO" ALGORITHM: str = "HS256" ACCESS_TOKEN_EXPIRE_MINUTES: int = 30 class Config: env_file = ".env" settings = Settings() # Resolve DB URL: wizard config volume > env > default _db_url = _resolve_db_url(settings.DATABASE_URL) engine = create_engine(_db_url, pool_pre_ping=True) SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine) Base = declarative_base() def get_db(): db = SessionLocal() try: yield db finally: db.close()