简体   繁体   English

使用 Pydantic 嵌套模型从 FastAPI 获取 JSON

[英]Obtain JSON from FastAPI using Pydantic Nested Models

The following code receives some JSON that was POSTed to a FastAPI server.以下代码接收一些已发布到 FastAPI 服务器的 JSON。 FastAPI makes it available within a function as a Pydantic model. FastAPI 使其在函数中作为 Pydantic 模型可用。 My example code processes it by writing a file.我的示例代码通过编写文件来处理它。 What I don't like (and it seems to be side-effect of using Pydantic List) is that I have to loop back around to get some usable JSON.我不喜欢的(似乎是使用 Pydantic List 的副作用)是我必须循环返回以获得一些可用的 JSON。

How can I do this without looping?如何在不循环的情况下执行此操作?

I feel it must be possible because return images just works.我觉得这一定是可能的,因为return images才有效。

from typing import List

from fastapi import FastAPI
from pydantic import BaseModel
import json

app = FastAPI()

class Image(BaseModel):
    url: str
    name: str

@app.post("/images/multiple/")
async def create_multiple_images(images: List[Image]):
  #return images             # returns json string
  #print(images)             # prints an Image object
  #print(images.json())      # AttributeError: 'list' object has no attribute 'json'
  #print(json.dumps(images)) # TypeError: Object of type Image is not JSON serializable
  img_data = list()          # does it really have to be this way?
  for i in images:
    img_data.append(i.dict())
  with open('./images.json', 'w') as f:  
    json.dump(img_data, f, indent=2)

'''
curl -v -d '[{"name":"wilma","url":"http://this.com"},{"name":"barney","url":"http://that.com"}]' http://localhost:8000/images/multiple/
'''

The example is expanded from the FastAPI docs该示例扩展自FastAPI 文档

To dump a list of model objects without loops, pydantic provides the ability to define a model with a custom root type .为了在没有循环的情况下转储模型对象列表,pydantic 提供了定义具有自定义根类型的模型的能力。

Here is a small example of how it looks:这是它的外观的一个小例子:

class Image(BaseModel):
    url: str
    name: str


class Images(BaseModel):
    __root__: List[Image]


images_raw = '[{"url":"url1", "name":"name1"}, {"url":"url2", "name":"name2"}]'
images = parse_raw_as(Images, images_raw)

with open('./images.json', 'w') as f:
    f.write(images.json(indent=2))

And the definition of your path operation would look like this:您的路径操作的定义如下所示:

@app.post("/images/multiple/")
async def create_multiple_images(images: Images):
    with open('./images.json', 'w') as f:
        f.write(images.json(indent=2))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM