一、声明路径参数
您可以使用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
的值会作为参数 item_id
传递到你的视图函数.
因此,如果你运行上述示例,然后跳转到 http://127.0.0.1:8000/items/foo, 你将会看见这样的回应:
{"item_id":"foo"}
二、路径参数的类型
您可以使用 标准的Python类型注释 在函数中声明路径参数的类型:
from fastapi import FastAPI
app = FastAPI()
@app.get("/items/{item_id}")
async def read_item(item_id: int):
return {"item_id": item_id}
在上述示例中,item_id
被声明为 int
类型.
说明
这将为您的函数提供编辑器支持,包括错误检查,完整性检查等。
三、数据转换
当你在你的浏览转到http://127.0.0.1:8000/items/3, 你将会看到如下的响应:
{"item_id":3}
说明
指明你的函数接收并返回的参数是3
,是Python中的int
类型,而不是字符串 "3"
.
因此,只要有了类型检查, FastAPI为您自动提供请求“解析”。
四、数据校验
将你的浏览器跳转到 http://127.0.0.1:8000/items/foo, 你将会看见一个友好的HTTP错误页:
{
"detail": [
{
"loc": [
"path",
"item_id"
],
"msg": "value is not a valid integer",
"type": "type_error.integer"
}
]
}
错误的原因在于路径参数 item_id
的值 "foo"
不是 int
.
同样,当你提供一个 float
类型的值的时候也会报错 http://127.0.0.1:8000/items/4.2
说明
因此,使用Python类型声明,FastAPI 还可提供数据验证。
请注意,该错误也清楚地指出了验证未通过的点。
在开发和调试与您的API交互的代码时,这非常有用。
五、文档
在浏览器打开 http://127.0.0.1:8000/docs, 你将会看见如下的API交互文档:
说明
再次使用相同的Python类型声明,FastAPI 为您提供自动的交互式文档(集成Swagger UI)。
请注意,path参数声明为整数。
六、基于标准的好处:可选文档
因为都是从标准 OpenAPI 产生的模型,这里有许多可选的兼容工具.
基于这个原因, FastAPI 本身提供了一个可选的 API 文档(使用 ReDoc):
同样,有许多兼容的工具。 包括多种语言的代码生成工具。
七、Pydantic
所有的数据验证都是由 Pydantic实现的.
你可以用同样的类型声明比如 str
, float
, bool
或者其他更复杂的类型.
本教程的下一章将探讨其中的一些内容。
八、指定路径顺序
创建路径操作时,您会发现路径固定的情况。
像/ users / me一样,假设它是获取有关当前用户的数据。
然后,您还可以使用路径/ users / {user_id}来通过某些用户ID获取有关特定用户的数据。
由于路径操作是按顺序评估的,因此您需要确保/ users / me的路径在/ users / {user_id}的路径之前声明。
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 / {user_id}
的路径也将匹配/ users / me
,“认为”它正在接收参数“ user_id”,其值为“ me”。
九、预定义Path参数
如果您的 path操作 接收到 path参数,但是您希望预定义可能的有效 path参数值,则可以使用标准的Python Enum
.
1. 创建一个 Enum
类
Import Enum
然后创建一个子类继承自 str
和 Enum
.
通过继承 str
, API 文档将可能知道接收的值必须是 string
类型才会被正确渲染。
并创建具有固定值的类属性,这些固定值将是可用的有效值:
from enum import Enum
from fastapi import FastAPI
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"}
注意:
Enumerations (or enums) are available in Python 仅在Python3.4+提供支持.
说明:“ AlexNet”,“ ResNet”和“ LeNet”只是机器学习模型的名称。
2. 声明 Path 参数
然后使用您创建的枚举类(ModelName
)创建带有类型注释的* path参数*:
from enum import Enum
from fastapi import FastAPI
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"}
3. 检查文档
由于指定了 path参数 的可用值,因此交互式文档可以很好地显示它们:
4. 使用 Python 枚举
path 参数 的值是enumeration 成员之一.
a. 比较 : 枚举成员
您可以将其与创建的枚举ModelName中的 枚举成员 进行比较:
from enum import Enum
from fastapi import FastAPI
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"}
b. 获取: 枚举成员的值
你可以使用 model_name.value
获得枚举值(在本例中是 str
), 一般情况下, your_enum_member.value
:
from enum import Enum
from fastapi import FastAPI
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"}
也可以使用
ModelName.lenet.value
得到lenet
的值
c. 返回: 枚举成员
你也可以从你的 路径操作 返回 枚举成员, 甚至嵌套在 JSON 中(比如一个dict
).
在将它们返回给客户端之前,它们将被转换为相应的值:
from enum import Enum
from fastapi import FastAPI
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"}
十、包含Path的路径参数
假设现在你有一个路径操作:/files/{file_path}
,但是你需要 file_path
本身包含一个 路径, 比如 home/johndoe/myfile.txt
.
因此, 文件路径可能是: /files/home/johndoe/myfile.txt
.
1. OpenAPI 支持
OpenAPI 本身并不支持定义包含path的路径参数,因此这可能导致难以定义和测试。
不过, 使用 Starlette的内置工具仍然可以在 FastAPI 中实现该功能。
并且支持交互文档,只是文档中并不会添加任何说明,告诉你这个参数可能应该Path。
2. Path 转换器
使用直接来自Starlette的选项,您可以使用以下声明带 path 的 * path参数*:
/files/{file_path:path}
在上面例子中,参数的名字是 file_path
,:path
说明参数file_path
对应的类型是 path 类型.
因此,你也可以这样使用它:
from fastapi import FastAPI
app = FastAPI()
@app.get("/files/{file_path:path}") async def read_user_me(file_path: str):
return {"file_path": file_path}
3. 建议
你可能会将参数以 /
开头,比如 /home/johndoe/myfile.txt
在这个例子中,URL将会是 /files//home/johndoe/myfile.txt
, 在 files
和 home
之间会有双斜线//
.
十一、总结
使用** FastAPI **,通过使用简短,直观和标准的Python类型声明,您可以获得:
- 编辑器支持: 错误检查, 自动补全, 等
- 数据解析
- 数据验证
- API批注和自动文档
并且你只需要声明一次即可
与其他框架相比,这可能是** FastAPI **的主要可见优势(除了原始性能)。
网友评论