# crudkit/integrations/flask.py from __future__ import annotations from flask import Flask from sqlalchemy.orm import scoped_session, sessionmaker from ..engines import CRUDKitRuntime from ..config import Config def init_app(app: Flask, *, runtime: CRUDKitRuntime | None = None, config: type[Config] | None = None): """ Initializes CRUDKit for a Flask app. Provides `app.extensions['crudkit']` with a runtime (engine + session_factory). Caller manages session lifecycle. """ runtime = runtime or CRUDKitRuntime(config=config) app.extensions.setdefault("crudkit", {}) app.extensions["crudkit"]["runtime"] = runtime # Build ONE sessionmaker bound to the ONE true engine object # so engine id == sessionmaker.bind id, always. engine = runtime.engine SessionFactory = runtime.session_factory or sessionmaker(bind=engine, **runtime._config.session_kwargs()) app.extensions["crudkit"]["SessionFactory"] = SessionFactory app.extensions["crudkit"]["Session"] = scoped_session(SessionFactory) # Attach pool listeners to the *same* engine the SessionFactory is bound to. # Don’t guess. Don’t hope. Inspect. try: bound_engine = getattr(SessionFactory, "bind", None) or getattr(SessionFactory, "kw", {}).get("bind") or engine pool = bound_engine.pool except Exception as e: print(f"[crudkit.init_app] Failed to attach pool listeners: {e}") return runtime