Search code examples
pythonfastapipydantic

Using FastAPI & Pydantic, how do I define an Optional field with a description


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?


Solution

  • 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.