Path Parameters


path 中可以用 python 格式字符串的形式来声明变量,例如

from fastapi import FastAPI

app = FastAPI()


@app.get("/items/{item_id}")
async def read_item(item_id):
    return {"item_id": item_id}

变量 item_id 会成为为函数的一个参数

带类型的路径变量

from fastapi import FastAPI

app = FastAPI()


@app.get("/items/{item_id}")
async def read_item(item_id: int):
    return {"item_id": item_id}

给路径变量添加类型

  • 有助于 IDE 的检查和代码自动补全

  • FastAPI 可以根据声明的类型对变量自动解析 (将从http请求获得的字符串转化为 python data)

  • FastAPI 可以根据声明的类型对数据进行验证,例如访问 http://127.0.0.1:8000/items/foo 会得到如下错误

    • {
          "detail": [
              {
                  "loc": [
                      "path",
                      "item_id"
                  ],
                  "msg": "value is not a valid integer",
                  "type": "type_error.integer"
              }
          ]
      }

Pydantic

所有的数据验证工作都是由 Pydantic 提供的

路径顺序

from fastapi import FastAPI

app = FastAPI()


@app.get("/users/me")
async def read_user_me():
    return {"user_id": "the current user"}


@app.get("/users/{user_id}")
async def read_user(user_id: str):
    return {"user_id": user_id}

如果用 /users/me 表示当前用户 /users/{user_id} 表示特定用户,则 /users/me 需要放在前面,在 fastapi 中路径是按照声明的顺序来依次匹配的

Predefined values

如果希望接收到预先定义的合法路径变量,可以使用 Enum

from enum import Enum

from fastapi import FastAPI


# 继承自 str 相当于给每一个属性声明 str 类型
class ModelName(str, Enum):
    alexnet = "alexnet"
    resnet = "resnet"
    lenet = "lenet"


app = FastAPI()


@app.get("/model/{model_name}")
async def get_model(model_name: ModelName):
    # 枚举的值可以从类中得到
    if model_name == ModelName.alexnet:
        return {"model_name": model_name, "message": "Deep Learning FTW!"}
    # 枚举的值可以从实例中得到
    if model_name.value == "lenet":
        return {"model_name": model_name, "message": "LeCNN all the images"}
    return {"model_name": model_name, "message": "Have some residuals"}

包含路径的路径变量

OpenAPI 不支持包含路径变量中包含路径,但是 FastAPI 借助 Starlette 的内置工具可以实现,并且生成的 API 文档仍然可用

from fastapi import FastAPI

app = FastAPI()


@app.get("/files/{file_path:path}")
async def read_file(file_path: str):
    return {"file_path": file_path}

在上面的例子中,如果希望 file_path=/home/johndoe/myfile.txt 则访问的地址为 http://127.0.0.1:8000/files//home/johndoe/myfile.txt

Recap

使用 Python type declarations 可以:

  • 获得 IDE 支持,如错误检查,自动补全等
  • 数据解析
  • 数据验证
  • API 文档的注释

文章作者: qiufeng
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 qiufeng !
评论
  目录