# 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 from sqlalchemy import event @event.listens_for(pool, "checkout") def _on_checkout(dbapi_conn, conn_record, conn_proxy): sz = pool.size() chk = pool.checkedout() try: conns_in_pool = pool.checkedin() except Exception: conns_in_pool = "?" print(f"POOL CHECKOUT: Pool size: {sz} Connections in pool: {conns_in_pool} " f"Current Overflow: {pool.overflow()} Current Checked out connections: {chk} " f"engine id= {id(bound_engine)}") @event.listens_for(pool, "checkin") def _on_checkin(dbapi_conn, conn_record): sz = pool.size() chk = pool.checkedout() try: conns_in_pool = pool.checkedin() except Exception: conns_in_pool = "?" print(f"POOL CHECKIN: Pool size: {sz} Connections in pool: {conns_in_pool} " f"Current Overflow: {pool.overflow()} Current Checked out connections: {chk} " f"engine id= {id(bound_engine)}") except Exception as e: print(f"[crudkit.init_app] Failed to attach pool listeners: {e}") return runtime