Pydanti c - Невозможно сериализовать / проверять при использовании «Union» с «Field» в response_model - PullRequest
0 голосов
/ 22 апреля 2020
  • ОС: Ubuntu 18.04.4 LTS
  • Python версия: 3.7.7
  • Pydanti c версия: 1.4

I Я пытаюсь сделать class TableSetting как BaseModel и принять его за response body. Но, похоже, в этом классе есть некоторые ошибки валидации или сериализации. Я думаю, это может быть Union или Optional[str], который я использую, но не уверен.

Исходный код

from fastapi import FastAPI, Query, Body, Path
from pydantic import BaseModel, Field
from typing import Union, Optional
from enum import Enum


app = FastAPI()


class Tableware(str, Enum):
    SPOON= "SPOON"
    FORK= "FORK"

class TableSetting(BaseModel):
    kitchen: Union[Tableware, Optional[str]] = Field(..., title="I am title")
    numberOfknife: int = Field(None, ge=0, le=4)

@app.post(
    "/{tableNumber}/provide-table-setting",
    response_model= TableSetting,    
)

def provide_table_setting(
    *,
    tableNumber: str= Path(...),
):
    results = {"tableNumber": tableNumber}
    return results

Схема json class TableSetting должна выглядеть следующим образом

TableSetting{
    kitchen*        I am title{
                        anyOf ->    string  
                                    Enum:
                                        [ SPOON, FORK ]
                                    string
                    }
    numberOfknife   integer
                    maximum: 4
                    minimum: 0
}

При выполнении curl

curl -X POST "http://localhost:8000/2/provide-table-setting" -H  "accept: application/json"

он возвращает ошибки следующим образом с кодом ответа 500, Внутренняя ошибка сервера , кажется, что есть некоторые проблемы с проверкой с kitchen, но я не могу понять, почему.

INFO:     127.0.0.1:53558 - "POST /2/provide-table-setting HTTP/1.1" 500 Internal Server Error
ERROR:    Exception in ASGI application
Traceback (most recent call last):
  File "/home/*****/miniconda3/envs/fastAPI/lib/python3.7/site-packages/uvicorn/protocols/http/httptools_impl.py", line 385, in run_asgi
    result = await app(self.scope, self.receive, self.send)
.
.
.
  File "/home/*****/miniconda3/envs/fastAPI/lib/python3.7/site-packages/fastapi/routing.py", line 126, in serialize_response
    raise ValidationError(errors, field.type_)
pydantic.error_wrappers.ValidationError: 1 validation error for TableSetting
response -> kitchen
  field required (type=value_error.missing)

Однако, когда удалите = Field(..., title="I a title") из кода следующим образом. Он отлично работает с кодом ответа 200 , но так как мне нужно Item kitchen, как требуется, поэтому это не то, что я хочу.

class TableSetting(BaseModel):
    kitchen: Union[Tableware, Optional[str]]
    numberOfknife: int = Field(None, ge=0, le=4)

Как я могу это исправить?

Спасибо

1 Ответ

0 голосов
/ 22 апреля 2020

в соответствии с do c Union он принимает другой тип, но не оба, вместо этого вам следует использовать кортеж с (обязательным, необязательным) чем-то подобным

from typing import Optional, Tuple
class TableSetting(BaseModel):
    kitchen: Tuple[Tableware, Optional[str]] = (None, Field(..., title="I am title"))
    #kitchen: Union[Tableware, Optional[str]] 
    numberOfknife: int = Field(None, ge=0, le=4)
...