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.