python-dependency-injector
python-dependency-injector copied to clipboard
Possibility to inject FastAPI Request object as argument of router dependency
Hi mates, trying use this beautiful lib with FastApi as better IoC container but not sure whether it is possible to inject http Request object as argument of FastApi router dependency.
So let's say I have a router where a Service is injected:
@router.get('/') @inject async def get(search_service: SearchService = Depends(Provide[Container.service])):...
Service itself has ctor parameter of http Request type:
class Service: def __init__(self, request: Request):...
And in container it is registered via Factory provider:
service=providers.Factory(Service)
As result during http request argument is not given and exception is thrown.
However FastApi framework without DependencyInjector able to analyze constructor parameters and provide instance of http request in case it is required via Depends built in DI mechanism:
@router.get('/') async def get(search_service: SearchService = Depends(SearchService)):...
But for sure in future Service could have other dependencies and I prefer to use dedicated IoC container with its separated bindings
So yeah the question is: is it possible to get http Request object somehow automatically?
Many thanks
Hi @AshurovRustam , right now it's not possible. I'm not sure if that's gonna work, but I could try to implement this.
As a temporary solution you can use Provider
marker to inject service provider and initialize service inside the handler:
from dependency_injector import providers
from dependency_injector.wiring import inject, Provider
@router.get('/', response_model=Response)
@inject
async def index(
request: Request,
service_provider: providers.Factory[Service] = Depends(Provider[Container.service]),
):
service = service_provider(request)
...
I will get back after running some experiments.
Thanks for your quick response @rmk135 Roman, it is exactly how I'm using it now. Probably having usage of providers only in routers is not a big problem for me while these DI concepts don't leak to the lower layers of the application.
Plus maybe I should consider to organize access to the request data via some static contextvars collection that will be populated in FastApi middleware per request. Probably DI Factory provider being something like "transient" type of DI binding will also access this static contextvars collection per request and pass its value as argument of Service ctor parameter properly?
👍 I think having contextvar scope would a good idea anyway.
Any further thoughts on this? Would be hugely helpful.
I didn't get to these experiments yet, my apologies. I still believe that the closest solution to this problem should be in using contextvars + middleware + special provider for context vars.
As of now I can share this piece of code: https://gist.github.com/rmk135/ddc45d2cd1981bfe3d4486dbfbba0b1a
This is based on aiohttp
. Server gets some data from the request and pushes it into contextvars, that are later used for making the injections in the container.
Thanks. On a related note, I also found this which was super helpful: https://gist.github.com/ddanier/ead419826ac6c3d75c96f9d89bea9bd0
Hi guys 👋
Any news on this? It'd be very nice to have it out of the box, without using ContextVar
s to work around this.
Thanks a lot