简体   繁体   中英

Pydantic - Unable to serialize/validate while using “Union” with “Field” in response_model

  • OS: Ubuntu 18.04.4 LTS
  • Python version: 3.7.7
  • Pydantic version: 1.4

I'm trying to make the class TableSetting as BaseModel and take it as response body . But seems like there are some validation or serialization errors in this class. I guess it might be Union or Optional[str] that I ues but not sure.

Source code

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

The json schema of class TableSetting should look like this

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

While performing curl

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

it return errors as follows with response code 500, Internal Server Error , seems like some there are some validation problems with kitchen but I can't figure out why.

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)

However, when remove = Field(..., title="I a title") from the code as follows. It's works fine with a response code 200 , but since I need Item kitchen as required, so it's not what I want.

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

How can I fix this?

Thanks

according to the doc Union it's accept different type, but not both, instead of this you should use tuple with (required, optional) something like that

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)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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