zoukankan      html  css  js  c++  java
  • FastAPI Response(一) Response模型

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

    一、Response模型

    在路径操作中,我们可以用参数response_model来声明Response模型。

    from typing import List
    from fastapi import FastAPI
    from pydantic import BaseModel
    
    app = FastAPI()
    
    
    class Item(BaseModel):
        name: str
        description: str = None
        price: float
        tax: float = None
        tags: List[str] = []
    
    
    @app.post("/items/", response_model=Item)
    async def create_item(item: Item):
        return item

    注意response_model是装饰器方法(get,post等)的参数。

    Response模型可以是一个Pydantic模型,也可以是一个Pydantic模型的列表,例如List[Item]。

    支持任意路径操作:

    @app.get()
    @app.post()
    @app.put()
    @app.delete()

    FastAPI利用Response模型实现以下功能:

    1、将输出数据转换成声明的Response模型。

    2、对数据进行校验

    3、生成自动化文档

    4、(最重要的)限制输出数据只能是所声明的Response模型。

    二、输入输出模型示例

    # 可能需要安装email-validator  -->  pip install email-validator 

    from
    fastapi import FastAPI from pydantic import BaseModel, EmailStr app = FastAPI() class UserIn(BaseModel): username: str password: str email: EmailStr full_name: str = None class UserOut(BaseModel): username: str email: EmailStr full_name: str = None @app.post("/user/", response_model=UserOut) async def create_user(*, user: UserIn): return user

    如上所示,虽然路径操作函数返回的结果是user(包含了password),但我们声明的Response模型是UserOut(不包含password)。

    FastAPI会过滤掉所有不在输出模型中的数据,因此最终的输出结果里并没有password。

    如果输入内容如下:

    {
        "username": "user",
        "password": "1234",
        "email": "user@qq.com",
        "full_name": "full_name"
    }

    那么输出结果为:

    {
        "username": "user",
        "email": "user@qq.com",
        "full_name": "full_name"
    }

    三、Response模型参数

    1、Response模型可以有缺省值。

    from typing import List
    
    from fastapi import FastAPI
    from pydantic import BaseModel
    
    app = FastAPI()
    
    
    class Item(BaseModel):
        name: str
        description: str = None
        price: float
        tax: float = 10.5
        tags: List[str] = []
    
    
    items = {
        "foo": {"name": "Foo", "price": 50.2},
        "bar": {"name": "Bar", "description": "The bartenders", "price": 62, "tax": 20.2},
        "baz": {"name": "Baz", "description": None, "price": 50.2, "tax": 10.5, "tags": []},
    }
    
    
    @app.get("/items/{item_id}", response_model=Item, response_model_exclude_unset=True)
    async def read_item(item_id: str):
        return items[item_id]

    2、返回实际有效数据

    有时候我们只想返回被真正设置过的数据,而忽略其他未被设置过的或者缺省数据。

    我们可以用参数response_model_exclude_unset来实现这个目的。如上所示代码。

    # 访问:
    http://127.0.0.1:8000/items/foo

    # 返回结果:
    {
        "name": "Foo",
        "price": 50.2
    }

    3、参数 response_model_includeresponse_model_exclude

    这两个参数接收Response模型的部分属性集合,分别表示包含(排除剩下的)和排除(包含剩下的)集合里的属性。

    在实际工作中,我们应该尽量少利用这两个参数,而是应该声明不同的类表示不同的数据需求,这样更利于数据维护和逻辑清晰。

    from fastapi import FastAPI
    from pydantic import BaseModel
    
    app = FastAPI()
    
    
    class Item(BaseModel):
        name: str
        description: str = None
        price: float
        tax: float = 10.5
    
    
    items = {
        "foo": {"name": "Foo", "price": 50.2},
        "bar": {"name": "Bar", "description": "The Bar fighters", "price": 62, "tax": 20.2},
        "baz": {
            "name": "Baz",
            "description": "There goes my baz",
            "price": 50.2,
            "tax": 10.5,
        },
    }
    
    
    @app.get("/items/{item_id}/name", response_model=Item, response_model_include={"name", "description"})
    async def read_item_name(item_id: str):
        return items[item_id]
    
    
    @app.get("/items/{item_id}/public", response_model=Item, response_model_exclude={"tax"})
    async def read_item_public_data(item_id: str):
        return items[item_id]

    四、Response联合模型

    我们可以声明Response模型是一个Union类型(包含两种类型),实际返回结果可以是Union其中任何一个。

    from typing import Union
    from fastapi import FastAPI
    from pydantic import BaseModel
    
    app = FastAPI()
    
    
    class BaseItem(BaseModel):
        description: str
        type: str
    
    
    class CarItem(BaseItem):
        type = "car"
    
    
    class PlaneItem(BaseItem):
        type = "plane"
        size: int
    
    
    items = {
        "item1": {"description": "All my friends drive a low rider", "type": "car"},
        "item2": {
            "description": "Music is my aeroplane, it's my aeroplane",
            "type": "plane",
            "size": 5,
        },
    }
    
    
    @app.get("/items/{item_id}", response_model=Union[PlaneItem, CarItem])
    async def read_item(item_id: str):
        return items[item_id]

    这里PlaneItem、CarItem均从BaseItem继承而来,提高代码复用,也便于代码维护。

    五、Response列表模型

    Response模型也可以是一个列表。

    from typing import List
    from fastapi import FastAPI
    from pydantic import BaseModel
    
    app = FastAPI()
    
    
    class Item(BaseModel):
        name: str
        description: str
    
    
    items = [
        {"name": "Foo", "description": "There comes my hero"},
        {"name": "Red", "description": "It's my aeroplane"},
    ]
    
    
    @app.get("/items/", response_model=List[Item])
    async def read_items():
        return items

    六、Response字典模型

    我们也可以不用Pydantic模型,而是直接基于字典来声明Response模型。

    from typing import Dict
    from fastapi import FastAPI
    
    app = FastAPI()
    
    
    @app.get("/keyword-weights/", response_model=Dict[str, float])
    async def read_keyword_weights():
        return {"foo": 2.3, "bar": 3.4}
  • 相关阅读:
    使用Stream方式处理集合元素
    Consumer方法结合Lambda表达式的应用
    java-遍历字符串的两种方式:1.char charAt(int index);2.char[] toCharArray()
    java-成员变量与局部变量的测试
    java-统计字符串中各字符次数
    java-字符串的遍历和字符串数组的遍历
    java-String类的获取方法(indexOf();substring()等)
    java-模拟登陆练习
    java-String类中的各字符串判断(包括" "和null的区别)
    java-String类的常见面试题
  • 原文地址:https://www.cnblogs.com/mazhiyong/p/12942241.html
Copyright © 2011-2022 走看看