I have implemented an auth middleware based on BaseDeviceAuthMiddleware and need to access the database from within the middleware. I found that accessing dependencies like you normally would with route handlers is not possible via middleware. I then found by searching posts here that I should be using SQLAlchemyAsyncConfig.provide_transaction() to get access to a session from middleware.
What's the safest/cleanest way to get get access to provide_transaction() from within my middleware class?
Right now, in my create_app(), after I create the app, I store a reference to the provide_transaction function in the Litestar app state:
__init__.py:
def create_app() -> Litestar:
engine_config = EngineConfig(echo=True)
db_config = SQLAlchemyAsyncConfig(
connection_string=build_database_uri(),
metadata=Base.metadata,
create_all=True,
engine_config=engine_config,
)
from .devices_controller import DevicesController
app = Litestar(
route_handlers=[DevicesController],
dependencies={'transaction': provide_transaction},
plugins=[SQLAlchemyPlugin(db_config)]
)
app.state.provide_session = db_config.provide_session
return app
Then in my middleware, I reference it like so:
auth_middleware.py:
async def authenticate_request(self, connection: ASGIConnection) -> AuthenticationResult:
...
async with connection.app.state.provide_session(connection.app.state, connection.scope) as session:
result = await session.execute(...)
...
This seems to work fine, but feels clunky. Is there a better way than storing a reference to provide_session in the app state? Is this a safe method? I also considered having my db_config instance stored in a separate Python module that I could import from both create_app and in the middleware.