Ответ
FastAPI, построенный на ASGI-фреймворке Starlette и библиотеке Pydantic, обрабатывает запросы в несколько четких и высокопроизводительных этапов.
Жизненный цикл запроса:
-
Маршрутизация (Routing)
- Starlette получает входящий HTTP-запрос.
- Он сопоставляет HTTP-метод (GET, POST и т.д.) и путь запроса (например,
/items/1) с соответствующей функцией-обработчиком (path operation function), определенной с помощью декоратора (@app.get("/items/{item_id}")).
-
Извлечение и Валидация (Parsing & Validation)
- FastAPI использует Pydantic для автоматического парсинга, приведения типов и валидации данных.
- Данные извлекаются из пути, query-параметров, заголовков, cookie и тела запроса.
- Если данные не соответствуют аннотациям типов или валидаторам в модели Pydantic, FastAPI автоматически прерывает цикл и возвращает клиенту ошибку
422 Unprocessable Entityс подробным JSON-описанием проблемы.
-
Обработка Зависимостей (Dependency Injection)
- FastAPI выполняет все зависимости, указанные для эндпоинта с помощью
Depends. - Это может включать проверку аутентификации, получение сессии базы данных или выполнение другого общего кода.
- Результаты выполнения зависимостей передаются в функцию-обработчик в качестве аргументов.
- FastAPI выполняет все зависимости, указанные для эндпоинта с помощью
-
Выполнение Кода Эндпоинта (Path Operation Execution)
- Вызывается сама функция-обработчик с уже валидированными данными и результатами работы зависимостей.
- FastAPI эффективно обрабатывает как асинхронные (
async def), так и синхронные (def) функции. Синхронные функции выполняются в отдельном пуле потоков, чтобы не блокировать основной цикл событий (event loop).
-
Формирование Ответа (Response Generation)
- Результат, возвращаемый функцией, сериализуется (обычно в JSON).
- FastAPI упаковывает данные в HTTP-ответ с соответствующим статус-кодом, заголовками и телом.
Пример с валидацией:
from fastapi import FastAPI
from pydantic import BaseModel, Field
app = FastAPI()
class Item(BaseModel):
name: str
price: float = Field(..., gt=0) # Цена должна быть больше нуля
@app.post("/items/")
async def create_item(item: Item):
# Этот код выполнится только если 'item' пройдет валидацию Pydantic
return {"status": "success", "item": item}
Если отправить POST-запрос с {"name": "Apple", "price": -1}, FastAPI автоматически вернет ошибку 422 еще до вызова функции create_item.
Ответ 18+ 🔞
А, слушай, вот эта FastAPI штука, блядь! Ну реально, как она там внутри работает, а? Сижу, думаю, э бошка, думай. А там, оказывается, всё по полочкам, чётко, как у хорошего столяра, блядь.
Представь, прилетает к тебе запрос, типа «дай мне там че-нибудь». И начинается, сука, целый спектакль, ёперный театр!
Вот как оно там, в этой кухне, происходит:
-
Маршрутизация, блядь (Routing) Starlette, этот основательный чувак, хватает входящий запрос и начинает его шарить. «Ты куда, сука? На
/items/1? И метод у тебя GET? Ага, ща, я знаю, кто за это отвечает!» — и находит нужную функцию, которую ты обвешал декораторами, как ёлку,@app.get("/items/{item_id}"). -
Разбор и проверка, а то вдруг хуйню прислали (Parsing & Validation) А вот тут выходит на сцену Pydantic, наш главный зануда и педант, ядрёна вошь! Он берёт все данные — из пути запроса, из этих query-параметров, из заголовков, из тела — и начинает их щупать. «Так-так, — говорит, — тут у нас
priceдолжен бытьfloatи больше нуля, а ты мне что подсовываешь, минус один? Да иди ты нахуй!» И если что не так — бац! — цикл прерывается, и клиенту летит ответ422 Unprocessable Entityс таким подробным описанием ошибки, что хоть плачь. Функция-обработчик даже пальцем не пошевелит, пока Pydantic не скажет «ок». -
Впрыскивание зависимостей, или «дай-ка я тебе помогу» (Dependency Injection) Тут FastAPI такой: «О, я вижу, у тебя в аргументах функции есть
Depends. Ну-ка, давай выполним всё, что там нужно — проверим авторизацию, подключимся к базе, чаю, блядь, приготовим». И результаты этой всей движухи аккуратно подсовывает в твою функцию. Удобно, сука! -
Ну наконец-то, работа! (Path Operation Execution) Вот теперь вызывается твоя родная функция-обработчик. Все данные уже проверены, зависимости готовы — работай, не хочу! И неважно, асинхронная она (
async def) или обычная (def) — FastAPI разберётся, куда её затолкать, чтобы не заблокировать главный цикл. -
Упаковка и отправка (Response Generation) Функция что-то там посчитала, вернула результат. FastAPI берёт это, сериализует в JSON (чаще всего), красиво упаковывает в HTTP-ответ со статусом, заголовками — и отсылает обратно, как горячую пиццу.
Смотри, вот живой пример, где Pydantic свою власть показывает:
from fastapi import FastAPI
from pydantic import BaseModel, Field
app = FastAPI()
class Item(BaseModel):
name: str
price: float = Field(..., gt=0) # Цена, блядь, должна быть больше нуля!
@app.post("/items/")
async def create_item(item: Item):
# А этот код выполнится ТОЛЬКО если 'item' пройдёт валидацию нашего зануды Pydantic.
return {"status": "success", "item": item}
Представь, какой-то умник пришлёт {"name": "Apple", "price": -1}. Pydantic посмотрит на это, ебалом заморгает и скажет: «Цена больше нуля, мудила, написано же!». И функция create_item даже не проснётся — сразу в ответе будет ошибка 422. Красота, блядь! Всё автоматически, волнение ебать — ноль.