Unable to inject dependencies to FastAPI endpoints

Viewed 46

I have configured a dependencies.py where I'm injecting a set of dependencies to different services by using python's binder.bind(my_config). The goal is being able to easily inject those services to each endpoint of my API. The problem comes when I pass that service as an argument to my endpoint after having injected that service via its name. So:

import inject
from fastapi import APIRouter, HTTPException, Request, Depends

from src.services.chords import ChordsService

router = APIRouter(prefix="/chords")


@router.get("")
@inject.params(chords_service=ChordsService)
def get_chords(chords_service: ChordsService, req: Request, key: str, suffix: str = None, instrument: str = None):

    params = dict(req.query_params)
    return chords_service.get(params)

This does not work, I've tried changing the order of get_chords' arguments. All I'm doing is getting different errors, but the one that appears the most is that ChordsService is not a valid pydantic field type. I've read a bit about the use of pydantic in FastAPI and I see why I get this error, but I'm stuck at trying to inject those services... Is there a way to do it? Thanks!

2 Answers

You could use the dependency injection from fastapi directly. I don't have an IDE, so syntax is probably wrong, but you could do something like:

@lru_cache(max_size=1)
def get_chords_service():
    return ChordsService()

@router.get("")
def get_chords(chords_service: ChordsService=Depends(get_chords_service), req: Request ...

This if you want the same ChordService instance everywhere. If you are ok getting a new one each time, it becomes much simpler (you don't even need the getter function):

@router.get("")
def get_chords(chords_service: ChordsService=Depends(), req: Request ...
Related