OC_P8 / api /db.py
KLEB38's picture
Upload folder using huggingface_hub
ab6d9f6 verified
Raw
History Blame Contribute Delete
1.77 kB
"""Database engine + session factory for prediction logging.
Single engine per process, instantiated lazily so the API can boot even when
``DATABASE_URL`` is unset (local dev without Supabase). Use
``init_engine()`` from the FastAPI lifespan to validate connectivity at
startup, and ``get_engine()`` from request handlers to grab the cached
instance.
"""
from __future__ import annotations
import logging
from threading import Lock
from sqlalchemy import Engine, create_engine
from api import settings
logger = logging.getLogger(__name__)
_engine: Engine | None = None
_lock = Lock()
def init_engine(database_url: str | None = None) -> Engine | None:
"""Initialise the global engine. Returns None when no URL is configured.
Called once at app startup. Safe to call multiple times — subsequent
calls are no-ops.
"""
global _engine
url = database_url or settings.DATABASE_URL
if not url:
logger.warning(
"DATABASE_URL not set — prediction logging disabled. "
"Set the env var to enable Supabase persistence."
)
return None
with _lock:
if _engine is None:
_engine = create_engine(
url,
pool_size=5,
max_overflow=10,
pool_pre_ping=True,
future=True,
)
logger.info("Database engine initialised")
return _engine
def get_engine() -> Engine | None:
"""Return the cached engine, or None if logging is disabled."""
return _engine
def reset_engine() -> None:
"""Dispose and clear the engine. Useful for tests."""
global _engine
with _lock:
if _engine is not None:
_engine.dispose()
_engine = None