← Назад к вопросам

Какие знаешь пакеты на FastAPI для проверки типизации?

2.2 Middle🔥 131 комментариев
#FastAPI и Flask

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

# Пакеты для проверки типизации в FastAPI

Проверка типов (Type Checking) — это критически важная практика для создания надёжного кода на Python. FastAPI отлично работает с инструментами типизации.

1. mypy — статический анализатор типов

Установка и использование

pip install mypy
mypy your_app.py
mypy . --strict  # Строгий режим

Пример использования в FastAPI

from fastapi import FastAPI
from pydantic import BaseModel
from typing import List

app = FastAPI()

class User(BaseModel):
    id: int
    name: str
    email: str

@app.get("/users", response_model=List[User])
async def get_users() -> List[User]:
    return [{"id": 1, "name": "John", "email": "john@example.com"}]

# mypy проверит, что возвращаемый тип соответствует List[User]

Конфигурация mypy (mypy.ini или setup.cfg)

[mypy]
python_version = 3.11
warn_return_any = True
warn_unused_configs = True
disallow_untyped_defs = True
disallow_incomplete_defs = True
check_untyped_defs = True

2. Pydantic — валидация и сериализация

Встроенная типизация в Pydantic

from pydantic import BaseModel, Field, validator
from typing import Optional

class UserCreate(BaseModel):
    name: str = Field(..., min_length=1, max_length=100)
    email: str = Field(..., regex=r"^[\w\.-]+@[\w\.-]+\.\w+$")
    age: int = Field(..., ge=0, le=150)
    is_active: Optional[bool] = None
    
    @validator('email')
    def validate_email(cls, v: str) -> str:
        if '@' not in v:
            raise ValueError('Invalid email')
        return v.lower()

Использование с FastAPI

from fastapi import FastAPI

app = FastAPI()

@app.post("/users")
async def create_user(user: UserCreate) -> dict:
    # Pydantic автоматически валидирует типы
    return user.model_dump()

3. Pyright — высокопроизводительный анализатор типов

Установка

pip install pyright
pyright your_app.py

Преимущества перед mypy

  • Быстрее выполняется
  • Лучше поддерживает новые фичи Python
  • Интегрируется с VS Code из коробки

Конфигурация (pyrightconfig.json)

{
  "typeCheckingMode": "strict",
  "pythonVersion": "3.11",
  "include": ["src"],
  "exclude": ["tests", "venv"]
}

4. Typing-extensions — дополнительные типы

Установка

pip install typing-extensions

Примеры использования

from typing import Literal
from typing_extensions import TypedDict, NotRequired

# Literal для ограничения значений
def process_status(status: Literal["pending", "approved", "rejected"]) -> str:
    return f"Status: {status}"

# TypedDict для структурированных словарей
class UserDict(TypedDict):
    id: int
    name: str
    email: str
    phone: NotRequired[str]  # Опциональное поле

# Использование в FastAPI
@app.post("/users")
async def create_user(user: UserDict) -> UserDict:
    return user

5. Annotated — добавление метаданных к типам

Использование в FastAPI

from typing import Annotated
from fastapi import FastAPI, Query, Path
from pydantic import Field

app = FastAPI()

@app.get("/users/{user_id}")
async def get_user(
    user_id: Annotated[int, Path(..., ge=1, le=999)],
    skip: Annotated[int, Query(0, ge=0)] = 0,
    limit: Annotated[int, Query(10, ge=1, le=100)] = 10
) -> dict:
    return {"user_id": user_id, "skip": skip, "limit": limit}

6. FastAPI встроенная типизация

Автоматическая валидация

from fastapi import FastAPI, HTTPException
from pydantic import BaseModel

app = FastAPI()

class Item(BaseModel):
    name: str
    price: float
    description: str | None = None  # Union[str, None]
    
class Order(BaseModel):
    items: list[Item]
    total_price: float

