JavaRush /Курси /Модуль 4: FastAPI /Що таке Pydantic: основні можливості

Що таке Pydantic: основні можливості

Модуль 4: FastAPI
Рівень 3 , Лекція 0
Відкрита

Ну що ж, настав час вивчити потужний інструмент валідації даних — Pydantic.

Навіщо він потрібен? Давай розберемося.

Коли ми працюємо з даними, будь то вхідні запити від користувача або відповіді від твого API, важливо бути впевненим у їх коректності. Уяви, що твій API отримує JSON з "ім'я користувача" як число замість рядка. Або, наприклад, обробка "віку" у вигляді рядка "двадцять" спричинить падіння системи. Такі помилки можуть приводити до несподіваних багів, ламати код і створювати хаос.

Ось тут на арену виходить Pydantic. Він дбає про валідацію даних і їх перетворення. Pydantic дозволяє:

  • Автоматично перевіряти вхідні дані.
  • Гарантувати коректні типи даних.
  • Створювати зрозумілі повідомлення про помилки, якщо дані некоректні.
  • Обробляти складні структури даних, такі як вкладені JSON.

Pydantic — це бібліотека для роботи з даними, яку використовують у FastAPI для валідації запитів і відповідей. Він як строгий, але дбайливий вчитель: перевіряє кожен рядок даних, приводить їх до правильних типів, а якщо щось не так — каже про це простими словами.


Основні можливості Pydantic

  1. Простота створення моделей

    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) вказують, якого типу дані мають приходити.

    Це як написати паспорт для даних: у кожного є своє суворе місце і суворе типове відповідність.

  2. Автоматична валідація даних

    Коли Pydantic стикається з твоїми даними, він автоматично перевіряє їх відповідність заявленим типам і перетворює, якщо це можливо.

    Приклад перевірки:

    
    user_data = {"id": "123", "name": "Alice", "is_active": "true"}
    
    user = User(**user_data)
    print(user)
    # Користувач перетворюється на: id=123, name='Alice', is_active=True
        

    Pydantic спокійно приводить рядок "123" до числа, а "true" до булевого значення True.

    Але якщо надійдуть некоректні дані, наприклад, "id": "abc", буде кинуто виключення з детальним повідомленням про помилку.

  3. Підтримка складних структур даних

    Ти можеш визначати вкладені моделі для роботи зі складнішими даними.

    
    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}
      ]
    }
        
  4. Зрозумілі повідомлення про помилки

    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)
        

    Повідомлення досить інформативні, щоб швидко зрозуміти, де помилка.

  5. Підтримка значень за замовчуванням

    Pydantic підтримує значення за замовчуванням для полів, що дозволяє спростити обробку даних.

    
    class Product(BaseModel):
        name: str
        price: float = 0.0  # За замовчуванням ціна товару — 0.0
        

    Якщо поле price відсутнє в запиті, Pydantic просто використовує значення за замовчуванням.

  6. Документація з коробки

    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 в документацію.

  7. Простота кастомізації

    Хочеш задати конкретну поведінку для поля або повідомлення про помилку? Без проблем! Використовуй 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 і будемо валідовувати дані на практиці! 🚀

Коментарі
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