FastAPI Middleware
What is middleware in FastAPI?
Middleware in FastAPI is a function that is executed before and after each request. Middleware can intercept incoming requests and outgoing responses to perform operations such as logging, modifying headers, handling authentication, or processing errors. Middleware is executed for every request, and it can modify the request, response, or both.
How do you create middleware in FastAPI?
To create middleware in FastAPI, you use the @app.middleware("http") decorator. The middleware function must accept two parameters: request and call_next. The request is the incoming request object, and call_next is a function that processes the request and returns a response.
Example of creating middleware:
from fastapi import FastAPI, Request
app = FastAPI()
@app.middleware("http")
async def add_custom_header(request: Request, call_next):
response = await call_next(request)
response.headers["X-Custom-Header"] = "Custom Value"
return response
In this example, the middleware adds a custom header X-Custom-Header to the response for every request.
How do you modify requests in middleware?
In FastAPI middleware, you can modify the incoming request before passing it to the route handler. You can log the request, add or modify headers, or change the body of the request.
Example of modifying requests in middleware:
from fastapi import FastAPI, Request
app = FastAPI()
@app.middleware("http")
async def log_request(request: Request, call_next):
print(f"Incoming request: {request.url}")
response = await call_next(request)
return response
In this example, the middleware logs the URL of every incoming request before passing it to the route handler.
How do you modify responses in middleware?
You can modify responses in middleware by intercepting the response object after the route handler has processed the request. You can modify headers, change the status code, or even alter the response body.
Example of modifying responses in middleware:
from fastapi import FastAPI, Request
app = FastAPI()
@app.middleware("http")
async def add_process_time_header(request: Request, call_next):
response = await call_next(request)
response.headers["X-Process-Time"] = "0.05s"
return response
In this example, the middleware adds a custom header X-Process-Time to the response, simulating the processing time for the request.
What is the purpose of the call_next function in FastAPI middleware?
The call_next function in FastAPI middleware is used to pass the request to the next handler in the request lifecycle. It processes the request by calling the corresponding route handler and returning the response. You use call_next to ensure that the request is passed through to the actual route after any middleware processing.
Example of using call_next:
from fastapi import FastAPI, Request
app = FastAPI()
@app.middleware("http")
async def process_request(request: Request, call_next):
response = await call_next(request)
return response
In this example, call_next processes the request and returns the response after any middleware operations have been applied.
How do you handle exceptions in middleware in FastAPI?
You can handle exceptions in middleware by using a try-except block around the call_next function. This allows you to catch exceptions that occur during request processing and return a custom response or log the error.
Example of handling exceptions in middleware:
from fastapi import FastAPI, Request, HTTPException
app = FastAPI()
@app.middleware("http")
async def exception_handling_middleware(request: Request, call_next):
try:
response = await call_next(request)
except HTTPException as exc:
return {"error": str(exc.detail)}
except Exception as exc:
return {"error": "An unexpected error occurred"}
return response
In this example, the middleware catches HTTPException errors and returns a custom error message. It also catches other unexpected exceptions and returns a generic error message.
How do you log requests and responses using middleware in FastAPI?
You can use middleware to log both incoming requests and outgoing responses in FastAPI. This is useful for monitoring, debugging, or auditing API calls.
Example of logging requests and responses:
from fastapi import FastAPI, Request
app = FastAPI()
@app.middleware("http")
async def log_requests_responses(request: Request, call_next):
print(f"Request: {request.method} {request.url}")
response = await call_next(request)
print(f"Response status: {response.status_code}")
return response
In this example, the middleware logs the HTTP method and URL of the request and the status code of the response for every request handled by the API.
How do you add global CORS settings with middleware in FastAPI?
FastAPI provides built-in support for Cross-Origin Resource Sharing (CORS) by using the CORSMiddleware middleware. CORS is used to control which domains are allowed to access resources from a different domain.
Example of adding CORS middleware:
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
app = FastAPI()
app.add_middleware(
CORSMiddleware,
allow_origins=["*"], # Allows all origins
allow_credentials=True,
allow_methods=["*"], # Allows all HTTP methods
allow_headers=["*"], # Allows all headers
)
In this example, CORS is configured globally for the FastAPI app, allowing all origins, HTTP methods, and headers. This ensures that requests from any domain can interact with the API.
How do you use third-party middleware in FastAPI?
FastAPI allows you to add third-party middleware using the add_middleware method. Third-party middleware can be used for tasks such as request throttling, authentication, and logging. You pass the middleware class and configuration options to add_middleware.
Example of adding third-party middleware:
from fastapi import FastAPI
from starlette.middleware.httpsredirect import HTTPSRedirectMiddleware
app = FastAPI()
app.add_middleware(HTTPSRedirectMiddleware)
In this example, the HTTPSRedirectMiddleware ensures that all incoming requests are redirected to HTTPS, adding an extra layer of security to the API.
How do you run code after the response is sent in middleware?
Middleware in FastAPI runs before the response is sent, but you can also execute code after the response is sent by using an asynchronous context manager. This allows you to handle tasks such as logging or cleanup operations after the response has been returned to the client.
Example of running code after the response is sent:
from fastapi import FastAPI, Request
import time
app = FastAPI()
@app.middleware("http")
async def process_time_middleware(request: Request, call_next):
start_time = time.time()
response = await call_next(request)
process_time = time.time() - start_time
print(f"Request processed in {process_time} seconds")
return response
In this example, the middleware calculates the time it takes to process a request and logs the time after the response has been sent to the client.