'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"
extrawhether to ignore, allow, or forbid extra attributes during model initialization. Accepts the string values of
'ignore','allow', or'forbid', or values of theExtraenum (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 | 
