fastapi/docs/zh/docs/tutorial/path-params.md

8.0 KiB
Raw Blame History

路径参数

你可以使用与 Python 字符串格式化相同的语法声明路径“参数”或“变量”:

{* ../../docs_src/path_params/tutorial001_py39.py hl[6:7] *}

路径参数 item_id 的值会作为参数 item_id 传递给你的函数。

运行示例并访问 http://127.0.0.1:8000/items/foo,可获得如下响应:

{"item_id":"foo"}

声明路径参数的类型

使用 Python 标准类型注解,声明路径操作函数中路径参数的类型:

{* ../../docs_src/path_params/tutorial002_py39.py hl[7] *}

本例把 item_id 的类型声明为 int

/// check | 检查

类型声明将为函数提供错误检查、代码补全等编辑器支持。

///

数据转换

运行示例并访问 http://127.0.0.1:8000/items/3,返回的响应如下:

{"item_id":3}

/// check | 检查

注意,函数接收并返回的值是 3 int),不是 "3"str)。

FastAPI 通过类型声明自动解析请求中的数据

///

数据校验

通过浏览器访问 http://127.0.0.1:8000/items/foo,接收如下 HTTP 错误信息:

{
  "detail": [
    {
      "type": "int_parsing",
      "loc": [
        "path",
        "item_id"
      ],
      "msg": "Input should be a valid integer, unable to parse string as an integer",
      "input": "foo"
    }
  ]
}

这是因为路径参数 item_id 的值("foo")的类型不是 int

值的类型不是 int 而是浮点数(float)时也会显示同样的错误,比如: http://127.0.0.1:8000/items/4.2

/// check | 检查

FastAPI 使用同样的 Python 类型声明实现了数据校验。

注意,上面的错误清晰地指出了未通过校验的具体位置。

这在开发调试与 API 交互的代码时非常有用。

///

文档

访问 http://127.0.0.1:8000/docs,查看自动生成的交互式 API 文档:

/// check | 检查

还是使用 Python 类型声明,FastAPI 提供了(集成 Swagger UI 的)自动交互式文档。

注意,路径参数的类型是整数。

///

基于标准的好处,备选文档

FastAPI 使用 OpenAPI 生成概图,所以能兼容很多工具。

因此,FastAPI 还内置了 ReDoc 生成的备选 API 文档,可在此查看 http://127.0.0.1:8000/redoc

同样,还有很多兼容工具,包括多种语言的代码生成工具。

Pydantic

FastAPI 充分地利用了 Pydantic 的优势用它在后台校验数据。众所周知Pydantic 擅长的就是数据校验。

同样,strfloatbool 以及很多复合数据类型都可以使用类型声明。

接下来的章节会介绍其中的好几种。

顺序很重要

有时,路径操作中的路径是写死的。

比如要使用 /users/me 获取当前用户的数据。

然后还要使用 /users/{user_id},通过用户 ID 获取指定用户的数据。

由于路径操作是按顺序依次运行的,因此,一定要在 /users/{user_id} 之前声明 /users/me

{* ../../docs_src/path_params/tutorial003_py39.py hl[6,11] *}

否则,/users/{user_id} 将匹配 /users/meFastAPI 会认为正在接收值为 "me"user_id 参数。

同样,你不能重复定义一个路径操作:

{* ../../docs_src/path_params/tutorial003b_py39.py hl[6,11] *}

由于路径首先匹配,始终会使用第一个定义的。

预设值

路径操作使用 Python 的 Enum 类型接收预设的路径参数。

创建 Enum

导入 Enum 并创建继承自 strEnum 的子类。

通过从 str 继承API 文档就能把值的类型定义为字符串,并且能正确渲染。

然后,创建包含固定值的类属性,这些固定值是可用的有效值:

{* ../../docs_src/path_params/tutorial005_py39.py hl[1,6:9] *}

/// tip | 提示

AlexNetResNetLeNet 是机器学习模型的名字。

///

声明路径参数

使用 Enum 类(ModelName)创建使用类型注解的路径参数:

{* ../../docs_src/path_params/tutorial005_py39.py hl[16] *}

查看文档

API 文档会显示预定义路径参数的可用值:

使用 Python 枚举

路径参数的值是一个枚举成员。

比较枚举成员

可以将其与枚举类 ModelName 中的枚举成员进行比较:

{* ../../docs_src/path_params/tutorial005_py39.py hl[17] *}

获取枚举值

使用 model_name.value 或通用的 your_enum_member.value 获取实际的值(本例中为 str

{* ../../docs_src/path_params/tutorial005_py39.py hl[20] *}

/// tip | 提示

使用 ModelName.lenet.value 也能获取值 "lenet"

///

返回枚举成员

即使嵌套在 JSON 请求体里(例如,dict),也可以从路径操作返回枚举成员。

返回给客户端之前,会把枚举成员转换为对应的值(本例中为字符串):

{* ../../docs_src/path_params/tutorial005_py39.py hl[18,21,23] *}

客户端中的 JSON 响应如下:

{
  "model_name": "alexnet",
  "message": "Deep Learning FTW!"
}

包含路径的路径参数

假设路径操作的路径为 /files/{file_path}

但需要 file_path 中也包含路径,比如,home/johndoe/myfile.txt

此时,该文件的 URL 是这样的:/files/home/johndoe/myfile.txt

OpenAPI 支持

OpenAPI 不支持声明包含路径的路径参数,因为这会导致测试和定义更加困难。

不过,仍可使用 Starlette 内置工具在 FastAPI 中实现这一功能。

而且不影响文档正常运行,但是不会添加该参数包含路径的说明。

路径转换器

直接使用 Starlette 的选项声明包含路径的路径参数:

/files/{file_path:path}

本例中,参数名为 file_path,结尾部分的 :path 说明该参数应匹配路径。

用法如下:

{* ../../docs_src/path_params/tutorial004_py39.py hl[6] *}

/// tip | 提示

注意,包含 /home/johndoe/myfile.txt 的路径参数要以斜杠(/)开头。

本例中的 URL 是 /files//home/johndoe/myfile.txt。注意,fileshome 之间要使用双斜杠(//)。

///

小结

通过简短、直观的 Python 标准类型声明,FastAPI 可以获得:

  • 编辑器支持:错误检查,代码自动补全等
  • 数据 "解析"
  • 数据校验
  • API 注解和自动文档

只需要声明一次即可。

这可能是除了性能以外,FastAPI 与其它框架相比的主要优势。