FastAPI 基础学习(四) 路径参数

作者:麦克煎蛋   出处:https://www.cnblogs.com/mazhiyong/ 转载请保留这段声明,谢谢!

 

一、路径参数声明

我们可以用以下的方式来声明URL路径参数。

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传递给函数read_item。

运行这个示例并访问: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}

注意这里函数接收到的数据是int类型的3,而不是字符串"3"。

也就是说,借助类型声明,FastAPI可以对Request内容自动进行数据解析和数据转换。

四、数据校验

如果访问 http://127.0.0.1:8000/items/foo,你会看到如下的错误:

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

因为这里路径参数item_id的值是"foo",无法转换成int。

如果提供给item_id一个float类型的值,如4.2,也会发生类似的错误。

 

因此借助类型声明,FastAPI给了你自动进行数据校验的能力。返回结果里清晰的指出了具体错误内容,这非常有利于你的代码开发和调试。

所有的数据校验能力都是在Pydantic的底层支持下得以实现的。你可以利用通用的数据类型如str、float、bool或者其他更复杂的数据类型进行类型注释。

五、路径的顺序问题

在有些情况下,路径声明的顺序不同会影响访问结果,这里应该留意下。

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 的访问就会被匹配到 /users/{user_id},因为"me"会被认为是路径参数 user_id 的值。

六、路径参数的预定义值

我们可以使用Python Enum来声明路径参数的预定义值。

from enum import Enum

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

这里,我们声明了一个类ModelName,它继承自str(这样限制了值的类型必须是字符串类型)和Enum。

这里也给出了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"}

这时路径参数model_name的类型是我们定义的枚举类ModelName

我们可以访问可交互式文档 http://127.0.0.1:8000/docs 来快速进行接口验证。

七、路径参数中包含文件路径

当路径参数中包含文件路径时,比如 /files/{file_path},我们可以用声明file_path类型的方式进行支持。

/files/{file_path:path}

这里:path指出了file_path可以匹配任何文件路径。

from fastapi import FastAPI

app = FastAPI()


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

八、路径操作的其他参数

我们可以在路径操作中添加其他参数,比如标签列表。

@app.post("/items/", response_model=Item, tags=["items"])
async def create_item(*, item: Item):
    return item


@app.get("/items/", tags=["items"])
async def read_items():
    return [{"name": "Foo", "price": 42}]


@app.get("/users/", tags=["users"])
async def read_users():
    return [{"username": "johndoe"}]

也可以添加summarydescription参数。

@app.post(
    "/items/",
    response_model=Item,
    summary="Create an item",
    description="Create an item with all the information, name, description, price, tax and a set of unique tags",
)

以及文档字符串。

@app.post("/items/", response_model=Item, summary="Create an item")
async def create_item(*, item: Item):
    """
    Create an item with all the information:

    - **name**: each item must have a name
    - **description**: a long description
    - **price**: required
    - **tax**: if the item doesn't have tax, you can omit this
    - **tags**: a set of unique tag strings for this item
    """
    return item

或者deprecated参数表示该路径操作已过期。

@app.get("/elements/", tags=["items"], deprecated=True)
async def read_elements():
    return [{"item_id": "Foo"}]

 

可以在交互式文档中查看显示效果。(略)

 

posted on 2020-05-12 14:53  麦克煎蛋  阅读(3579)  评论(0编辑  收藏  举报