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

Middleware (Промежуточный слой)

Вы можете добавить промежуточный слой (middleware) в FastAPI приложение.

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

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

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

Если у вас есть зависимости с yield, то код выхода (код после yield) будет выполняться после 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 предоставляет такой доступ для удобства разработчиков. Но, на самом деле, это Request из 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.