Ну що ж, настав час вивчити потужний інструмент валідації даних — Pydantic.
Навіщо він потрібен? Давай розберемося.
Коли ми працюємо з даними, будь то вхідні запити від користувача або відповіді від твого API, важливо бути впевненим у їх коректності. Уяви, що твій API отримує JSON з "ім'я користувача" як число замість рядка. Або, наприклад, обробка "віку" у вигляді рядка "двадцять" спричинить падіння системи. Такі помилки можуть приводити до несподіваних багів, ламати код і створювати хаос.
Ось тут на арену виходить Pydantic. Він дбає про валідацію даних і їх перетворення. Pydantic дозволяє:
- Автоматично перевіряти вхідні дані.
- Гарантувати коректні типи даних.
- Створювати зрозумілі повідомлення про помилки, якщо дані некоректні.
- Обробляти складні структури даних, такі як вкладені JSON.
Pydantic — це бібліотека для роботи з даними, яку використовують у FastAPI для валідації запитів і відповідей. Він як строгий, але дбайливий вчитель: перевіряє кожен рядок даних, приводить їх до правильних типів, а якщо щось не так — каже про це простими словами.
Основні можливості Pydantic
- Простота створення моделей
Pydantic дозволяє визначати моделі даних (або схеми) з використанням анотацій типів Python. Так, тих самих
int,str,List,Dictі т.д.Це робиться за допомогою класів, які наслідуються від
pydantic.BaseModel.from pydantic import BaseModel class User(BaseModel): id: int name: str is_active: boolЩо тут відбувається?
- Ми створили модель
User. - Поля
id,name,is_activeпредставляють дані, які ми очікуємо. - Анотації типів (
int,str,bool) вказують, якого типу дані мають приходити.
Це як написати паспорт для даних: у кожного є своє суворе місце і суворе типове відповідність.
- Ми створили модель
- Автоматична валідація даних
Коли Pydantic стикається з твоїми даними, він автоматично перевіряє їх відповідність заявленим типам і перетворює, якщо це можливо.
Приклад перевірки:
user_data = {"id": "123", "name": "Alice", "is_active": "true"} user = User(**user_data) print(user) # Користувач перетворюється на: id=123, name='Alice', is_active=TruePydantic спокійно приводить рядок
"123"до числа, а"true"до булевого значенняTrue.Але якщо надійдуть некоректні дані, наприклад,
"id": "abc", буде кинуто виключення з детальним повідомленням про помилку. - Підтримка складних структур даних
Ти можеш визначати вкладені моделі для роботи зі складнішими даними.
from typing import List class Order(BaseModel): order_id: int product_name: str quantity: int class Customer(BaseModel): id: int name: str orders: List[Order]JSON, що відповідає цим моделям:
{ "id": 1, "name": "John", "orders": [ {"order_id": 101, "product_name": "Laptop", "quantity": 1}, {"order_id": 102, "product_name": "Mouse", "quantity": 2} ] } - Зрозумілі повідомлення про помилки
Pydantic дає подробні й зрозумілі повідомлення про помилки. Подивимось приклад:
invalid_user_data = {"id": "abc", "name": 123, "is_active": "yes"} user = User(**invalid_user_data)Побачиш щось на кшталт:
pydantic.error_wrappers.ValidationError: 2 validation errors for User id value is not a valid integer (type=type_error.integer) name str type expected (type=type_error.str)Повідомлення досить інформативні, щоб швидко зрозуміти, де помилка.
- Підтримка значень за замовчуванням
Pydantic підтримує значення за замовчуванням для полів, що дозволяє спростити обробку даних.
class Product(BaseModel): name: str price: float = 0.0 # За замовчуванням ціна товару — 0.0Якщо поле
priceвідсутнє в запиті, Pydantic просто використовує значення за замовчуванням. - Документація з коробки
FastAPI автоматично інтегрує Pydantic-моделі в OpenAPI-документацію.
Коли ти створюєш Pydantic-модель і використовуєш її в своїх ендпоінтах, ця модель стає частиною документації твого API.
from fastapi import FastAPI app = FastAPI() class User(BaseModel): id: int name: str is_active: bool @app.post("/user/") async def create_user(user: User): return userЗайди в свій Swagger UI (
http://127.0.0.1:8000/docs), і ти побачиш, як FastAPI автоматично додав опис моделіUserв документацію. - Простота кастомізації
Хочеш задати конкретну поведінку для поля або повідомлення про помилку? Без проблем! Використовуй
pydantic.Field.from pydantic import BaseModel, Field class Product(BaseModel): name: str = Field(max_length=50, description="Ім'я товару") price: float = Field(gt=0, description="Ціна повинна бути більше 0")Це не тільки валідовує дані (наприклад, перевіряє, що ціна більше нуля), але й додає опис для документації.
Чому Pydantic важливий у FastAPI
FastAPI інтегрував Pydantic глибоко в свою основу. Починаючи від валідації запитів і закінчуючи перевіркою даних у відповідях — уся магія відбувається завдяки Pydantic. Використання Pydantic спрощує розробку, підвищує надійність і зменшує ймовірність багів.
Уяви, що раніше тобі доводилося явно перевіряти кожне значення типу "якщо це число", "якщо рядок довжиною не більше 10 символів". Тепер ти просто описуєш модель, і Pydantic усе робить за тебе.
Практичне завдання
Тепер твоя черга! Створи Pydantic-модель для наступного JSON:
{
"username": "fastapi_user",
"age": 25,
"email": "user@example.com",
"is_premium": true
}
Додай валідацію:
- Поле age має бути більше або рівне 18.
- Поле email має бути валідною електронною адресою.
- Поле is_premium — опціонально, за замовчуванням має бути False.
Спробуй інтегрувати цю модель в ендпоінт FastAPI і протестуй її з різними вхідними даними.
from typing import Optional
from fastapi import FastAPI
from pydantic import BaseModel, EmailStr, Field
app = FastAPI()
class User(BaseModel):
username: str
age: int = Field(ge=18)
email: EmailStr
is_premium: bool | None = False
@app.post("/users/")
async def create_user(user: User):
return user
POST /users/
{
"username": "johndoe",
"age": 17,
"email": "notanemail"
}
Побачимось на наступній лекції, де ми заглибимось у створення моделей з Pydantic і будемо валідовувати дані на практиці! 🚀
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