Модель Pydantic в FastAPI
Pydantic — это основная зависимость FastAPI, используемая для проверки и сериализации данных. Она позволяет определять модели данных с помощью стандартных аннотаций типов Python, автоматически выполняя проверку данных, преобразование типов и создание документации.
Что такое Pydantic
Pydantic — это библиотека Python для проверки данных. Её основная философия:определяйте структуры данных с помощью аннотаций типов Python, а Pydantic автоматически выполняет проверку и преобразованиеВ FastAPI Pydantic в основном используется для:
| Назначение | Описание |
|---|---|
| Валидация тела запроса | Автоматически проверять, соответствуют ли JSON-данные, отправленные клиентами, определению модели |
| Сериализация тела ответа | Автоматически преобразовывать данные модели в JSON-ответы |
| Автоматическая документация | Поля модели, типы и правила валидации автоматически отображаются в документации API |
| Поддержка редактора | Атрибуты модели получают полное автодополнение в редакторе |
Определение моделей Pydantic
Создание наследованияBaseModelклассов, которые объявляют поля с использованием стандартных типов Python:
Пример
class Item(BaseModel):
name: str # Обязательно: название продукта
description: str | None = None # Необязательно: описание продукта
price: float # Обязательно: цена продукта
tax: float | None = None # Необязательно: налог
Является ли поле обязательным, зависит от того, есть ли у него значение по умолчанию:
| Fields | Способ объявления | Обязательно? |
|---|---|---|
name | name: str | Обязательный |
description | description: str | None = None | Optional |
price | price: float | Обязательный |
tax | tax: float | None = None | Optional |
Используйте модели Pydantic
В качестве тела запроса
Наиболее распространённый вариант использования — объявление модели в качестве параметра функции операции пути:
Пример
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
description: str | None = None
price: float
tax: float | None = None
@app.post("/items/")
async def create_item(item: Item):
# FastAPI автоматически проверяет тело запроса и после успешной проверки присваивает его параметру item
return item
Доступ к данным модели и работа с ними
Пример
async def create_item(item: Item):
# Доступ к атрибутам модели
print(item.name) # Прямой доступ к атрибутам
print(item.price) # Редактор обеспечивает автодополнение
# Сериализация в словарь
item_dict = item.model_dump()
print(item_dict) # {"name": "Foo", "description": None, "price": 45.2, "tax": None}
# Сериализация в строку JSON
item_json = item.model_dump_json()
print(item_json) # '{"name":"Foo","description":null,"price":45.2,"tax":null}'
return item_dict
Использование Pydantic v2
model_dump()иmodel_dump_json()Заменяет v1dict()иjson()метод. Новый метод имеет лучшую производительность (реализован на Rust под капотом).
Пример валидации модели
Когда данные, отправленные клиентом, не соответствуют определению модели, FastAPI возвращает подробные ошибки валидации:
Пример
POST /items/
{
"description": "отсутствуют имя и цена"
}
# Ошибка валидации ответа FastAPI
{
"detail": [
{
"type": "missing",
"loc": ["body", "name"],
"msg": "Обязательное поле",
"input": {"description": "отсутствуют имя и цена"}
},
{
"type": "missing",
"loc": ["body", "price"],
"msg": "Обязательное поле",
"input": {"description": "отсутствуют имя и цена"}
}
]
}
Если отправлены данные неверного типа:
// price 应该是数字,但传了字符串
{
"name": "Foo",
"price": "not a number"
}
// FastAPI 返回的错误
{
"detail": [
{
"type": "float_parsing",
"loc": ["body", "price"],
"msg": "Input should be a valid number, unable to parse string as a number",
"input": "not a number"
}
]
}
Общие методы Pydantic v2
| Методы | v2 (рекомендуется) | v1 (устарело) | Описание |
|---|---|---|---|
| Сериализация в словарь | item.model_dump() | item.dict() | Преобразование модели в словарь Python |
| Сериализация в JSON | item.model_dump_json() | item.json() | Преобразование модели в строку JSON |
| Создание из словаря | Item.model_validate(data) | Item.parse_obj(data) | Создание и проверка модели из словаря |
| Создание из JSON | Item.model_validate_json(json_str) | Item.parse_raw(json_str) | Создание модели из строки JSON |
| Получение JSON Schema | Item.model_json_schema() | Item.schema() | Получение JSON Schema модели |
Конфигурация модели (model_config)
Использование Pydantic v2model_configЗаменяет v1ConfigВнутренний класс:
Пример
class Item(BaseModel):
name: str
price: float
# Метод конфигурации Pydantic v2
model_config = ConfigDict(
json_schema_extra={ # Отображение примеров в документации API
"examples": [
{
"name": "Foo",
"price": 35.4
}
]
}
)
В Pydantic v2,
orm_mode = Trueизменено наfrom_attributes = True,schema_extraизменено наjson_schema_extra,allow_population_by_field_nameизменено наpopulate_by_name。
Наследование моделей
Модели Pydantic поддерживают наследование, что упрощает создание входных и выходных моделей:
Пример
# Базовая модель
class UserBase(BaseModel):
username: str # Обязательно
email: EmailStr # Обязательно, автоматически проверяет формат электронной почты
full_name: str | None = None # Необязательно
# Входная модель для создания пользователя (включая пароль)
class UserCreate(UserBase):
password: str # Обязательно
# Выходная модель для возврата информации о пользователе (не включает пароль)
class UserOut(UserBase):
id: int # Генерируется сервером
# Пример использования
@app.post("/users/", response_model=UserOut)
async def create_user(user: UserCreate):
# Функция получает UserCreate (с паролем), но ответ использует UserOut (без пароля)
# Таким образом, пароль не появится в ответе API.
return {"id": 1, **user.model_dump(exclude={"password"})}
Использование разных моделей ввода и вывода — важное средство защиты конфиденциальных данных. Никогда не возвращайте конфиденциальные поля, такие как пароли, в ответах API.
Итог
Ключевые моменты моделей Pydantic:
- Использование
BaseModelОпределяйте модели данных, объявляя поля стандартными типами Python - Поля со значениями по умолчанию необязательны, поля без значений по умолчанию обязательны
- использование v2
model_dump()、model_validate()и другие новые методы - Создавайте разные модели ввода/вывода с помощью наследования моделей для защиты конфиденциальных данных
- Вся валидация и документация автоматически — просто объявите типы один раз