• 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"}]

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

  • 相关阅读:
    简单的测试用例计划放法
    黑盒测试用例设计方法-等价类划分
    Redis净化板
    爬虫部署与Django
    怎样实现前端的优化
    关于Apache简介笔记
    yield生成器的经典案例
    石头剪刀布
    函数内是否可以修改传递进来的列表
    不定长参数的传递
  • 原文地址:https://www.cnblogs.com/mazhiyong/p/12871349.html
Copyright © 2020-2023  润新知