Master FastAPI Middleware, Background Tasks, and Deployment Strategies
This article walks through using FastAPI middleware for request timing, redirection, host whitelisting, and CORS, demonstrates background tasks and custom response codes, and explains various deployment options including Uvicorn, Gunicorn, Docker, and Nginx, providing complete code examples.
FastAPI Middleware Overview
FastAPI supports middleware similar to Flask hooks, allowing you to add functionality to requests and responses. Below is an example that measures request processing time and adds it to the response headers.
# -*- coding: UTF-8 -*-
import time
from fastapi import FastAPI
from starlette.requests import Request
app = FastAPI()
@app.middleware("http")
async def add_process_time_header(request: Request, call_next):
start_time = time.time()
response = await call_next(request)
process_time = time.time() - start_time
response.headers["X-Process-Time"] = str(process_time)
print(response.headers)
return response
@app.get("/")
async def main():
return {"message": "Hello World"}
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="127.0.0.1", port=8000)Request Redirection Middleware
FastAPI can use HTTPSRedirectMiddleware to force HTTPS redirection (301).
from fastapi import FastAPI
from starlette.middleware.httpsredirect import HTTPSRedirectMiddleware
app = FastAPI()
app.add_middleware(HTTPSRedirectMiddleware)
@app.get("/")
async def main():
return {"message": "Hello World"}Host Whitelist Middleware
Use TrustedHostMiddleware to restrict allowed hosts, supporting wildcard patterns.
from fastapi import FastAPI
from starlette.middleware.trustedhost import TrustedHostMiddleware
app = FastAPI()
app.add_middleware(
TrustedHostMiddleware, allowed_hosts=["example.com", "*.example.com"]
)
@app.get("/")
async def main():
return {"message": "Hello World"}CORS Middleware
Configure CORSMiddleware to allow cross‑origin requests from specified origins.
from fastapi import FastAPI
from starlette.middleware.cors import CORSMiddleware
app = FastAPI()
origins = [
"https://gzky.live",
"https://google.com",
"http://localhost:5000",
"http://localhost:8000",
]
app.add_middleware(
CORSMiddleware,
allow_origins=origins,
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)Background Tasks
FastAPI provides BackgroundTasks to run functions after a response is sent. Example writes logs asynchronously.
# -*- coding: UTF-8 -*-
from fastapi import BackgroundTasks, Depends, FastAPI
app = FastAPI()
def write_log(message: str):
with open("log.txt", mode="a") as log:
log.write(message)
def get_query(background_tasks: BackgroundTasks, q: str = None):
if q:
message = f"found query: {q}
"
background_tasks.add_task(write_log, message)
return q
@app.post("/send-notification/{email}")
async def send_notification(email: str, background_tasks: BackgroundTasks, q: str = Depends(get_query)):
message = f"message to {email}
"
background_tasks.add_task(write_log, message)
return {"message": "Message sent"}Custom Response Status Codes
FastAPI allows explicit status codes for endpoints using status constants.
from fastapi import FastAPI
from starlette import status
app = FastAPI()
@app.get("/201/", status_code=status.HTTP_201_CREATED)
async def item201():
return {"httpStatus": 201}
@app.get("/302/", status_code=status.HTTP_302_FOUND)
async def items302():
return {"httpStatus": 302}
@app.get("/404/", status_code=status.HTTP_404_NOT_FOUND)
async def items404():
return {"httpStatus": 404}
@app.get("/500/", status_code=status.HTTP_500_INTERNAL_SERVER_ERROR)
async def items500():
return {"httpStatus": 500}
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="127.0.0.1", port=8000)Deployment Options
FastAPI is commonly deployed with Uvicorn (or hypercorn ) for ASGI support. pip install uvicorn Run with auto‑reload:
uvicorn main:app --reload --host 0.0.0.0 --port 8000Alternatively, use Gunicorn with the Uvicorn worker:
pip install gunicorn
gunicorn -w 4 -b 0.0.0.0:5000 manage:app -DDocker deployment simplifies environment setup. Build an image with a Dockerfile and run the container, exposing the desired port.
Placing an Nginx reverse proxy in front of Uvicorn/Gunicorn adds production‑grade features such as static file handling and TLS termination.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Python Crawling & Data Mining
Life's short, I code in Python. This channel shares Python web crawling, data mining, analysis, processing, visualization, automated testing, DevOps, big data, AI, cloud computing, machine learning tools, resources, news, technical articles, tutorial videos and learning materials. Join us!
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
