Ответ
Middleware (промежуточное ПО) в FastAPI — это функция, которая обрабатывает каждый входящий запрос перед тем, как он достигнет обработчика пути, и каждый исходящий ответ перед его отправкой клиенту.
Оно используется для сквозной функциональности, применяемой ко многим или всем эндпоинтам. Основная польза — вынесение общей логики из обработчиков, что делает код чище и позволяет избежать дублирования.
Основные сценарии использования:
- Логирование: запись информации о каждом запросе и ответе.
- Аутентификация: проверка токенов или сессий.
- Обработка CORS: добавление необходимых заголовков.
- Измерение времени выполнения: отслеживание производительности запросов.
- Обработка ошибок: централизованный перехват исключений.
Пример middleware для логирования:
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.time()
# Передача запроса следующему middleware или обработчику пути
response = await call_next(request)
# Код, который выполняется после обработки запроса
process_time = time.time() - start_time
response.headers["X-Process-Time"] = str(process_time)
print(f"Запрос {request.method} {request.url.path} выполнен за {process_time:.4f} сек")
return response
@app.get("/")
async def root():
return {"message": "Hello World"}
В этом примере call_next(request) — это вызов следующего звена в цепочке обработки. Все, что находится до этого вызова, выполняется на пути "внутрь" приложения, а все, что после, — на пути "наружу".
Ответ 18+ 🔞
А, слушай, про middleware в FastAPI! Это же, блядь, как швейцар в дорогом отеле, только для твоего кода, понимаешь? Он стоит на пороге каждого запроса и говорит: "Стой, мудила, куда прешь? Сначала через меня пройди!"
Ну, если по-человечьи, то это такая функция-надзиратель, которая ловит каждый входящий запрос, ещё до того как он доползёт до твоего основного обработчика-роута. И обратно, когда ответ уже готов, она его тоже по головке гладит перед отправкой. Польза-то какая? Овердохуищная! Всякую общую, сквозную хуйню в одно место засунуть, чтобы не копипастить одно и то же в каждом эндпоинте.
Где это, блядь, пригождается? Да везде!
- Логирование: Чтобы записывать, кто, когда и с каким запросом приходил. А то потом, когда всё ебнется, будешь как дурак в потолок плевать — "а что, сука, случилось-то?"
- Аутентификация: Проверка, а свой ли это человек стучится, или левый пидор с улицы. Токены там всякие, сессии.
- CORS: Ну, это чтобы браузеры не орали "ой, ой, не могу!" когда твой фронтенд с другого домена стучится.
- Замер времени: Посмотреть, не тормозит ли какой-нибудь запрос, как черепаха в сиропе.
- Обработка ошибок: Чтобы не размазывать
try...exceptпо всему коду, а ловить всё в одном месте. Красота, ёпта!
Вот, смотри, пример middleware для логирования, простой как три копейки:
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.time()
# А это — магическая палочка! Передаём запрос дальше по цепочке
response = await call_next(request)
# А тут мы уже ПОСЛЕ того, как запрос обработали, ловим ответ
process_time = time.time() - start_time
response.headers["X-Process-Time"] = str(process_time)
print(f"Запрос {request.method} {request.url.path} выполнен за {process_time:.4f} сек")
return response
@app.get("/")
async def root():
return {"message": "Hello World"}
Видишь, в чём фокус? Вся магия вокруг этого call_next(request). Всё, что до него — это как раз путь запроса внутрь приложения. А всё, что после — это уже он, бедолага, вылезает обратно с ответом. И ты его в этот момент ещё и по головке погладить можешь, заголовки ему навешать. Удобно же, блядь! В рот меня чих-пых, гениальная просто штука.