zoukankan      html  css  js  c++  java
  • FastAPI(8)- 请求体 Request Body

    前言

    • 接口传参方式之一:通过发送请求体(Request Body)来传递请求数据
    • 在 FastAPI,提倡使用 Pydantic 模型来定义请求体
    • 这篇文章会详细讲不使用 Pydantic 和 使用 Pydantic 发送请求体的栗子

    注意

    • 请求体并不是只有 POST 请求有,只不过 POST 更常见
    • 在 PUT、DELETE、PATCH 请求中都可以使用请求体
    • 其实,在 GET 请求中也可以用请求体,不过仅适用于非常极端的情况下,而且 Swagger API 并不会显示 GET 请求的请求体

    不使用 Pydantic的栗子

    from fastapi import FastAPI
    import uvicorn
    
    app = FastAPI()
    
    
    @app.post("/items")
    async def read_item(item: dict):
        return {"item": item}
    
    
    if __name__ == "__main__":
        uvicorn.run(app="6_request:app", host="127.0.0.1", port=8080, reload=True, debug=True)

    指定查询参数的类型为 dict

    正确传参的请求结果

    查看请求头

    是 json 格式,符合预期 

    重点

    • 用 postman 发起请求的话,一定要选 JSON 格式哦
    • 因为接收的是 dict,所以 FastAPI 会自动将 JSON 字符串转换为 dict
    • 这种场景下,虽然查询参数叫 item,但请求体的字段名可以随意取,字段数量也可以任意个

    错误传参的请求结果

    选了 text 之后,因为不是 JSON 字符串,FastAPI 无法正确解析请求体为 dict,所以会报类型错误的提示

    查看请求头

     

    类型是 text

    用 Dict 代替 dict 的栗子

    Dict 是 typing 模块提供的类,可以指定键值对的数据类型

    from typing import Dict
    
    from fastapi import FastAPI
    
    app = FastAPI()
    
    
    @app.post("/Dict/")
    # 键为 str,值为 float
    async def create_index_weights(weights: Dict[str, float]):
        return weights

    使用 Dict 相比直接用 dict 的好处

    声明为 Dict[str, float],FastAPI 会对每一个键值对都做数据校验,校验失败会有友好的错误提示

    正确传参的请求结果

    校验失败的请求结果

    友好的错误提示啊~

    使用 Pydantic 模型(建议使用)

    实际栗子

    from fastapi import FastAPI
    from typing import Optional
    from pydantic import BaseModel
    
    app = FastAPI()
    
    
    # 自定义一个 Pydantic 模型
    class Item(BaseModel):
        name: str
        description: Optional[str] = None
        price: float
        tax: Optional[float] = None
    
    
    @app.post("/items/")
    # item 参数的类型指定为 Item 模型
    async def create_item(item: Item): 
        return item

    参数指定为 Pydantic 模型后,FastAPI 做了这几件事

    1. 将请求体识别为 JSON 字符串
    2. 将字段值转换相应的类型(若有需要)
    3. 验证数据,如果验证失败,会返回一个清晰的错误,准确指出错误数据的位置和信息
    4. item 会接收到完整的请求体数据,拥有所有属性及其类型,IDE 也会给予对应的智能提示
    5. 给 Pydantic 模型自动的生成 JSON Schema,这些 Schema 会成为生成 OpenAPI Schema 的一部分,并显示在接口文档上

    正确传参的请求结果

    正常传参,所有属性按指定的类型进行传数据

    字段值类型自动转换

    •  name: str  传了 bool 类型的数据
    •  description: str  传了 float 类型的数据
    •  price: float   传了 int 类型的数据
    •  tax: float  传了 bool 类型的数据

    FastAPi 会将传进来的值自动转换为指定类型的值

    • 将 true 转成 str 类型,即 "True"
    • 将 12.22 转成 str 类型,即 "12.22"
    • 将 12 转成 float 类型,即 12.0
    • 将 true 转成 float 类型,即 1.0

    如果转换失败,则会报 type_error 错误(如下图)

    验证数据失败的请求结果

    查看 Swagger API 文档

    Schema 部分

    model 的 JSON Schema 会成为 Swagger APi 文档的一部分

    示例值部分

    IDE 智能提示

    因为知道 name 属性的类型是 str,所以 IDE 会智能提示 str 内置的方法

    Request body + path + query parameters 综合栗子

    • 可以同时声明请求体、路径参数、查询参数
    • FastAPI 可以识别出它们中的每一个,并从正确的位置获取到数据

    实际代码

    from typing import Optional
    from fastapi import FastAPI
    from pydantic import BaseModel
    
    
    class Item(BaseModel):
        name: str
        description: Optional[str] = None
        price: float
        tax: Optional[float] = None
    
    
    app = FastAPI()
    
    
    @app.put("/items/{item_id}")
    async def create_item(
            # 路径参数
            item_id: int,
            # 请求体,模型类型
            item: Item,
            # 查询参数
            name: Optional[str] = None):
        result = {"item_id": item_id, **item.dict()}
        print(result)
        if name:
            # 如果查询参数 name 不为空,则替换掉 item 参数里面的 name 属性值
            result.update({"name": name})
        return result

    FastAPI 识别参数的逻辑

    • 如果参数也在路径中声明,它将解释为路径参数【item_id】
    • 如果参数是单数类型(如int、float、str、boo l等),它将被解释为查询参数【name】
    • 如果参数被声明为 Pydantic 模型的类型,它将被解析为请求体【item】

    正确传参的请求结果

    Pycharm Console 输出结果

    打印 result 的值

    {'item_id': 1234, 'name': '小菠萝', 'description': '描述,非必填', 'price': 12.22, 'tax': 0.0}

    查看 Swagger API 文档

  • 相关阅读:
    程序从命令行接收多个数字,求和之后输出结果。
    动态规划(1)
    软件工程个人作业(4)
    冲刺2 01
    构建之法
    水王
    大道至简第七章读后感
    构建之法03
    团队冲刺第四天
    团队冲刺第三天
  • 原文地址:https://www.cnblogs.com/poloyy/p/15309691.html
Copyright © 2011-2022 走看看