【问题标题】:Read a body JSON list with FastAPI使用 FastAPI 读取正文 JSON 列表
【发布时间】:2020-07-05 18:18:42
【问题描述】:

HTTP PUT 请求的主体是一个 JSON 列表 - 像这样:

[item1, item2, item3, ...]

我无法改变这一点。 (如果根是 JSON 对象而不是列表,则没有问题。)

使用 FastAPI 我似乎无法以正常方式访问此内容:

@router.put('/data')
def set_data(data: DataModel): # This doesn't work; how do I even declare DataModel?

我找到了以下解决方法,这似乎是一个非常丑陋的 hack:

class DataModel(BaseModel):
    __root__: List[str]


from fastAPI import Request

@router.put('/data')
async def set_data(request: Request): # Get the request object directly
    data = DataModel(__root__=await request.json())

这肯定不是实现这一目标的“认可”方式。我已经浏览了 FastAPI 和 pydantic 的文档。我错过了什么?

【问题讨论】:

    标签: python fastapi pydantic


    【解决方案1】:

    从模型角度下降到基元

    在 FastAPI 中,您从 BaseModel 派生来描述您发送和接收的数据模型(即,FastAPI 还为您从正文解析并转换为 Python 对象)。另外,它依赖于pydantic的建模和处理。

    from typing import List
    from pydantic import BaseModel
    
    class Item(BaseModel):
        name: str
    
    class ItemList(BaseModel):
        items: List[Item]
    
    def process_item_list(items: ItemList):
        pass
    

    这个例子可以像解析 JSON 一样

    {"items": [{"name": "John"}, {"name": "Mary"}]}
    

    在您的情况下 - 取决于您的列表条目的 shape - 您还需要进行适当的类型建模,但您希望直接接收和处理列表而不需要 JSON dict 包装器.你可以去:

    from typing import List
    from pydantic import BaseModel
    
    class Item(BaseModel):
        name: str
    
    def process_item_list(items: List[Item]):
        pass
    

    现在可以像这样处理 JSON:

    [{"name": "John"}, {"name": "Mary"}]
    

    这可能是您正在寻找的内容,最后一次调整取决于您收到的列表中 item* 的形状。如果是纯字符串,也可以选择:

    from typing import List
    
    def process_item_list(items: List[str]):
        pass
    

    可以像处理 JSON 一样

    ["John", "Mary"]
    

    我概述了从模型到列表中的原语的路径,因为我认为如果需要更复杂的数据模型,那么值得了解它的发展方向。

    【讨论】:

    • 我以为我已经尝试了上述方法,但显然在此过程中犯了一些错误并排除了它。非常感谢。
    • 我为什么不发布最后一个选项?是的,这看起来会更好,但 API 规范说整个列表都被重写了。
    • 不,最后一个标题是对我自己的一个问题——也许它措辞不当,但我想证明我为什么会走这么远;)
    • 我也尝试返回一个没有名称的数组,如下所示; class ListItem(baseModel) List[Item] 以某种方式正在打印但无法输出。 class ListItem(List[Item]) pass 救了我的命,谢谢伙计
    猜你喜欢
    • 1970-01-01
    • 2021-01-30
    • 2020-09-04
    • 2021-02-01
    • 2020-10-18
    • 2020-09-01
    • 1970-01-01
    • 2019-09-04
    • 1970-01-01
    相关资源
    最近更新 更多