You don't have access to this class

Keep learning! Join and start boosting your career

Aprovecha el precio especial y haz tu profesión a prueba de IA

Antes: $249

Currency
$209
Suscríbete

Termina en:

0 Días
3 Hrs
22 Min
6 Seg
Curso de FastAPI

Curso de FastAPI

Luis Martínez

Luis Martínez

Implementación y Uso de Middlewares en FastAPI

19/23
Resources

Middlewares in FastAPI are fundamental tools for modifying the behavior of requests in a centralized and efficient way. A middleware, in simple terms, is a function that runs before and after each request, allowing to intercept and extend the base functionality of an API without modifying each endpoint individually.

How do middlewares work in FastAPI?

A middleware captures each incoming request, processes some functionality, and then allows the flow to continue to the corresponding endpoint. FastAPI offers several predefined middlewares for common cases, but also allows you to create custom middlewares for specific needs.

How to implement a custom middleware in FastAPI?

To create a custom middleware, we can define an asynchronous function that records the processing time of each request. The steps are:

  • In the main.py file, where the application is defined, add a new function log_request_time.
  • This function receives two parameters:
    • request: The object that contains the request information.
    • call_next: A function that calls the next operation in the request chain.

The goal is to record the time before and after executing the request, and then calculate how long the whole process took.

Example code

import timefrom fastapi import FastAPI, Request app = FastAPI()@app.middleware("http")async def log_request_time(request: Request, call_next):start_time = time.time() # Initial request timeresponse = await call_next(request) # Call request functionalityprocess_time = time.time() - start_time # Calculate total processing time # Print URL and processing time in secondsprint(f"Request {request.url} completed in {process_time:.2f} seconds") return response

How to register the middleware in the application?

To register the middleware, it is necessary to use app.middleware and specify the type. In this case, we will use the http type so that it is executed with all HTTP requests.

  • Register log_request_time in the application with @app.middleware("http").
  • Import time at the beginning of the file to calculate startup and processing times.

How to interpret the middleware results?

When you run the application and make a request, the middleware prints the endpoint URL and the processing time in seconds to the console. This log helps to understand endpoint performance and identify potential bottlenecks.

What is the implementation challenge?

As a challenge, it is suggested to create an additional middleware that prints on the console all the headers sent in each request. This exercise allows to visualize the information of the headers and to better understand the structure of the requests.

Contributions 5

Questions 0

Sort by:

Want to see more contributions, questions and answers from the community?

