Читать список JSON тела с FastAPI - PullRequest
0 голосов
/ 25 марта 2020

Тело HTTP-запроса PUT представляет собой список JSON, например:

[item1, item2, item3, ...]

Я не могу это изменить. (Если бы root был JSON объектом, а не списком, проблем не было бы.)

Используя FastAPI, я не могу получить доступ к этому контенту обычным способом:

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

Я нашел следующий обходной путь, который выглядит как очень уродливый хак:

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 и pydanti c. Чего мне не хватает?

1 Ответ

1 голос
/ 25 марта 2020

Спуск с перспективы модели к примитивам

В 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 записи вашего списка имеют - вы также go для правильного моделирования типов, но вы хотите напрямую получать и обрабатывать список без обертки JSON вокруг него. Вы могли бы go для:

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"}]

Это, вероятно, то, что вы ищете, и последняя адаптация к дубль зависит от формы вашего предмета * в списке, который вы получите. Если это простые строки, вы также можете go для:

from typing import List

def process_item_list(items: List[str]):
    pass

, которые могут обрабатывать JSON, как

["John", "Mary"]

Я обозначил путь от моделей до примитивов в списках, потому что Я думаю, что стоит знать, где это может go, если требуется более сложная модель данных.

...