Ось готовий урок, створений спеціально за твоїм запитом, у стилі енергійних лекцій CS50.
🎓 Урок: Request body та Pydantic-моделі
Привіт, світ! 👋 Мене звати [Твоє Ім'я], і сьогодні ми зануримось у серце сучасної веб-розробки на Python (FastAPI).
Ми вже вміємо передавати прості дані через URL (пам’ятаєте query-параметри? ?id=5&q=search). Але що, якщо нам потрібно передати щось більше? Щось складніше?
1. 🔥 Вступ: Проблема та мотивація
Уявіть, що ви замовляєте піцу онлайн. 🍕
Якщо використовувати лише URL-параметри (те, що йде після знаку питання), ваше посилання виглядало б як жахливий монстр:
my-pizza.com/order?type=pepperoni&size=large&crust=thin&extra_cheese=true&address=Kyiv_Khreschatyk_1&comment=do_not_ring_doorbell...
А тепер уявіть, що ви реєструєте користувача. Ви справді хочете передавати пароль прямо в адресному рядку, де його побачить будь-хто, хто стоїть за вашою спиною, або збереже історія браузера? 😱 Звісно, ні! Це небезпечно, незручно і непрофесійно.
Риторичне запитання: Як нам передати "пакет" даних (об'єкт, структуру, цілий документ) так, щоб це було безпечно, зручно і, головне, щоб сервер зрозумів, що ми йому надіслали?
Аналогія з поштою: 📮 * Query params (URL) — це написи на конверті. Їх бачать усі, там мало місця. * Request Body (Тіло запиту) — це лист всередині конверта. Там може бути багато сторінок, фотографії, структурований текст. І це приховано від сторонніх очей (особливо з HTTPS).
Але тут виникає проблема. Якщо хтось надішле вам у конверті не лист, а, скажімо, цеглу? Або лист китайською мовою, яку ви не знаєте? Ваш сервер (як і ви) просто "зламається".
Ось тут на сцену виходить Pydantic. Це ваш особистий охоронець-перекладач, який перевіряє вміст конверта ще до того, як він потрапить до вас на стіл.
2. 🧠 Теоретична база (без нудних лекцій)
Давайте розберемося, що відбувається "під капотом".
Що таке Request Body?
Це дані, які кліент (браузер, мобільний додаток) відправляє API. Зазвичай у форматі JSON (JavaScript Object Notation). Це стандарт де-факто.
Він виглядає як словник у Python: {"name": "Ivan", "age": 25}.
Що таке Pydantic?
Це бібліотека Python, яка робить одну річ геніально: Data Validation (валідацію даних).
Коли FastAPI отримує запит: 1. Він бере JSON. 2. Передає його Pydantic-моделі (яку ми створимо). 3. Pydantic каже: "Ага, тут має бути число, а тут рядок". 4. Якщо все ок — він перетворює JSON у зручний Python-об'єкт. 5. Якщо ні — він автоматично "відшиває" клієнта з чіткою помилкою.
📌 Що треба запам'ятати залізно:
- Ми створюємо класи, які наслідуються від
BaseModel. - Ми використовуємо Type Hints (підказки типів:
str,int,bool), щоб задати правила.
3. 🧪 Приклади: Від "Hello" до Pro
Приклад 1: Мінімальний (Рівень "Новачок")
Створимо модель товару. Нам потрібна назва і ціна.
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
# 1. Описуємо "форму" наших даних
class Item(BaseModel):
name: str
price: float
# 2. Використовуємо це в ендпоінті
@app.post("/items/")
async def create_item(item: Item):
# Тут item — це вже не просто JSON, це об'єкт Python!
return {"message": f"Товар {item.name} створено з ціною {item.price}"}
👀 Запитання до вас: Що станеться, якщо я надішлю такий JSON: {"name": "Laptop", "price": "дорого"}?
.
.
.
Відповідь: Pydantic викине помилку! Тому що "дорого" — це str, а ми вимагали float. Він захищає ваш код від падіння.
Приклад 2: Реальний світ (Рівень "Junior")
У реальності деякі поля обов'язкові, а деякі — ні. Давайте додамо опис товару, якого може і не бути, та податок.
from typing import Optional
class Product(BaseModel):
name: str
description: str | None = None # Опціональне поле (Python 3.10+)
price: float
tax: float = 10.5 # Значення за замовчуванням
@app.post("/products/")
async def create_product(product: Product):
total_price = product.price + product.tax
return {
"product": product.name,
"final_price": total_price,
"desc": product.description
}
Тут магія Pydantic в дії:
* Якщо клієнт не надішле tax, Pydantic сам підставить 10.5.
* Якщо не надішле description, там буде None.
* Але якщо не надішле price — буде помилка, бо це поле обов'язкове!
4. 🛠 Практична частина
Прийшов час бруднити руки кодом! Відкривайте редактор.
Завдання 1: Реєстрація
Створіть модель User, яка має:
* username (рядок)
* email (рядок)
* age (ціле число)
Напишіть ендпоінт POST /users/, який приймає цю модель і повертає повідомлення: "Користувач [username] зареєстрований".
Завдання 2: "А ти повнолітній?"
Додайте логіку в ендпоінт із Завдання 1. Якщо age менше 18, повертайте JSON {"error": "Вам сюди не можна"}. (Підказка: використовуйте звичайний if всередині функції).
Завдання 3: Робота над помилками
Запустіть код. Спробуйте надіслати в age дробове число (наприклад, 25.5). Що зробив Pydantic? (Він спробував округлити чи видав помилку? Перевірте!).
Завдання 4: Міні-кейс "Блог"
Створіть модель BlogPost:
* title
* content
* published (булеве значення, за замовчуванням True).
Зробіть так, щоб при створенні поста ви повертали кількість слів у content.
Челлендж "А що, якщо..."
Що, якщо в моделі ми хочемо передати список тегів (наприклад, ["news", "tech"])?
Спробуйте здогадатися, як це описати в Pydantic, використовуючи list або list[str].
5. 💡 Мислення як у розробника
Як думає досвідчений інженер, коли працює з моделями?
-
"Не довіряй нікому". Новачок думає: "Я ж роблю фронтенд, я точно надішлю правильні дані". Профі знає: "Фронтенд можна обійти через Postman або
curl. Валідація на бекенді (Pydantic) — це єдиний захист". -
Розділяй та володарюй. Не пишіть валідацію вручну (
if "name" in data...). Це "спагетті-код". Винесіть це в Pydantic-модель. Ваш код функції має займатися бізнес-логікою (збереженням у БД, обробкою), а не перевіркою типів. -
Автодоповнення — це суперсила. 🦸♂️ Оскільки ви описали типи в класі
class Item(BaseModel), ваша IDE (VS Code, PyCharm) буде підказувати вам поля через крапку:item.nam...->item.name. Це економить години пошуку одруківок!
6. 🧩 Підсумок
Сьогодні ми зробили величезний крок вперед.
- Ми відмовилися від хаосу в URL.
- Ми навчилися передавати складні об'єкти через Request Body.
- Ми найняли Pydantic працювати нашим "фейс-контролем".
Що ви тепер вмієте? Ви можете створити API, яке приймає дані реєстрації, замовлення товарів, створення постів — будь-що, що вимагає введення даних користувачем. І ви робите це безпечно!
🔜 Тизер наступного уроку: Зараз ми просто повертаємо дані назад користувачу. Але це трохи безглуздо, правда? У наступному уроці ми дізнаємося, як зберегти ці дані назавжди, підключивши справжню базу даних!
А поки — код сам себе не напише. Успіхів! 💻🚀