I have a returned result from a webservice, whose values come as they are (see example). The keys are not Optional and must be included.
2 validation errors for Result:
- cause –
str type expected (type=type.error.str)
- urls –
str type expected (type=type.error.str)
{ 'code': 0, 'codetext': 'blablabla', 'status': None, 'cause': None, 'urls': None }
class Result(BaseModel): code: int codetext: str status: str = "" cause: str = "" urls: str = "" @validator("status", "cause", "urls") def replace_none(cls, v): return v or "None"
First questions is, what is the correct way to handle the None values coming as answer from the webservice and set to ‘None’ (with single-quotation marks and None as String) and secondly, why are there only 2 and not 3 errors?
Advertisement
Answer
You can mark fields as required but optional by declaring the field optional and using ellipsis (...
) as its value. Here is a complete, simplified example with tests to verify it works (execute with pytest <file>
):
import pytest from pydantic import BaseModel, ValidationError, validator class Result(BaseModel): code: int status: str | None = ... @validator("status") def replace_none(cls, v): return v or "None" def test_result(): p = Result.parse_obj({"code": 1, "status": "test status"}) assert p.code == 1 assert p.status == "test status" def test_required_optionals(): """Test that missing fields raise an error.""" with pytest.raises(ValidationError): Result.parse_obj({"code": 1}) def test_required_optional_accepts_none(): """Test that none values are accepted.""" p = Result.parse_obj( { "code": 0, "status": None, } ) assert p.status == "None"