/
olevok
/
python-dev-course
Обзор
Документация
Войти
/
olevok
/
python-dev-course
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
Part 8 - FastAPI/L15/L15_3/main.py
155 строк
5 KB
PetrovSerega
Update L15
17 июн 2026, 17:09
17 июн 2026, 17:09
dc687cf
Код
Авторство
О чём код?
# uvicorn L15_3.main:app --reload # В VS Code комментарии с region + endregion используются для группировки кода # Свернуть все регионы и функции: Ctrl + K, затем Ctrl + 0 (ноль). # Развернуть все: Ctrl + K, затем Ctrl + J. from fastapi import FastAPI from pydantic import BaseModel app = FastAPI() # region Тело запроса: модели Pydantic. Пример 1: Простая модель для создания книги class Book(BaseModel): title: str author: str price: float @app.post("/books") async def create_book(book: Book): # book — это объект Python с полями title, author, price return {"message": f"Книга '{book.title}' добавлена", "price": book.price} # endregion # region Тело запроса: модели Pydantic. Пример 2: Использование модели в PUT-запросе @app.put("/books/{book_id}") async def update_book(book_id: int, book: Book): return {"book_id": book_id, "updated": book.title} # endregion # region Валидация данных. Пример 1: Ограничения на поля с помощью Field from pydantic import BaseModel, Field class Product(BaseModel): # min_length и max_length ограничивают количество символов в строке name: str = Field(min_length=3, max_length=50) # gt (greater than) — строго больше 0 # le (less or equal) — меньше или равно 10000 price: float = Field(gt=0, le=10000) # ge (greater or equal) — больше или равно 0 stock: int = Field(default=0, ge=0) @app.post("/products") async def create_product(product: Product): # FastAPI автоматически проверит все ограничения перед вызовом этой функции return product # endregion # region Валидация данных. Пример 2: Валидация с помощью регулярных выражений и кастомные (собственные) валидаторы from pydantic import BaseModel, Field, field_validator class UserCreate(BaseModel): # Логин: только латинские буквы и цифры, от 3 до 20 символов username: str = Field(pattern=r"^[a-zA-Z0-9]+$", min_length=3, max_length=20) password: str = Field(min_length=8) # Кастомный валидатор для пароля @field_validator("password") @classmethod def password_must_contain_digit(cls, v: str) -> str: if not any(char.isdigit() for char in v): raise ValueError("Пароль должен содержать хотя бы одну цифру") return v @app.post("/register") async def register(user: UserCreate): return { "message": "Пользователь успешно прошел валидацию", "username": user.username, } # endregion # region Вложенные модели. # Пример 1: Вложенная модель (Item внутри Order) # main.py (раскомментировать) class Item(BaseModel): name: str quantity: int = Field(ge=1) class Order(BaseModel): order_id: str items: list[Item] # список из Item total: float = Field(gt=0) @app.post("/orders") async def create_order(order: Order): return {"order_id": order.order_id, "item_count": len(order.items)} # endregion # region Вложенные модели. Пример 2: Словарь (dict) # main.py (раскомментировать) from pydantic import BaseModel, ConfigDict class Metadata(BaseModel): # Разрешаем конвертацию чисел к строкам model_config = ConfigDict(coerce_numbers_to_str=True) # Словарь, где ключи и значения — строки attributes: dict[str, str] @app.post("/metadata") async def add_metadata(data: Metadata): return {"received_attributes": data.attributes} # endregion # region Вложенные модели. Пример 3: Рекурсивно вложенные модели # main.py (раскомментировать) from pydantic import BaseModel class Comment(BaseModel): id: int text: str # Список ответов, которые сами являются комментариями. Если ответов нет, список будет пустым. replies: list["Comment"] = [] def get_max_depth(comment: Comment) -> int: if not comment.replies: return 1 return 1 + max(get_max_depth(reply) for reply in comment.replies) @app.post("/comments") async def check_comment(comment: Comment): depth = get_max_depth(comment) return {"message": "Дерево комментариев получено", "max_depth": depth} # endregion