Optional str in Pydantic 2.0 with field constraints

478 Views Asked by At

I am trying to define an optional string field in Pydantic 2.0 that should follow the constraints (if provided), else pass None. However, none of the below implementation is working and it is giving the same error.

    Option1: 
    role_desc: Annotated[
    str | None,
    Field(
        min_length=5,
        max_length=200,
        examples=["Role description is provided here"],
        default=None,
    ),
]
   Option 2:
   role_desc: Annotated[
    Optional[str],
    Field(
        min_length=5,
        max_length=200,
        examples=["Role description is provided here"],
        default=None,
    ),
]
 Option 3:
 role_desc: str | None =
    Field(
        min_length=5,
        max_length=200,
        examples=["Role description is provided here"],
        default=None,
    ),
]

All of the above implementations are giving the same error.

{
  "detail": [
    {
      "type": "string_too_short",
      "loc": [
        "body",
        "role_desc"
      ],
      "msg": "String should have at least 5 characters",
      "input": "",
      "ctx": {
        "min_length": 5
      },
      "url": "https://errors.pydantic.dev/2.4/v/string_too_short"
    }
  ]
}

Is there any possible solution to have data field that validates only if some strings are provided, otherwise pass the None.

1

There are 1 best solutions below

0
Chris On

As described in this answer, when a field is declared as optional, users are not required to pass a value for that field in their HTTP request. Hence, users can leave that field out of the request, which, in that case, would default to None.

In your example, however, since you specify the input field's value in your client's HTTP request as "input": "", this means that you pass an empty str (which is not the same as None) for the input field, and hence, the restrictions specified for that Field() will be applied. In turn, that leads to the error that you got, i.e., "String should have at least 5 characters", since you specified min_length=5 in that Field(). Thus, if you need to keep the value for a field set to None, all you have to do is to avoid sending a value for it in the client's HTTP request.