Poniższy kod odbiera JSON, który został opublikowany na serwerze fastapi. Fastapi sprawia, że jest dostępny w funkcji jako model Pydantic. Mój przykładowy kod przetwarza go przez zapisanie pliku. Nie podoba mi się (i wydaje się być efektem ubocznym używania listy Pydantic) jest to, że muszę pętli dookoła, aby uzyskać jakąś użyteczny JSON.

Jak mogę to zrobić bez zapętlenia?

Czuję, że musi być możliwe, bo return images po prostu działa.

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/
'''

Przykład jest rozszerzony z Dokumenty Fastapi

1
snow6oy 21 listopad 2020, 18:39

1 odpowiedź

Najlepsza odpowiedź

Aby zrzucić listę obiektów modelowych bez pętli, Pydantic zapewnia możliwość definiowania modelu z niestandardowym typem korzenia.

Oto niewielki przykład tego, jak wygląda:

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))

A definicja operacji ścieżki wyglądałaby tak:

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