Tips and Tricks

FastAPI

FastAPI - Using "callable" instances as dependencies in your API endpoints


FastAPI tip:

You can inject instances of a class as a dependency to your API endpoints, which you can then use when you as a configurable dependency.

You need to make instances callable via __call__.

https://fastapi.tiangolo.com/advanced/advanced-dependencies/#a-callable-instance

👇

from fastapi import FastAPI, Depends, HTTPException, status
from pydantic import BaseModel


class User(BaseModel):
    username: str
    groups: set[str]


users = [
    User(username='johndoe', groups={"admin"}),
    User(username='bobbuilder', groups={"builders"}),
]

app = FastAPI()


class AuthorizeUser:
    def __init__(self, allowed_groups: set[str]):
        self._allowed_groups = allowed_groups

    def __call__(self, username: str):
        try:
            user = next(user for user in users if user.username == username)
        except StopIteration:
            raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED)

        if user.groups.isdisjoint(self._allowed_groups):
            raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED)

        return user


@app.get("/only-admins")
def only_admins(user: User = Depends(AuthorizeUser(allowed_groups={"admin"}))):
    return {"message": f"User: {user.username} is in admin group."}


@app.get("/only-builders")
def only_admins(user: User = Depends(AuthorizeUser(allowed_groups={"builders"}))):
    return {"message": f"User: {user.username} is in builders group."}