Навіть без додаткових налаштувань, Pydantic автоматично генерує повідомлення про помилки валідації. Це крута фішка, яка дозволяє зекономити час. Ось простий приклад:
from pydantic import BaseModel
class User(BaseModel):
name: str
age: int
# Намагаємося створити модель з некоректними даними
data = {"name": "Alice", "age": "not_a_number"}
try:
user = User(**data)
except Exception as e:
print(e)
Вивід:
1 validation error for User
age
value is not a valid integer (type=type_error.integer)
Як бачимо, помилка досить інформативна: ми одразу розуміємо, що поле age отримало недопустиме значення. Повідомлення включає в себе:
- Ім'я поля, яке спричинило помилку.
- Короткий опис помилки («не є цілим числом»).
- Тип помилки для подальшого аналізу (
type_error.integer).
Чому це корисно?
Такі повідомлення дозволяють швидко знаходити й виправляти помилки як під час розробки, так і при взаємодії з API. Pydantic обробляє навіть складні структури даних, даючи розробнику максимум ясності.
Навіщо кастомізувати повідомлення про помилки?
Хоча вбудовані повідомлення Pydantic чудово працюють «з коробки», іноді вони можуть бути занадто технічними для кінцевого користувача. Наприклад, замість повідомлення на кшталт «value is not a valid integer» користувачу краще показати щось на зразок: «Вік має бути числом». Це особливо важливо для застосунків, де взаємодіють не лише розробники, а й користувачі з різним рівнем технічної підготовки.
Як кастомізувати повідомлення про помилки?
Для налаштування користувацьких повідомлень у Pydantic використовується параметр Field з модуля pydantic.
Давайте створимо модель з використанням Field, де визначимо більш дружні повідомлення про помилки:
from pydantic import BaseModel, Field
class User(BaseModel):
name: str = Field(..., title="Ім'я користувача", max_length=20, description="Будь ласка, введіть ім'я довжиною до 20 символів.")
age: int = Field(..., gt=0, lt=130, description="Вік має бути числом від 1 до 129.")
# Намагаємося передати некоректні дані
data = {"name": "A very very long name that is not valid", "age": 200}
try:
user = User(**data)
except Exception as e:
print(e)
Вивід:
2 validation errors for User
name
ensure this value has at most 20 characters (type=value_error.any_str.max_length; limit_value=20)
age
ensure this value is less than 130 (type=value_error.number.not_lt; limit_value=130)
Зовсім інша річ! Ми задали обмеження (наприклад, максимум 20 символів для поля name або числовий діапазон для age), і Pydantic автоматично додав їх у опис помилок.
Кастомізація повідомлень через валідатори
Іноді потрібно задати настільки специфічні правила, що стандартні інструменти валідації не впораються. У таких випадках на допомогу приходить декоратор @validator або @field_validator.
Приклад з кастомним валідатором
from pydantic import BaseModel, Field, field_validator
class User(BaseModel):
name: str
age: int = Field(..., ge=18) # Можна одразу задати обмеження через Field
@field_validator("age")
@classmethod
def check_age(cls, value):
if value < 18:
raise ValueError("Вік повинен бути не менше 18.")
return value
# Намагаємося передати дані неповнолітнього
data = {"name": "John", "age": 16}
try:
user = User(**data)
except Exception as e:
print(e)
Вивід:
1 validation error for User
age
Вік повинен бути не менше 18. (type=value_error)
Тут ми створили повністю кастомне правило: для поля віку тепер можна задавати унікальну логіку, наприклад, перевірку на повноліття.
Практичний приклад: API з кастомними помилками
Давайте інтегруємо все в один эндпоінт FastAPI. Ми будемо обробляти запити на реєстрацію користувачів і покращувати зворотній зв'язок через кастомні помилки.
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel, Field, ValidationError
app = FastAPI()
class User(BaseModel):
name: str = Field(..., max_length=20, description="Ім'я має бути не довше 20 символів.")
age: int = Field(..., gt=0, lt=130, description="Вік має бути в діапазоні від 1 до 129.")
@app.post("/register")
async def register_user(user: User):
return {"message": f"Користувач {user.name} успішно зареєстрований!"}
# Запускаємо і пробуємо надіслати невірні дані через curl або Postman
Якщо передати некоректні дані, наприклад:
{
"name": "A very very long name that definitely will not pass validation",
"age": 150
}
Відповідь буде такою:
{
"detail": [
{
"loc": ["body", "name"],
"msg": "ensure this value has at most 20 characters",
"type": "value_error.any_str.max_length",
"ctx": {"limit_value": 20}
},
{
"loc": ["body", "age"],
"msg": "ensure this value is less than 130",
"type": "value_error.number.not_lt",
"ctx": {"limit_value": 130}
}
]
}
Глибоке налаштування користувацьких повідомлень
Якщо хочете мати максимальний контроль над обробкою помилок, можна перехоплювати виключення ValidationError і самостійно формувати відповіді.
from fastapi import FastAPI, Request
from pydantic import ValidationError
app = FastAPI()
@app.exception_handler(ValidationError)
async def validation_exception_handler(request: Request, exc: ValidationError):
return JSONResponse(
status_code=422,
content={"detail": "Некоректні дані. Перевірте введені дані!"}
)
Тепер усі валідаційні помилки будуть повертати єдине повідомлення "Некоректні дані. Перевірте введені дані!".
Підсумок
Ми навчилися працювати з вбудованими і кастомними повідомленнями про помилки Pydantic, що допоможе вам створювати більш дружні та зрозумілі додатки. Використовуйте Field, Config і кастомні валідатори, щоб поліпшити взаємодію з користувачами. Тепер ваші API не тільки потужні й зручні, а й дружні до людей — справжня мрія будь-якого розробника.
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