Is it possible to pass Path arguments into FastAPI dependency functions?

Question:

Is there anyway for a FastAPI "dependency" to interpret Path parameters?

I have a lot of functions of the form:

@app.post("/item/{item_id}/process", response_class=ProcessResponse)
async def process_item(item_id: UUID, session: UserSession = Depends(security.user_session)) -> ProcessResponse:
    item = await get_item(client_id=session.client_id, item_id=item_id)
    await item.process()

Over and over, I need to pass in [multiple] arguments to fetch the required item before doing something with it. This is very repetitive and makes the code very verbose. What I’d really like to do is pass the item in as an argument to the method.

Ideally I’d like to make get_item a dependency or embed it somehow in the router. This would dramatically reduce the repetitive logic and excessively verbose function arguments. The problem is that some critical arguments are passed by the client in the Path.

Is it possible to pass Path arguments into a dependency or perhaps execute the dependency in the router and pass the result?

Asked By: Philip Couling

||

Answers:

A FastAPI dependency function can take any of the arguments that a normal endpoint function can take.

So in a normal endpoint you might define a path parameter like so:

from fastapi import FastAPI

app = FastAPI()


@app.get("/items/{item_id}")
async def read_item(item_id):
    return {"item_id": item_id}

Now if you want to use that parameter in a dependency, you can simply do:

from fastapi import Depends, FastAPI

app = FastAPI()

async def my_dependency_function(item_id: int):
    return {"item_id": item_id}


@app.get("/items/{item_id}")
async def read_item(item_id: int, my_dependency: dict = Depends(my_dependency_function)):
    return my_dependency

The parameters will simply be passed on through to the dependency function if they are present there. You can also use things like Path and Query within the dependency function to define where these are coming from.

It will just analyze the request object to pull these values.

Here is an example using the Path function from FastAPI:

from fastapi import Depends, FastAPI, Path

app = FastAPI()

async def my_dependency_function(item_id: int = Path(...)):
    return {"item_id": item_id}


@app.get("/items/{item_id}")
async def read_item(my_dependency: dict = Depends(my_dependency_function)):
    return my_dependency

As for your concern of implementing it as a dependency in the router, you can do something like this when creating the router:

items_router = APIRouter(
    prefix="/items",
    tags=["items"],
    dependencies=[Depends(my_dependency_function)],
)

Or you can do it when you run include_router on the app like:

app.include_router(
    items_router,
    prefix="/items",
    dependencies=[Depends(my_dependency_function)],
)

For more on dependencies and more examples like this see https://fastapi.tiangolo.com/tutorial/dependencies/

Answered By: Darren
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.