Solución al reto: ```python @app.middleware("http") async def log_request_headers(request: Request, call_next): print("Request Headers:") for header, value in request.headers.items(): print(f"{header}: {value}") response = await call_next(request) return response ```
solucion:@app.middleware("http")async def log\_request\_headers(request: Request, call\_next):    response = await call\_next(request)        print(f"Request: {request.url} headers: {dict(request.headers)}")        return response ```js @app.middleware("http") async def log_request_headers(request: Request, call_next): response = await call_next(request) print(f"Request: {request.url} headers: {dict(request.headers)}") return response ```
Me gusta mas mantener segmentado el codigo y es mejor trabajar con la clase BaseHTTPMiddleware. Ejemplo: import time from fastapi import FastAPI, Request, Response, status from fastapi.responses import JSONResponse from starlette.middleware.base import BaseHTTPMiddleware class LogHandler(BaseHTTPMiddleware): def \_\_init\_\_(self, app: FastAPI) -> None: super().\_\_init\_\_(app) async def dispatch(self, request: Request, call\_next) -> Response | JSONResponse: try: start\_time = time.time() response = await call\_next(request) end\_time = time.time() process\_time = end\_time - start\_time print(f"Request: {request.url} complete in: {process\_time:.4f}") return response except Exception as error: return JSONResponse(status\_code=status.STATUS\_500, content={'error': str(error)}) Para registar el middlaware, seri solo: app.add\_middleware(LogHandler)
Mi solucion muy simple: @app.middleware("http")async def add\_process\_time\_header(request: Request, call\_next): print(request.headers) response = await call\_next(request) return response ```python @app.middleware("http") async def add_process_time_header(request: Request, call_next): print(request.headers) response = await call_next(request) return response ```
### **Implementación y Uso de Middlewares en FastAPI** En **FastAPI**, los *middlewares* son componentes que se ejecutan antes y después de que cada solicitud sea manejada por un endpoint. Son útiles para tareas como autenticación, registro de solicitudes, manejo de errores, compresión y más. ### **1. ¿Qué es un Middleware?** Un middleware es una función o clase que intercepta las solicitudes HTTP entrantes y las respuestas salientes. Esto permite realizar operaciones personalizadas, como: * Registrar logs de las solicitudes. * Verificar tokens de autenticación. * Modificar solicitudes o respuestas. ### **2. Crear un Middleware Básico** En FastAPI, los middlewares se implementan como clases que heredan de `BaseHTTPMiddleware` o se definen como funciones personalizadas. #### **Ejemplo básico: Registrar Logs** from fastapi import FastAPI, Request from starlette.middleware.base import BaseHTTPMiddleware app = FastAPI() class LogMiddleware(BaseHTTPMiddleware): async def dispatch(self, request: Request, call\_next): \# Antes de procesar la solicitud print(f"Request: {request.method} {request.url}") \# Procesar la solicitud response = await call\_next(request) \# Después de procesar la solicitud print(f"Response status: {response.status\_code}") return response \# Agregar el middleware a la aplicación app.add\_middleware(LogMiddleware) @app.get("/") async def read\_root(): return {"message": "Hello, World!"} ### **3. Uso de Middlewares Incorporados** FastAPI permite integrar middlewares ya existentes de **Starlette** o externos, como: * **CORS (Cross-Origin Resource Sharing):** Para permitir que dominios externos accedan a la API. * **GZipMiddleware:** Para comprimir respuestas grandes. #### **CORS Middleware** Permite configurar qué dominios pueden hacer solicitudes a tu API. from fastapi.middleware.cors import CORSMiddleware app = FastAPI() app.add\_middleware( CORSMiddleware, allow\_origins=\["https://example.com"], # Dominios permitidos allow\_credentials=True, allow\_methods=\["\*"], # Métodos permitidos (GET, POST, etc.) allow\_headers=\["\*"], # Encabezados permitidos ) @app.get("/") async def read\_root(): return {"message": "Hello, CORS!"} #### **GZip Middleware** Comprime las respuestas para mejorar el rendimiento. from starlette.middleware.gzip import GZipMiddleware app = FastAPI() app.add\_middleware(GZipMiddleware) @app.get("/") async def read\_root(): return {"message": "This response is compressed!"} ### **4. Middleware Personalizado con Validaciones** Supongamos que deseas validar un encabezado personalizado en cada solicitud. from fastapi import Request, HTTPException from starlette.middleware.base import BaseHTTPMiddleware class HeaderValidationMiddleware(BaseHTTPMiddleware): async def dispatch(self, request: Request, call\_next): if "x-custom-header" not in request.headers: raise HTTPException(status\_code=400, detail="Missing x-custom-header") \# Pasar al siguiente middleware o endpoint response = await call\_next(request) return response app = FastAPI() app.add\_middleware(HeaderValidationMiddleware) @app.get("/") async def read\_root(): return {"message": "Header is valid!"} ### **5. Orden de los Middlewares** El orden en el que los middlewares son añadidos es importante, ya que se ejecutan en secuencia. Por ejemplo: app.add\_middleware(MiddlewareA) app.add\_middleware(MiddlewareB) En este caso: 1. `MiddlewareA` se ejecuta primero al procesar la solicitud. 2. `MiddlewareB` se ejecuta después al procesar la solicitud. 3. Durante la respuesta, el orden es inverso: `MiddlewareB` → `MiddlewareA`. ### **6. Middleware vs. Dependencias** Aunque los middlewares son globales y afectan todas las solicitudes, las dependencias en FastAPI ofrecen una forma más granular de validar o modificar solicitudes por endpoint. Usa middlewares para tareas generales y dependencias para validaciones específicas. ### **7. Ejemplo Completo: Middleware de Tiempo de Ejecución** Calcula cuánto tiempo tarda cada solicitud en ser procesada. import time from fastapi import Request from starlette.middleware.base import BaseHTTPMiddleware class TimerMiddleware(BaseHTTPMiddleware): async def dispatch(self, 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) return response app = FastAPI() app.add\_middleware(TimerMiddleware) @app.get("/") async def read\_root(): return {"message": "Check the X-Process-Time header for timing info."} ### **Conclusión** Los middlewares en FastAPI son una herramienta poderosa para gestionar solicitudes y respuestas a nivel global. Puedes usarlos para optimizar tu API con tareas como autenticación, registro, compresión y validaciones. Asegúrate de combinarlos sabiamente con dependencias para una arquitectura eficiente.