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)
JavaScript
x
3
1
{ 'code': 0, 'codetext': 'blablabla', 'status': None, 'cause': None, 'urls': None }
2
3
JavaScript
1
13
13
1
class Result(BaseModel):
2
3
code: int
4
codetext: str
5
status: str = ""
6
cause: str = ""
7
urls: str = ""
8
9
@validator("status", "cause", "urls")
10
def replace_none(cls, v):
11
return v or "None"
12
13
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>
):
JavaScript
1
36
36
1
import pytest
2
from pydantic import BaseModel, ValidationError, validator
3
4
5
class Result(BaseModel):
6
code: int
7
status: str | None =
8
9
@validator("status")
10
def replace_none(cls, v):
11
return v or "None"
12
13
14
def test_result():
15
p = Result.parse_obj({"code": 1, "status": "test status"})
16
assert p.code == 1
17
assert p.status == "test status"
18
19
20
def test_required_optionals():
21
"""Test that missing fields raise an error."""
22
with pytest.raises(ValidationError):
23
Result.parse_obj({"code": 1})
24
25
26
def test_required_optional_accepts_none():
27
"""Test that none values are accepted."""
28
p = Result.parse_obj(
29
{
30
"code": 0,
31
"status": None,
32
}
33
)
34
assert p.status == "None"
35
36