16

For a FastAPI Pydanctic class I have these values

class ErrorReportRequest(BaseModel):
    sender: Optional[str] = Field(..., description="Who sends the error message.")
    error_message_displayed_to_client: str = Field(..., description="The error message displayed to the client.")

I use the class as an input model

router = APIRouter()

@router.post(
    "/error_report",
    response_model=None,
    include_in_schema=True,

)
def error_report(err: ErrorReportRequest):
    pass

When I run this, sender is a required field. If it's not included in the incoming JSON, I get a validation error.

Input:

{
  "error_message_displayed_to_client": "string"
}

Results in:

{
  "detail": [
    {
      "loc": [
        "body",
        "sender"
      ],
      "msg": "field required",
      "type": "value_error.missing"
    }
  ]
}

If I remove the Field description like this:

    class ErrorReportRequest(BaseModel):
        sender: Optional[str]
        error_message_displayed_to_client: str = Field(..., description="The error message displayed to the client.")

the request passes.

How can I add a Field description to an optional field so that it's still allowed to omit the field name?

576i
  • 7,579
  • 12
  • 55
  • 92

1 Answers1

24

You'll need to provide an explicit default value to Field, for example None instead of ...:

class ErrorReportRequest(BaseModel):
    sender: Optional[str] = Field(None, description="Who sends the error message.")
    error_message_displayed_to_client: str = Field(..., description="The error message displayed to the client.")

... indicates that the value is required. This is of course in conflict with the Optional, but it looks like pydantic gives higher priority to ....

From the documentation of Field:

default: (a positional argument) the default value of the field. Since the Field replaces the field's default, this first argument can be used to set the default. Use ellipsis (...) to indicate the field is required.

mihi
  • 3,097
  • 16
  • 26
  • thanks for saving me from sandtrap #427 for fastapi/pydantic/typehints noobs that isn't made clear by docs/books/tutorials (this has been a frustrating experience) – odigity Jul 11 '23 at 14:34
  • also, that still leaves the problem of how to tell the difference between clients leaving the field out and clients explicitly setting the field to None – odigity Jul 11 '23 at 14:37
  • 1
    @odigity this answer might help with that: https://stackoverflow.com/a/66231175/5768147 – mihi Jul 11 '23 at 19:19