Path-параметры и их валидация

Path-параметры и их валидация FastAPI

Привет! В FastAPI path-параметры (параметры пути) — это часть URL, которая передаётся в фигурных скобках. FastAPI позволяет валидировать их с помощью аннотаций типов и функции Path.

В этой статье мы разберём:

  • Базовую валидацию типов
  • Валидацию через Path
  • Ограничение значений с помощью Enum
  • Примеры из реальной жизни

Что нужно знать перед началом

Для этого урока тебе понадобится:

  • Установленный FastAPI
  • Базовое понимание path-параметров

Совет: Валидация path-параметров — это гарантия того, что API получает корректные данные из URL.

Основная часть

Базовые типы

FastAPI автоматически валидирует типы path-параметров.

from fastapi import FastAPI

app = FastAPI()

@app.get("/users/{user_id}")
def get_user(user_id: int):           # Автоматически проверяет, что user_id — int
    return {"user_id": user_id}

@app.get("/products/{product_id}")
def get_product(product_id: int):
    return {"product_id": product_id}

@app.get("/items/{item_name}")
def get_item(item_name: str):         # По умолчанию str
    return {"item_name": item_name}

Валидация через Path

Path добавляет дополнительные проверки для path-параметров.

from fastapi import FastAPI, Path

app = FastAPI()

@app.get("/users/{user_id}")
def get_user(
    user_id: int = Path(..., ge=1, le=1000, description="ID пользователя")
):
    return {"user_id": user_id}

Параметры Path:

ПараметрНазначение
geБольше или равно (greater or equal)
leМеньше или равно (less or equal)
gtБольше (greater than)
ltМеньше (less than)
min_lengthМинимальная длина строки
max_lengthМаксимальная длина строки
regexРегулярное выражение
descriptionОписание для документации

Валидация чисел

from fastapi import FastAPI, Path

app = FastAPI()

@app.get("/posts/{post_id}")
def get_post(
    post_id: int = Path(..., ge=1, description="ID поста")
):
    return {"post_id": post_id}

@app.get("/products/{product_id}")
def get_product(
    product_id: int = Path(..., gt=0, le=10000)
):
    return {"product_id": product_id}

@app.get("/price/{price}")
def get_price(
    price: float = Path(..., ge=0.0, le=9999.99)
):
    return {"price": price}

Пример ошибки: /posts/0 → 422 Unprocessable Entity (post_id должен быть >= 1)

Валидация строк

from fastapi import FastAPI, Path

app = FastAPI()

@app.get("/users/{username}")
def get_user(
    username: str = Path(..., min_length=3, max_length=20)
):
    return {"username": username}

@app.get("/files/{file_path:path}")
def get_file(
    file_path: str = Path(..., min_length=1)
):
    return {"file_path": file_path}

Совет: :path в конце позволяет передавать пути со слешами.

Валидация с помощью регулярных выражений

from fastapi import FastAPI, Path

app = FastAPI()

@app.get("/users/{username}")
def get_user(
    username: str = Path(..., regex=r"^[a-zA-Z0-9_]+$")
):
    return {"username": username}

@app.get("/items/{item_id}")
def get_item(
    item_id: str = Path(..., regex=r"^[A-Z]{2}-\d{4}$")
):
    return {"item_id": item_id}

Примеры валидных значений: ABC-1234XY-9876

Ограничение значений с помощью Enum

from enum import Enum
from fastapi import FastAPI

class ModelName(str, Enum):
    alexnet = "alexnet"
    resnet = "resnet"
    lenet = "lenet"

app = FastAPI()

@app.get("/models/{model_name}")
def get_model(model_name: ModelName):
    return {"model_name": model_name}

Несколько path-параметров

from fastapi import FastAPI, Path

app = FastAPI()

@app.get("/posts/{year}/{month}/{day}")
def get_post_by_date(
    year: int = Path(..., ge=2000, le=2030),
    month: int = Path(..., ge=1, le=12),
    day: int = Path(..., ge=1, le=31)
):
    return {"date": f"{year}-{month:02d}-{day:02d}"}

