FastAPI top-level dependencies

This article lives in:

Intro

As well as top-level dependencies, tags, and other parameters for APIRouters, that before were available only on app.include_router().

This makes it easier to put configurations and dependencies (e.g. for authentication) related to a group of path operations more closely together. 🔒

Let’s start by checking APIRouter...

Include a router

from fastapi import APIRouterrouter = APIRouter()
@router.get("/users/")
def read_users():
return ["rick", "morty"]

And now let’s say you want to include it in the main.py file with:

from fastapi import FastAPI, Depends
from . import users
from .dependencies import get_query_token
app = FastAPI()app.include_router(
users.router,
tags=["users"],
dependencies=[Depends(get_query_token)]
)
@app.get("/")
def main():
return {"message": "Hello World"}

In this example, you are applying the tag users to all the path operations in users.py. And you are also applying the dependency get_query_token to all of them.

This works, and it was the only/main way to do it up to version 0.62.0.

But what is not so great about it is that the tag and the dependency are mainly related to users.py, not to main.py. But that code had to live in main.py, instead of being closer to what it is related to.

APIRouter top-level dependencies and tags

So, the new router.py can now look like:

from fastapi import APIRouter, Depends
from .dependencies import get_query_token
router = APIRouter(
tags=["users"],
dependencies=[Depends(get_query_token)]
)
@router.get("/users/")
def read_users():
return ["rick", "morty"]

…notice the tags and dependencies in the APIRouter, they can now live closer to their related code! 🎉

And the main.py would be simply:

from fastapi import FastAPI
from . import users
app = FastAPI()app.include_router(
users.router,
)
@app.get("/")
def main():
return {"message": "Hello World"}

Global dependencies

from fastapi import FastAPI, Depends
from .dependencies import get_query_token
app = FastAPI(
dependencies=[Depends(get_query_token)]
)
@app.get("/")
def main():
return {"message": "Hello World"}

Tips

  • By default, set all those configs in APIRouter().
  • Try to only set them in app.include_router() when you want to override some defaults that can't (or shouldn't) be set in APIRouter directly.
  • Set them in FastAPI() only when you want them to apply to everything, e.g. some default authentication for a simple app.

Learn More

And about APIRouter top-level dependencies, tags, and others.

If you don’t want to miss other news, you can subscribe to the FastAPI and friends official newsletter. 🎉

About me

You can follow me, contact me, see what I do, or use my open source code:

Creator of FastAPI and Typer. Dev at Exposion AI. APIs, Deep Learning/Machine Learning, full-stack distributed systems, SQL/NoSQL, Python, Docker, JS, TS, etc.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store