'How to do exact one-to-one match validation with pydantic model schema?
How can I exactly match the Pydantic schema?
The suggested method is to attempt a dictionary conversion to the Pydantic model but that's not a one-one match.
I am using something similar for API response schema validation using pytest.
class Model_actual(BaseModel):
val1 : str
dict_to_be_validated = {'val1':'Hello', 'val2':'World'}
assert Model_actual(**dict_to_be_validated) is not None
I am looking for this assertion to fail instead of pass because it this is not a one-to-one match.
Solution 1:[1]
By default, pydantic BaseModel
's ignores extra fields (val2
in this case).
You can tell the model to forbid extra fields and raise a ValidationError
by setting the BaseModel
's Model Config extra
option.
class Model_actual(BaseModel):
val1: str
class Config:
extra = "forbid"
extra
whether to ignore, allow, or forbid extra attributes during model initialization. Accepts the string values of
'ignore'
,'allow'
, or'forbid'
, or values of theExtra
enum (default:Extra.ignore
).'forbid'
will cause validation to fail if extra attributes are included,'ignore'
will silently ignore any extra attributes, and'allow'
will assign the attributes to the model.
In [1]: from pydantic import BaseModel
...:
...: class Model_actual(BaseModel):
...: val1: str
...:
...: class Config:
...: extra = "forbid"
...:
In [2]: dict_to_be_validated = {"val1": "Hello", "val2": "World"}
In [3]: Model_actual(**dict_to_be_validated)
---------------------------------------------------------------------------
ValidationError Traceback (most recent call last)
Input In [3], in <cell line: 1>()
----> 1 Model_actual(**dict_to_be_validated)
File ~/path/to/venv/lib/python3.9/site-packages/pydantic/main.py:331, in pydantic.main.BaseModel.__init__()
ValidationError: 1 validation error for Model_actual
val2
extra fields not permitted (type=value_error.extra)
To catch that in a pytest test function, you let the test assert that an Exception is raised.
def test_model_ok():
dict_to_be_validated = {"val1": "Hello"}
obj = Model_actual(**dict_to_be_validated)
assert obj.val1 == "Hello"
def test_model_ng():
dict_to_be_validated = {"val1": "Hello", "val2": "World"}
with pytest.raises(ValidationError) as exc:
Model_actual(**dict_to_be_validated)
assert exc.value.errors()[0]["msg"] == "extra fields not permitted"
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 |