FastAPI 教程

FastAPI 路径参数

在 FastAPI 中,路径参数(Path Parameters) 是 URL 路径的一部分,用于捕获动态的值。FastAPI 会利用 Python 的类型提示(Type Hints)自动对这些参数进行解析、类型转换和数据验证。

以下是 FastAPI 路径参数的核心用法和进阶技巧:


1. 基本用法

使用花括号 {} 在路径中声明参数,并在函数中定义同名参数。

纯文本
plaintext
from fastapi import FastAPI

app = FastAPI()

# 路径中声明 {item_id}
@app.get("/items/{item_id}")
async def read_item(item_id: str):
    return {"item_id": item_id}

访问 http://127.0.0.1:8000/items/foo,将返回 {"item_id": "foo"}


2. 类型转换与自动验证

FastAPI 会根据你提供的类型提示自动转换数据类型。如果转换失败(例如传入了字母而不是数字),它会自动返回清晰的 HTTP 422 Unprocessable Entity 错误。

纯文本
plaintext
@app.get("/items/{item_id}")
async def read_item(item_id: int):
    return {"item_id": item_id, "type": type(item_id).__name__}
  • 访问 /items/3:返回 {"item_id": 3, "type": "int"}
  • 访问 /items/foo:返回 422 错误,提示 value is not a valid integer

3. 预定义值(使用 Enum)

如果你希望路径参数只能是几个特定的值,可以使用 Python 的 Enum 类。

纯文本
plaintext
from enum import Enum
from fastapi import FastAPI

app = FastAPI()

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

@app.get("/models/{model_name}")
async def get_model(model_name: ModelName):
    if model_name == ModelName.alexnet:
        return {"model_name": model_name, "message": "Deep Learning FTW!"}

    # 可以通过 .value 获取字符串值
    return {"model_name": model_name.value, "message": "Have some residuals"}

访问 /models/resnet 会正常响应,但访问 /models/vgg 会返回 422 错误,因为 vgg 不在允许的枚举值中。


4. 包含路径的路径参数 (Path containing paths)

如果你的路径参数本身包含斜杠 /(例如文件路径),你需要使用特殊的语法 {param_name:path},并在函数参数中使用 Path

纯文本
plaintext
from fastapi import FastAPI, Path

app = FastAPI()

# 注意 {file_path:path} 的写法
@app.get("/files/{file_path:path}")
async def read_file(file_path: str = Path(..., description="The file path to read")):
    return {"file_path": file_path}

访问 /files/home/johndoe/myfile.txtfile_path 的值将是 home/johndoe/myfile.txt


5. 使用 Path 添加额外验证

你可以从 fastapi 导入 Path,为路径参数添加更复杂的验证规则(如最小值、最大值、正则表达式等)。... (Ellipsis) 表示该参数是必需的。

纯文本
plaintext
from fastapi import FastAPI, Path
from typing import Annotated # Python 3.9+ 推荐使用 Annotated

app = FastAPI()

# 传统写法
@app.get("/items/{item_id}")
async def read_item(
    item_id: int = Path(..., title="The ID of the item to get", ge=1, le=1000)
):
    return {"item_id": item_id}

# 现代写法 (推荐,Python 3.9+)
@app.get("/items/{item_id}")
async def read_item_modern(
    item_id: Annotated[int, Path(title="The ID of the item to get", ge=1, le=1000)]
):
    return {"item_id": item_id}
  • ge=1:大于或等于 1 (greater than or equal)
  • le=1000:小于或等于 1000 (less than or equal)
  • 如果传入 01001,将返回 422 验证错误。

6. 路径参数与查询参数混合使用

FastAPI 可以无缝区分路径参数和查询参数。路径参数在 {} 中声明,查询参数作为普通的函数参数声明。

纯文本
plaintext
@app.get("/users/{user_id}/items")
async def read_user_items(
    user_id: int, 
    skip: int = 0, 
    limit: int = 10
):
    return {
        "user_id": user_id, 
        "skip": skip, 
        "limit": limit
    }

访问 /users/5/items?skip=20&limit=5

  • user_id (路径参数) = 5
  • skip (查询参数) = 20
  • limit (查询参数) = 5

💡 最佳实践总结

  1. 始终使用类型提示:这能让 FastAPI 提供自动的数据验证和出色的 OpenAPI (Swagger) 文档。
  2. 优先使用 Annotated:在现代 Python (3.9+) 中,使用 Annotated[type, Path(...)] 是官方推荐的做法,代码更清晰。
  3. 善用枚举 (Enum):对于状态、分类等固定选项,使用 Enum 可以避免非法输入,并自动生成 Swagger UI 中的下拉选择框。

如果你有关于特定场景(如正则校验路径参数、动态路由等)的问题,可以随时告诉我!

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注