Great list of 4 tips for running fastapi applications.
Fat routers with all of the logic built in makes them hard to test, hard to refactor, causes lots of duplication, and makes it hard to reuse the business logic code later in something like a cli application.
I really like this advice! He reccommends deploying as early as you can get a healthcheck live in your application. I’ve found too many times developers build something that is really hard, or impossible to deploy, when if they had tried to deploy early they would have spotted some easy to fix issues. This is less important if you are building out of a template that your team commonly deploys from, but very important with new patterns.
Nice example of adding a healthcheck to fastapi, and integrating it with docker. Don’t forget to include curl in the install, nice touch. Very interesting approach to htmx and fast api. It uses separate decorators for returning template partials and json that can be stacked to include both options on a single route. The templates are explicitly set in the decorator. Separate decorators are used for full page and partial pages. I don’t see an example of full and partial pages being combined. I think the demo app must be behaving in a spa like fashion where it does not get all of the data when it calls index and index will ask for user-list. Definitely going to keep my eye on this project and ponder on it. Very interesting approach to htmx and fast api. It uses separate decorators for returning template partials and json that can be stacked to include both options on a single route. The templates are explicitly set in the decorator. Separate decorators are used for full page and partial pages. I don’t see an example of full and partial pages being combined. I think the demo app must be behaving in a spa like fashion where it does not get all of the data when it calls index and index will ask for user-list. Definitely going to keep my eye on this project and ponder on it. fastapi comes with a concept of background tasks which are functions that can be ran in the background after a function has been ran. This is handy for longer running functions that may take some time and you want to have fast response times. Here is an example from the docs This page shows how to customize your fastapi errors. I found this very useful to setup common templates so that I can return the same 404’s both programatically and by default, so it all looks the same to the end user. This post sat in draft for months. I stumbled upon it again and found great success returning good error messages based on user... ![[None]] I’ve been using these decorators to modify the behavior of specific routes. It will do things like 404 admin only routes in a way that looks just like fastapi’s default, or only allow certain roles into the route, or redirect unauthenticated users to login. After listening to yesterday’s syntaxfm I’m now really thinking about middleware and the benefits it might have. middleware would make it easy to apply things like admin to an entire admin router, so you wont forget it on any one admin route. It will look cleaner as the admin checker is only applied once per router, not once per route. ![[None]] jinja’s After struggling to get dependencies inside of middleware I learned that you can make global dependencies at the app level. I used this to set the user on every single route of the application without needing Depend on getting the user on each route. This page shows how to customize your fastapi errors. I found this very useful to setup common templates so that I can return the same 404’s both programatically and by default, so it all looks the same to the end user. Setting an additional log handler to the uvicorn logger for access logs in fastapi was not straightforward, but This post was very helpful. Here is a full example from the post. I’ve had better luck just routing both naked and trailing slash routes in fastapi. I’ve had api’s deployed as a subroute to a site rather than a subdomain, and the automatic redirect betweens them tended to always get messed up. This is pretty easy fix for the pain is causes just give vim a yyp, and if you don’t want deuplicates in your docs, ignore one. ... You can protect your fastapi docs behind auth so that not only can certain roles not run certain routes, but they cannot even see the docs at all. This way no one that shouldn’t be poking around can even discover routes they shouldn’t be using. Here is the soluteion provided by @kennylajara Fastapi passes flask in GitHub stars! arel is a “Lightweight browser hot reload for Python ASGI web apps” I just implemented this on my thoughts website using fastapi, and it’s incredibly fast and lightweight. There just two lines of js that make a web socket connection back to the backend that watches for changes. When in development mode, this snippet gets injected directly on the page and does a refresh when arel detects a change. I just discovered arel for hot reloading python applications when content changes from this snippet that implements it for fatapi. ... Fastapi lets you tag your Now all routes in exclude=True and repr=False is a good pydantic combination for secret attributes such as user passwords, or hashed passwords. exclude keeps it out of model_dumps, and repr keeps it out of the logs.from fastapi import FastAPI, Request from fastapi.responses import JSONResponse class UnicornException(Exception): def __init__(self, name: str): self.name = name app = FastAPI() @app.exception_handler(UnicornException) async def unicorn_exception_handler(request: Request, exc: UnicornException): return JSONResponse( status_code=418, content={"message": f"Oops! {exc.name} did something. There goes a rainbow..."}, ) @app.get("/unicorns/{name}") async def read_unicorn(name: str): if name == "yolo": raise UnicornException(name=name) return {"unicorn_name": name}
url_for in fastapi does not account for https by default, there is probably a better way, but this is a way that allows me to configure when I use http vs https. Setting tags in your fastapi endpoints will group them in the docs. You can also set some metadata around the tags to get nice descriptions. Excluding routes from fastapi docs, can be done from the route configuration using `include_in_schema`. This is handy for routes that are not really api based or duplicates. From the Docs #
from fastapi import FastAPI app = FastAPI() @app.get("/items/", include_in_schema=False) async def read_items(): return [{"item_id": "Foo"}] trailing slash #
import os import arel from fastapi import FastAPI, Request from fastapi.templating import Jinja2Templates app = FastAPI() templates = Jinja2Templates("templates") if _debug := os.getenv("DEBUG"): hot_reload = arel.HotReload(paths=[arel.Path(".")]) app.add_websocket_route("/hot-reload", route=hot_reload, name="hot-reload") app.add_event_handler("startup", hot_reload.startup) app.add_event_handler("shutdown", hot_reload.shutdown) templates.env.globals["DEBUG"] = _debug templates.env.globals["hot_reload"] = hot_reload @app.get("/") def index(request: Request): return templates.TemplateResponse("index.html", context={"request": request}) # run: # DEBUG=true uvicorn main:app --reload APIRouter’s so that the swagger docs are grouped according to the router.router = APIRouter(tags=['router']) router will appear in the router group in the swagger docs.