Динамическое тело в FastApi с использованием Pydantic - PullRequest
0 голосов
/ 26 марта 2020

Я хотел бы иметь динамическое обязательное тело в FastApi.

Я объясняю:

from fastapi import FastAPI, Body
from pydantic import BaseModel

app = FastAPI()

class Parameters(BaseModel):
    platform: str
    country: str

@app.put("/myroute")
async def provision_instance(*, parameters: Parameters = Body(...)):
    do_something

if __name__ == '__main__':
    uvicorn.run(app, host="0.0.0.0", port=80)

Здесь мое тело определяется вручную в классе Parameters с двумя атрибутами: platform и страна. В будущем эти атрибуты будут поступать из файла конфигурации, и их будет более двух. Поэтому мне нужно будет создавать их автоматически на лету.

Например, в файле конфигурации я мог бы иметь:

---
parameters:
  application:
    description: "Name of the application"
    type: string
  platform:
    description: "Name of the platform"
    type: string
  country:
    description: "Name of the country"
    type: string

Как я мог бы иметь в этом контексте переменное количество параметров, необходимых в теле? Должен ли я найти способ дать моему классу параметров переменное количество атрибутов?

1 Ответ

0 голосов
/ 04 апреля 2020
Модели

Pydanti c могут создаваться динамически, как описано в этом разделе документации. Вам все равно придется реализовать функцию, которая будет считывать ваш файл yaml и строить из него модель Pydanti c.


Теперь рассмотрим несколько моделей Pydanti c в файле python; разве это не эквивалентно наличию файла yaml, описывающего модели?


Если вы придумали этот план динамического построения моделей Pydanti c, потому что у вас будет многократная форма поступающих данных, вы может также изучить использование typing.Union для определения вашей конечной точки:


class Parameters1(BaseModel):
    platform: str
    country: str


class Parameters2(BaseModel):
    application: str
    country: str


@app.put("/myroute")
async def provision_instance(*, parameters: Union[Parameters1, Parameters2] = Body(...)):
    if isinstance(parameters, Parameters1):
        pass  # TODO
    elif isinstance(parameters, Parameters2):
        pass  # TODO

...