Unable to inject dependencies to FastAPI endpoints

Question:

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 arises 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 getting is different errors, but the one that appears the most is the following:

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!

Asked By: Infinite Wait

||

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 ...
Answered By: Levi

You can inject dependency to APIRouter like below –

router = APIRouter(prefix="/chords",
dependencies=[Depends(ChordsService)])

See Example: https://fastapi.tiangolo.com/tutorial/bigger-applications/#another-module-with-apirouter

Answered By: Always Sunny