Перейти к содержанию

Middleware (Служебные функции)

Вы можете добавлять служебные функции (middleware) в ваши FastAPI приложения.

"Middleware" это функция, которая выполняется с каждым запросом до его обработки функцией эндпоинта. А также с каждым ответом перед его возвращением.

  • Она берёт поступающий запрос
  • Делает что-то с этим запросом или выполняет некий нужный код.
  • Затем она передает запрос для последующей обработки в функцию эндпоинта
  • Получает ответ от функции эндпоинта
  • Что-то делает с этим ответом или выполняет некий нужный код
  • И возвращает ответ

Технические детали

Если у вас зависимости с yield, то код выхода (exit code) будет выполняться после middleware.

Если у вас выполняются некие фоновые задачи (см. документацию), то они будут запущены после middleware.

Создание middleware

Для создания middleware используйте декоратор @app.middleware("http").

Функция middleware получает:

  • request (объект запроса).
  • Функцию call_next, которая получает request в качестве параметра.
    • Эта функция передаёт request соответствующей функции эндпоинта.
    • Затем она возвращает ответ response, сгенерированный функцией эндпоинта.
  • Также имеется возможность обработать response перед тем как его вернуть.
import time

from fastapi import FastAPI, Request

app = FastAPI()


@app.middleware("http")
async def add_process_time_header(request: Request, call_next):
    start_time = time.perf_counter()
    response = await call_next(request)
    process_time = time.perf_counter() - start_time
    response.headers["X-Process-Time"] = str(process_time)
    return response

Подсказка

Имейте в виду, что можно добавлять свои собственные заголовки с 'X-' префиксом.

Если же вы хотите добавить собственные заголовки, которые клиент сможет увидеть в браузере, то вам потребуется добавить их в настройки CORS (CORS (Cross-Origin Resource Sharing)), используя параметр expose_headers`, см. документацию Starlette's CORS docs.

Технические Детали

Вы можете также использовать from starlette.requests import Request.

FastAPI предоставляет такой доступ для удобства разработчиков. Но это из Starlette.

До и после response

Вы можете добавить код, который будет использовать request, до передачи его функции эндпоинта.

А также после генерации response, до того, как вы его вернёте.

Например, вы можете добавить собственный заголовок X-Process-Time, содержащий время в секундах необходимое для обработки запроса и генерации ответа:

import time

from fastapi import FastAPI, Request

app = FastAPI()


@app.middleware("http")
async def add_process_time_header(request: Request, call_next):
    start_time = time.perf_counter()
    response = await call_next(request)
    process_time = time.perf_counter() - start_time
    response.headers["X-Process-Time"] = str(process_time)
    return response

Подсказка

Мы используем time.perf_counter() вместо time.time() для обеспечения большей точности наших примеров. 🤓

Другие middleware

Вы можете узнать больше о других middleware в разделе Advanced User Guide: Advanced Middleware.

В следующем разделе вы можете прочитать как работать с CORS middleware.