Параметры пути FastAPI
Параметры пути — это динамические части URL-пути, объявляемые с помощью фигурных скобок.{}FastAPI автоматически передаёт параметры пути в функцию операции пути и выполняет преобразование и валидацию данных на основе аннотаций типов.
Базовое использование
Используйте синтаксис форматированных строк Python для объявления параметров пути:
Пример
app = FastAPI()
# {item_id} — это параметр пути
@app.get("/items/{item_id}")
async def read_item(item_id: int):
return {"item_id": item_id}
Перейдите поhttp://127.0.0.1:8000/items/5, возвращает:
{"item_id": 5}
Обратите внимание, что возвращаемоеitem_idявляется целым числом5, а не строкой"5". FastAPI, используя аннотации типов,item_id: intавтоматически преобразует строку в URL в целое число.
Преобразование данных
Когда вы объявляете тип какintКогда , FastAPI автоматически выполняет преобразование типов:
# 传入整数,正常工作
GET /items/3 -> {"item_id": 3}
# 传入非整数,返回校验错误
GET /items/foo -> 错误:Input should be a valid integer
# 传入浮点数,同样报错
GET /items/4.2 -> 错误:Input should be a valid integer
Посетитеhttp://127.0.0.1:8000/items/fooКогда , FastAPI возвращает информацию об ошибке валидации:
{
"detail": [
{
"type": "int_parsing",
"loc": ["path", "item_id"],
"msg": "Input should be a valid integer, unable to parse string as an integer",
"input": "foo"
}
]
}
Сообщения об ошибках валидации FastAPI очень понятны и указывают точное место ошибки (
loc), тип ошибки (type) и описание ошибки (msg). Это очень полезно при отладке.
Тип параметра пути
exceptint, вы также можете использовать другие стандартные типы Python:
| Type | Описание | Пример URL |
|---|---|---|
str | Строка (тип по умолчанию) | /items/foo |
int | Integer | /items/5 |
float | Число с плавающей запятой | /items/5.5 |
bool | Логическое значение | /items/true |
uuid.UUID | UUID | /items/3fa85f64-5717-4562-b3fc-2c963f66afa6 |
Порядок путей имеет значение
Когда несколько маршрутов могут соответствовать одному и тому же URL, порядок определения определяет результат сопоставления. FastAPI сопоставляет маршруты один за другим в порядке их определения, и будет выполнен первый подходящий маршрут.
Пример
app = FastAPI()
# Должен быть перед /users/{user_id}
@app.get("/users/me")
async def read_user_me():
"""Получить информацию о текущем пользователе"""
return {"user_id": "текущий пользователь"}
@app.get("/users/{user_id}")
async def read_user(user_id: str):
"""Получить информацию о пользователе по ID"""
return {"user_id": user_id}
если вы поместите/users/meПоместите/users/{user_id}После этого затем получите доступ/users/meFastAPI будет рассматривать"me"Даuser_idзначение, тем самым сопоставив его с неправильной функцией.
Маршруты с фиксированными путями должны быть размещены перед маршрутами с динамическими параметрами пути, иначе динамические параметры «проглотят» значение фиксированного пути.
Параметры пути с предустановленными значениями (Enum)
Когда нужно ограничить параметр пути несколькими фиксированными значениями, можно использовать PythonEnumТип:
Пример
from fastapi import FastAPI
# Создайте класс перечисления, наследующий от str и Enum
class ModelName(str, Enum):
alexnet = "alexnet"
resnet = "resnet"
lenet = "lenet"
app = FastAPI()
@app.get("/models/{model_name}")
async def get_model(model_name: ModelName):
# Можно сравнивать с членами перечисления
if model_name is ModelName.alexnet:
return {"model_name": model_name, "message": "Глубокое обучение рулит!"}
if model_name.value == "lenet":
return {"model_name": model_name, "message": "LeCNN все изображения"}
return {"model_name": model_name, "message": "Отведайте остаточков"}
Ключевые моменты enum-классов:
| Ключевые моменты | Описание |
|---|---|
Наследованиеstr | чтобы документация API распознавала тип значения как строку, обеспечивая корректное отображение |
НаследованиеEnum | Создайте тип Enum, чтобы ограничить выбираемые значения. |
model_name.value | Получите фактическое значение члена перечисления (например,"alexnet") |
Перейдите по адресуhttp://127.0.0.1:8000/models/alexnet, возвращает:
{"model_name": "alexnet", "message": "Deep Learning FTW!"}
Если передано значение, не являющееся предустановленным (например,/models/foobar), FastAPI вернёт ошибку валидации, указывая, что допустимыми значениями являютсяalexnet、resnet、lenet。
Параметры пути, содержащие путь
Когда нужно, чтобы сам параметр пути содержал путь (например, путь к файлу), используйте конвертер пути Starlette:
Пример
app = FastAPI()
# :path указывает, что этот параметр может соответствовать путям, содержащим слеши
@app.get("/files/{file_path:path}")
async def read_file(file_path: str):
return {"file_path": file_path}
Перейдите по адресуhttp://127.0.0.1:8000/files/home/johndoe/myfile.txt, возвращает:
{"file_path": "home/johndoe/myfile.txt"}
Обратите внимание на URL
/files/и/home/двойные слеши появятся между//Это нормально, потому что параметры пути начинаются с/в начале.
Итог
Благодаря стандартным объявлениям типов Python параметры пути FastAPI могут одновременно получать:
- Преобразование данных: строка в URL автоматически преобразуется в объявленный тип
- Проверка данных: при несоответствии типа возвращается понятное сообщение об ошибке
- Автоматическая документация: типы и ограничения параметров пути автоматически появляются в документации API
- Поддержка редактора: аннотации типов обеспечивают автодополнение в редакторе