POST-запросы и Pydantic
Принимаем и проверяем данные от клиента.
Бытовая аналогия: бланк на паспортном контроле
Когда вы заполняете бланк (анкету) на границе, в нём заранее указано: «Имя — буквами», «Возраст — числом», «Email — необязательно». Сотрудник не пропустит бланк, где в графе «возраст» написано «двадцать пять» словами.
Pydantic-модель — это и есть такой бланк. Вы описываете, какие поля нужны и какого они типа, а FastAPI берёт на себя роль строгого пограничника: проверяет каждый присланный JSON и сам отклоняет неправильный, не пуская «битые» данные в вашу логику.
Pydantic — модели данных
Чтобы принимать данные (например, нового пользователя), описывают модель — классШаблон для создания объектов: описывает их данные (атрибуты) и поведение (методы). с типами полей. FastAPI сам проверит, что клиент прислал корректные данные, иначе вернёт понятную ошибку.
Модель — это знакомый вам класс, унаследованный от BaseModel (вспомните модуль про ООП и @dataclass — идея та же).
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
# модель входных данных
class User(BaseModel):
name: str
age: int
email: str = "" # необязательное поле со значением по умолчанию
@app.post("/users")
def create_user(user: User): # FastAPI разберёт JSON в объект User
return {
"message": f"Создан пользователь {user.name}",
"age": user.age
}🔮 Предскажите вывод
Главное, что делает Pydantic — приводит и проверяет типы. Ниже упрощённая «ручная» версия того же на чистом Python. Что выведет код?
Разбор. Клиент прислал возраст строкой "25". int("25") превращает её в число 25, поэтому age + 1 даёт 26, и вывод — Виктор, через год будет 26. Pydantic делает такое приведение и проверку автоматически: если бы пришло "двадцать", он вернул бы клиенту ошибку 422.
Как это работает
Клиент шлёт POST-запрос с JSON-телом:
{
"name": "Виктор",
"age": 25
}FastAPI автоматически:
- разберёт JSON и превратит его в объектКонкретный экземпляр класса — со своими данными. Почти всё в Python является объектом.
User; - проверит, что
name— строкаТекстовое значение в кавычках: "привет". Неизменяема. По-английски string (str)., аage— число; - если данные неверные — сам вернёт ошибку
422с описанием, что не так.
Мини-приложение: список задач
Соберём всё вместе — крошечный REST API для спискаИзменяемая упорядоченная коллекция элементов: [1, 2, 3]. По-английски list. дел (хранение в памяти):
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
app = FastAPI()
todos = [] # хранилище в памяти
class Todo(BaseModel):
title: str
done: bool = False
@app.get("/todos") # получить все задачи
def list_todos():
return todos
@app.post("/todos") # добавить задачу
def add_todo(todo: Todo):
todos.append(todo.dict())
return {"added": todo.title, "total": len(todos)}
@app.get("/todos/{index}") # получить одну по номеру
def get_todo(index: int):
if index < 0 or index >= len(todos):
raise HTTPException(status_code=404, detail="Задача не найдена")
return todos[index]Запустите этот файл (uvicorn todo_api:app --reload), откройте /docs и потыкайте кнопки: создайте пару задач через POST, затем получите их списком через GET. Вы только что написали настоящий backend-сервис.
Сейчас задачи хранятся в списке в памяти и пропадают при перезапуске. В реальных приложениях их сохраняют в базу данных (PostgreSQL, SQLite) — это ваш следующий шаг в изучении backend-разработки.
⚠️ Частые ошибки новичков
- Забывают аннотацию типа у параметра-тела. Если написать
def create_user(user):без: User, FastAPI не поймёт, что это тело запроса. - Шлют POST без тела. Эндпоинт ждёт JSON с полями модели — пустой запрос вернёт
422со списком недостающих полей. - Возвращают объект модели и удивляются. Лучше вернуть
dict(илиtodo.dict()) — FastAPI сериализует его в JSON.
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class User(BaseModel):
name: str
age: int
# ❌ нет аннотации : User — FastAPI ждёт name и age как query-параметры
@app.post("/users")
def create_user(user):
return {"ok": user.name} # AttributeError: '?' has no attribute
# ✅ правильно:
# def create_user(user: User):
# return {"ok": user.name}✅ Что вы узнали
- Pydantic-модель (класс от
BaseModel) описывает структуру и типы входных данных. - Декоратор
@app.post(...)с параметромuser: Userпринимает JSON-тело и проверяет его. - При неверных данных FastAPI сам возвращает 422; для «не найдено» используют
HTTPException(404). - Из таких эндпоинтов собирается настоящий backend-сервис (CRUD для списка задач).
Комментарии
Загрузка…
Загрузка комментариев…