woltapp / magic-di

Dependency Injector with minimal boilerplate code, built-in support for FastAPI and Celery, and seamless integration to basically anything.
MIT License
43 stars 1 forks source link

Is there a way to inject FastAPI `Request` object in the dependency chain? #19

Open wadinj opened 1 month ago

wadinj commented 1 month ago

Hi,

We use middleware and request state to bind a SQLAlchemy session to a request. Is there a way to inject the Request object from FastAPI in magic-di dependency chain?

RB387 commented 1 month ago

Hey 👋 magic-di dependencies are typically used in app scope. However, you can also combine them with fastapi’s request scope dependencies. Please correct me if I’m wrong, but I believe you can achieve it with something like this

from contextlib import asynccontextmanager
from fastapi import Request, Depends
from magic_di.fastapi import Provide
from magic_di import Connectable

class SQLAlchemy(Connectable):
   @asynccontextmanager
   async def start_session(self, request: Request):
       yield SQLAlchemySession(self, request)

async def get_sql_alchemy(request: Request, sql_alchemy: Provide[SQLAlchemy]) -> SQLAlchemySession:
    async with sql_alchemy.start_session(request) as session:
        yield session

@app.get('/test')
async def test_endpoint(sql_alchemy_session:  Annotated[SQLAlchemySession, Depends(get_sql_alchemy)]):
    ...
wadinj commented 1 month ago

Thanks! I'll make a try. There's no real consensus to bind the SQLAlchemy to the request lifecycle. Folks are sometimes using middleware, or Depends mechanism.

Do you have a best practices to bind 1 session per Request or per celery task with magic-di?

Awesome work with this DI injector ! Thank you