@app.post("/orders")
async def create_order(order: Order) -> Order:
    # FastAPI автоматически:
    # 1. Парсит JSON
    # 2. Валидирует типы
    # 3. Генерирует OpenAPI документацию
    return order

7. Dataclasses с типизацией

Альтернатива Pydantic

from dataclasses import dataclass
from typing import Optional

@dataclass
class User:
    id: int
    name: str
    email: str
    is_active: bool = True

# В FastAPI нужно конвертировать в Pydantic для валидации
from pydantic import BaseModel

class UserModel(BaseModel):
    id: int
    name: str
    email: str
    is_active: bool = True

8. Pytest с typechecking плагинами

Конфигурация pytest.ini

[pytest]
addopts = --strict-markers --tb=short
python_files = test_*.py
python_classes = Test*
python_functions = test_*

Тесты с типизацией

import pytest
from typing import List

def test_user_creation() -> None:
    user: dict = {"id": 1, "name": "John", "email": "john@example.com"}
    assert user["name"] == "John"

@pytest.mark.asyncio
async def test_api_endpoint() -> None:
    from fastapi.testclient import TestClient
    from main import app
    
    client: TestClient = TestClient(app)
    response = client.get("/users/1")
    assert response.status_code == 200

9. Pre-commit hooks для типизации

.pre-commit-config.yaml

repos:
  - repo: https://github.com/pre-commit/mirrors-mypy
    rev: v1.7.1
    hooks:
      - id: mypy
        args: [--ignore-missing-imports]
        additional_dependencies: [types-requests]
  
  - repo: https://github.com/charliermarsh/ruff
    rev: v0.1.8
    hooks:
      - id: ruff
        args: [--select, E, F, W]

10. Рекомендуемый stack для FastAPI

requirements-dev.txt

mypy>=1.7
pyright>=1.1
pydantic>=2.0
fastapi>=0.104
typing-extensions>=4.8
pytest>=7.4
pytest-asyncio>=0.21
pytest-cov>=4.1
pre-commit>=3.5
ruff>=0.1

Полный пример приложения с типизацией

from fastapi import FastAPI, HTTPException
from pydantic import BaseModel, Field
from typing import Annotated, Optional

app = FastAPI(title="Typed API")

class UserCreate(BaseModel):
    name: Annotated[str, Field(min_length=1, max_length=100)]
    email: Annotated[str, Field(regex=r"^[\w\.-]+@[\w\.-]+\.\w+$")]
    age: Annotated[int, Field(ge=0, le=150)]

class UserResponse(UserCreate):
    id: int

users_db: dict[int, UserCreate] = {}

@app.post("/users", response_model=UserResponse)
async def create_user(user: UserCreate) -> UserResponse:
    user_id: int = max(users_db.keys()) + 1 if users_db else 1
    users_db[user_id] = user
    return UserResponse(**user.model_dump(), id=user_id)

@app.get("/users/{user_id}", response_model=UserResponse)
async def get_user(user_id: int) -> UserResponse:
    if user_id not in users_db:
        raise HTTPException(status_code=404, detail="User not found")
    user = users_db[user_id]
    return UserResponse(**user.model_dump(), id=user_id)

11. Чек-лист типизации кода

  1. Все функции типизированы (параметры и возвращаемые значения)
  2. Используешь mypy или pyright для проверки
  3. Pydantic для валидации входных данных
  4. Type hints везде (даже для сложных типов)
  5. Документирование типов в docstrings
  6. Pre-commit hooks для автоматической проверки
  7. Tests типизированы (pytest с type hints)
  8. No any types или минимальное использование

Выводы

  • Pydantic — обязателен для FastAPI валидации
  • mypy — лучший выбор для проверки типов
  • Pyright — альтернатива, быстрее работает
  • Typing-extensions — для расширенных типов
  • Annotated — для добавления метаданных
  • Type checking экономит часы отладки в будущем
Какие знаешь пакеты на FastAPI для проверки типизации? | PrepBro