Полный пример

from fastapi import FastAPI, Path
from enum import Enum

app = FastAPI()

class UserRole(str, Enum):
    admin = "admin"
    user = "user"
    guest = "guest"

@app.get("/users/{user_id}")
def get_user(
    user_id: int = Path(..., ge=1, le=1000, description="ID пользователя")
):
    return {"user_id": user_id}

@app.get("/users/{user_id}/profile")
def get_user_profile(
    user_id: int = Path(..., ge=1, le=1000),
    role: UserRole = UserRole.guest
):
    return {"user_id": user_id, "role": role}

@app.get("/products/{product_id}")
def get_product(
    product_id: str = Path(..., regex=r"^[A-Z]{2}-\d{4}$")
):
    return {"product_id": product_id}

@app.get("/posts/{year}/{month}/{day}")
def get_post_by_date(
    year: int = Path(..., ge=2020, le=2030),
    month: int = Path(..., ge=1, le=12),
    day: int = Path(..., ge=1, le=31)
):
    return {"date": f"{year}-{month:02d}-{day:02d}"}

@app.get("/files/{file_path:path}")
def get_file(file_path: str = Path(..., min_length=1)):
    return {"file_path": file_path}

Задачи для закрепления

Задача 1. Создай эндпоинт с path-параметром user_id типа int с валидацией >= 1.

Задача 2. Создай эндпоинт с path-параметром username с валидацией длины 3–20 символов.

Задача 3. Создай эндпоинт с path-параметром product_id с регулярным выражением.

Задача 4. Создай эндпоинт с двумя path-параметрами year и month.

Задача 5. Создай Enum для статусов и используй его в path-параметре.

Ответы:

Задача 1.

@app.get("/users/{user_id}")
def get_user(user_id: int = Path(..., ge=1)):
    return {"user_id": user_id}

Задача 2.

@app.get("/users/{username}")
def get_user(username: str = Path(..., min_length=3, max_length=20)):
    return {"username": username}

Задача 3.

@app.get("/products/{product_id}")
def get_product(product_id: str = Path(..., regex=r"^[A-Z]{2}-\d{4}$")):
    return {"product_id": product_id}

Задача 4.

@app.get("/posts/{year}/{month}")
def get_posts(year: int = Path(..., ge=2020), month: int = Path(..., ge=1, le=12)):
    return {"year": year, "month": month}

Задача 5.

class Status(str, Enum):
    active = "active"
    inactive = "inactive"
    pending = "pending"

@app.get("/status/{status}")
def get_status(status: Status):
    return {"status": status}

Нюансы и подводные камни

  • Path-параметры обязательны. Если их нет — 404.
  • Path добавляет валидацию к path-параметрам.
  • gelegtlt — для чисел.
  • min_lengthmax_lengthregex — для строк.
  • Enum ограничивает допустимые значения.
  • :path — для путей со слешами.
  • Валидация path-параметров выполняется автоматически.
  • Ошибка валидации возвращает 422.

Частые ошибки и как их избежать

Ошибка 1: Неправильное имя параметра

Имя в {} должно совпадать с аргументом функции.

Ошибка 2: Использование Path без импорта

from fastapi import Path

Ошибка 3: Неправильный синтаксис :path

{file_path:path}

Шпаргалка

Что нужноКак пишется
Больше или равноPath(..., ge=1)
Меньше или равноPath(..., le=100)
Минимальная длинаPath(..., min_length=3)
Максимальная длинаPath(..., max_length=20)
Регулярное выражениеPath(..., regex=r"pattern")
Enumclass Status(str, Enum):
Путь со слешами{file_path:path}

Заключение

Сегодня мы:

  • Изучили валидацию path-параметров
  • Использовали Path для проверок
  • Применяли регулярные выражения
  • Ограничивали значения через Enum

КВИЗ

Что дальше?

Оцените статью
IMI-DS - PYTHON LERNEN
Содержание
Оглавление ×