Привет! В FastAPI данные могут передаваться разными способами. Сегодня мы разберём два основных: параметры пути (path parameters) и параметры запроса (query parameters). Они позволяют создавать гибкие и мощные API.
В этой статье мы разберём:
- Параметры пути (path parameters)
- Параметры запроса (query parameters)
- Типы данных и валидацию
- Примеры из реальной жизни
- Что нужно знать перед началом
- Основная часть
- Параметры пути (path parameters)
- Типы параметров пути
- Несколько параметров пути
- Параметры запроса (query parameters)
- Опциональные параметры
- Валидация параметров
- Обязательные и необязательные параметры
- Полный пример
- Задачи для закрепления
- Нюансы и подводные камни
- Частые ошибки и как их избежать
- Ошибка 1: Имя параметра пути не совпадает с аргументом
- Ошибка 2: Неправильный тип конвертера
- Ошибка 3: Забыл Optional для необязательных параметров
- Шпаргалка
- Заключение
- КВИЗ
- Что дальше?
Что нужно знать перед началом
Для этого урока тебе понадобится:
- Установленный FastAPI и Uvicorn
- Базовое понимание эндпоинтов
Совет: FastAPI использует аннотации типов Python для автоматической валидации параметров.
Основная часть
Параметры пути (path parameters)
Параметры пути передаются непосредственно в URL.
from fastapi import FastAPI
app = FastAPI()
@app.get("/users/{user_id}")
def get_user(user_id: int):
return {"user_id": user_id, "name": f"Пользователь {user_id}"}
@app.get("/products/{product_id}")
def get_product(product_id: int):
return {"product_id": product_id, "name": f"Товар {product_id}"}Совет: Имя параметра в фигурных скобках должно совпадать с именем аргумента функции.
Типы параметров пути
FastAPI автоматически преобразует параметры к указанным типам.
@app.get("/posts/{post_id}")
def get_post(post_id: int): # Автоматически в int
return {"post_id": post_id}
@app.get("/files/{file_path:path}") # path — для путей со слешами
def get_file(file_path: str):
return {"file": file_path}Поддерживаемые типы:
| Тип | Описание | Пример |
|---|---|---|
int | Целое число | /users/123 |
str | Строка | /users/anna |
float | Дробное число | /price/99.99 |
bool | Логический тип | /active/true |
path | Путь со слешами | /files/docs/readme.txt |
Совет: Используй
pathдля параметров, которые могут содержать слеши.
Несколько параметров пути
@app.get("/posts/{year}/{month}/{day}")
def get_post_by_date(year: int, month: int, day: int):
return {"date": f"{year}-{month:02d}-{day:02d}"}Параметры запроса (query parameters)
Параметры запроса передаются после ? в URL.
@app.get("/search")
def search(q: str, page: int = 1, limit: int = 10):
return {
"query": q,
"page": page,
"limit": limit,
"results": [f"Результат {i}" for i in range(1, limit + 1)]
}Пример запроса: /search?q=fastapi&page=2&limit=5
Совет: Параметры запроса указываются в функции как обычные аргументы. Если есть значение по умолчанию — параметр необязательный.
Опциональные параметры
@app.get("/items/")
def list_items(skip: int = 0, limit: int = 10):
return {"skip": skip, "limit": limit}Примеры запросов:
/items/ # skip=0, limit=10
/items/?skip=5 # skip=5, limit=10
/items/?limit=3 # skip=0, limit=3Валидация параметров
FastAPI автоматически валидирует параметры.
@app.get("/users/{user_id}")
def get_user(user_id: int): # Если передать строку, вернёт ошибку 422
return {"user_id": user_id}Ошибка при неверном типе:
# Запрос: /users/abc
# Ответ: 422 Unprocessable EntityСовет: Аннотации типов в FastAPI — это не просто подсказки, это валидация.
Обязательные и необязательные параметры
from typing import Optional
@app.get("/products/")
def get_products(
category: Optional[str] = None,
min_price: Optional[float] = None,
max_price: Optional[float] = None
):
filters = {}
if category:
filters["category"] = category
if min_price:
filters["min_price"] = min_price
if max_price:
filters["max_price"] = max_price
return {"filters": filters}Полный пример
from fastapi import FastAPI
from typing import Optional
app = FastAPI(title="API с параметрами")
# Параметры пути
@app.get("/users/{user_id}")
def get_user(user_id: int):
return {"user_id": user_id}
# Параметры запроса
@app.get("/search")
def search(q: str, page: int = 1, limit: int = 10):
return {
"query": q,
"page": page,
"limit": limit,
"total": limit
}
# Комбинация
@app.get("/posts/{year}/{month}")
def get_posts(year: int, month: int, sort: str = "desc", limit: int = 10):
return {
"year": year,
"month": month,
"sort": sort,
"limit": limit
}
# Опциональные параметры
@app.get("/products/")
def get_products(
category: Optional[str] = None,
min_price: Optional[float] = None,
max_price: Optional[float] = None
):
return {
"filters": {
"category": category,
"min_price": min_price,
"max_price": max_price
}
}Задачи для закрепления
Задача 1. Создай эндпоинт /users/{user_id} с параметром user_id типа int.
Задача 2. Создай эндпоинт /search с параметрами q (обязательный) и page (необязательный).
Задача 3. Создай эндпоинт /posts/{year}/{month}.
Задача 4. Добавь опциональный параметр category в эндпоинт /products/.
Задача 5. Что произойдёт, если передать строку в параметр user_id: int?
Ответы:
Задача 1.
@app.get("/users/{user_id}")
def get_user(user_id: int):
return {"user_id": user_id}Задача 2.
@app.get("/search")
def search(q: str, page: int = 1):
return {"query": q, "page": page}Задача 3.
@app.get("/posts/{year}/{month}")
def get_posts(year: int, month: int):
return {"year": year, "month": month}Задача 4.
@app.get("/products/")
def get_products(category: Optional[str] = None):
return {"category": category}Задача 5.
# Вернёт ошибку 422 Unprocessable EntityНюансы и подводные камни
- FastAPI автоматически валидирует типы параметров. Если тип не совпадает — возвращается 422.
- Параметры пути обязательны. Если их нет в URL — ошибка 404.
- Параметры запроса (query) могут быть опциональными, если указано значение по умолчанию.
- Параметры пути и запроса не могут иметь одинаковые имена.
path— специальный тип, позволяющий передавать пути со слешами.- При использовании
OptionalсNoneпараметр становится необязательным. - Порядок параметров в функции не важен — FastAPI определяет их по типу и имени.
Частые ошибки и как их избежать
Ошибка 1: Имя параметра пути не совпадает с аргументом
Неправильно:
@app.get("/users/{user_id}")
def get_user(id: int): # Ошибка! Имя должно быть user_id
passПравильно:
@app.get("/users/{user_id}")
def get_user(user_id: int):
passОшибка 2: Неправильный тип конвертера
Используй int для чисел, str для строк, path для путей.
Ошибка 3: Забыл Optional для необязательных параметров
q: Optional[str] = None
Шпаргалка
| Что нужно | Как пишется |
|---|---|
| Параметр пути | @app.get("/users/{user_id}") |
| Параметр запроса | def search(q: str, page: int = 1) |
| Тип int | user_id: int |
| Тип str | name: str |
| Тип float | price: float |
| Тип path | file_path: path |
| Опциональный параметр | Optional[str] = None |
Заключение
Сегодня мы:
- Изучили параметры пути
- Изучили параметры запроса
- Разобрали типы данных
- Научились валидировать параметры








