Write Fast API Controllers (Classes) that can inherit route information from it's parent. This also allows to create a path prefix from a template and add api version information in the template.
This utility library is written on top of fastapi-utils.
$ pip install fastapi-controller
importuvicornfrompydanticimportBaseModelfromfastapiimportHeader, Depends, FastAPIfromfastapi_controllerimportcreate_controller, controller, register_controllers_to_app# Create a controller with a path prefix template that can use the# controller name and version as template variables# For a controller named PeopleController, {controller} is replaced# by `people`ControllerBase=create_controller("/v{version}/{controller}", "1.0")
defget_jwt_user(auth: str=Header(...)) ->str:
""" Pretend this function gets a UserID from a JWT in the auth header """returnauthclassGetModel(BaseModel):
hello: strclassDefaultController(ControllerBase):
user_id: str=Depends(get_jwt_user)
@controller.get("/", response_model=GetModel)defget_all(self) ->dict:
return {"hello": self.user_id}
@controller.get("/{model_id}")defget_one(self, model_id: int):
return {"one": model_id}
classPeopleController(DefaultController):
# The people controller will have the two GET routes from the# parent class as well as the post route defined here.@controller.post("/")defcreate(self):
return {"create": self.user_id}
classScheduledJobsController(DefaultController):
# The jobs controller will have the two GET routes from the parent# class with one of the routes implementation overridden.defget_one(self, model_id: int):
# This'll inherit the route information GET /{model_id} from the# parent class and override functionality of the routepassif__name__=='__main__':
app=FastAPI()
# This function registers all the child controllers who have# ControllerBase as their parent in their inheritance heirarchy.# Intermediate Controllers between the ControllerBase and the# Child Controllers are ignored# For e.g. For the following inheritance heirarchy# ControllerBase -> DefaultController -> DerivedController -> FunctionsController -> PeopleController# Only the PeopleController is used for registering# the API routes with all the routes defined in the parent controllers# available in the child controller.register_controllers_to_app(app, ControllerBase)
uvicorn.run(app, host="0.0.0.0", port=8000)With the above example, the following API routes will be registered:
GET /v1.0/people/
GET /v1.0/people/{model_id}
POST /v1.0/people/
GET /v1.0/scheduled_jobs/
GET /v1.0/scheduled_jobs/{model_id}