Pydantic v2
You can use the extra field in the model_config class attribute to forbid extra attributes during model initialisation (by default, additional attributes will be ignored).
For example:
from pydantic import BaseModel, ConfigDict
class Pet(BaseModel):
model_config = ConfigDict(extra="forbid")
name: str
data = {
"name": "some name",
"some_extra_field": "some value",
}
my_pet = Pet.model_validate(data) # <- effectively the same as Pet(**pet_data)
will raise a ValidationError:
ValidationError: 1 validation error for Pet
some_extra_field
Extra inputs are not permitted [type=extra_forbidden, input_value='some value', input_type=str]
For further information visit https://errors.pydantic.dev/2.7/v/extra_forbidden
Works as well when the model is "nested", e.g.:
class PetModel(BaseModel):
my_pet: Pet
n: int
pet_data = {
"my_pet": {"name": "Some Name", "invalid_field": "some value"},
"n": 5,
}
pet_model = PetModel.model_validate(pet_data)
# Effectively the same as
# pet_model = PetModel(my_pet={"name": "Some Name", "invalid_field": "some value"}, n=5)
will raise:
ValidationError: 1 validation error for PetModel
my_pet.invalid_field
Extra inputs are not permitted [type=extra_forbidden, input_value='some value', input_type=str]
For further information visit https://errors.pydantic.dev/2.7/v/extra_forbidden
NB: As you can see, extra has the type ExtraValues now, and its value will get validated by ConfigDict. This means it's not possible to accidentally provide an unsupported value for extra (e.g. having a typo), i.e. something like ConfigDict(extra="fordib") will fail with a SchemaError.
Pydantic v1
You can use the extra field in the Config class to forbid extra attributes during model initialisation (by default, additional attributes will be ignored).
For example:
from pydantic import BaseModel, Extra
class Pet(BaseModel):
name: str
class Config:
extra = Extra.forbid
data = {
"name": "some name",
"some_extra_field": "some value",
}
my_pet = Pet.parse_obj(data) # <- effectively the same as Pet(**pet_data)
will raise a VaidationError:
ValidationError: 1 validation error for Pet
some_extra_field
extra fields not permitted (type=value_error.extra)
Works as well when the model is "nested", e.g.:
class PetModel(BaseModel):
my_pet: Pet
n: int
pet_data = {
"my_pet": {"name": "Some Name", "invalid_field": "some value"},
"n": 5,
}
pet_model = PetModel.parse_obj(pet_data)
# Effectively the same as
# pet_model = PetModel(my_pet={"name": "Some Name", "invalid_field": "some value"}, n=5)
will raise:
ValidationError: 1 validation error for PetModel
my_pet -> invalid_field
extra fields not permitted (type=value_error.extra)
Answer from Paul P on Stack OverflowPydantic v2
You can use the extra field in the model_config class attribute to forbid extra attributes during model initialisation (by default, additional attributes will be ignored).
For example:
from pydantic import BaseModel, ConfigDict
class Pet(BaseModel):
model_config = ConfigDict(extra="forbid")
name: str
data = {
"name": "some name",
"some_extra_field": "some value",
}
my_pet = Pet.model_validate(data) # <- effectively the same as Pet(**pet_data)
will raise a ValidationError:
ValidationError: 1 validation error for Pet
some_extra_field
Extra inputs are not permitted [type=extra_forbidden, input_value='some value', input_type=str]
For further information visit https://errors.pydantic.dev/2.7/v/extra_forbidden
Works as well when the model is "nested", e.g.:
class PetModel(BaseModel):
my_pet: Pet
n: int
pet_data = {
"my_pet": {"name": "Some Name", "invalid_field": "some value"},
"n": 5,
}
pet_model = PetModel.model_validate(pet_data)
# Effectively the same as
# pet_model = PetModel(my_pet={"name": "Some Name", "invalid_field": "some value"}, n=5)
will raise:
ValidationError: 1 validation error for PetModel
my_pet.invalid_field
Extra inputs are not permitted [type=extra_forbidden, input_value='some value', input_type=str]
For further information visit https://errors.pydantic.dev/2.7/v/extra_forbidden
NB: As you can see, extra has the type ExtraValues now, and its value will get validated by ConfigDict. This means it's not possible to accidentally provide an unsupported value for extra (e.g. having a typo), i.e. something like ConfigDict(extra="fordib") will fail with a SchemaError.
Pydantic v1
You can use the extra field in the Config class to forbid extra attributes during model initialisation (by default, additional attributes will be ignored).
For example:
from pydantic import BaseModel, Extra
class Pet(BaseModel):
name: str
class Config:
extra = Extra.forbid
data = {
"name": "some name",
"some_extra_field": "some value",
}
my_pet = Pet.parse_obj(data) # <- effectively the same as Pet(**pet_data)
will raise a VaidationError:
ValidationError: 1 validation error for Pet
some_extra_field
extra fields not permitted (type=value_error.extra)
Works as well when the model is "nested", e.g.:
class PetModel(BaseModel):
my_pet: Pet
n: int
pet_data = {
"my_pet": {"name": "Some Name", "invalid_field": "some value"},
"n": 5,
}
pet_model = PetModel.parse_obj(pet_data)
# Effectively the same as
# pet_model = PetModel(my_pet={"name": "Some Name", "invalid_field": "some value"}, n=5)
will raise:
ValidationError: 1 validation error for PetModel
my_pet -> invalid_field
extra fields not permitted (type=value_error.extra)
The preferred solution is to use a ConfigDict (ref. the documentation):
from pydantic import BaseModel, ConfigDict
class Pet(BaseModel):
model_config = ConfigDict(extra='forbid')
name: str
Paul P's answer still works (for now), but the Config class has been deprecated in pydantic v2.0.
Another deprecated solution is pydantic.Extra.forbid.
One advantage of the method above is that it can be type checked.
» pip install pydantic
Pydantic extra fields behaviour was updated in their 2.0 release. Per their docs, you now don't need to do anything but set the model_config extra field to allow and then can use the model_extra field or __pydantic_extra__ instance attribute to get a dict of extra fields.
from pydantic import BaseModel, Field, ConfigDict
class Model(BaseModel):
python_name: str = Field(alias="name")
model_config = ConfigDict(
extra='allow',
)
m = Model(**{"name": "Name", "address": "bla bla", "post": "post"}).model_extra
assert m == {'address': 'bla bla', 'post': 'post'}
m = Model(**{"name": "Name", "foobar": "fizz"}).__pydantic_extra__
assert m == {'foobar': 'fizz'}
m = Model(**{"name": "Name"}).__pydantic_extra__
assert m == {}
NOTE: This answer applies to version Pydantic 1.x. See robcxyz's answer for a 2.x solution.
From the pydantic docs:
extra
whether 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.
This can either be included in the model Config class, or as arguments when inheriting BaseModel.
from pydantic import BaseModel, Extra
class BaseModel(BaseModel, extra=Extra.allow):
name: str
model = Model.parse_obj(
{"name": "Name", "address": "bla bla", "post": "post"}
)
print(model)
# name='Name' post='post' address='bla bla'
To get the extra values you could do something simple, like comparing the set of __fields__ defined on the class to the values in __dict__ on an instance:
class Model(BaseModel, extra=Extra.allow):
python_name: str = Field(alias="name")
@property
def extra_fields(self) -> set[str]:
return set(self.__dict__) - set(self.__fields__)
>>> Model.parse_obj({"name": "Name", "address": "bla bla", "post": "post"}).extra_fields
{'address', 'post'}
>>> Model.parse_obj({"name": "Name", "foobar": "fizz"}).extra_fields
{'foobar'}
>>> Model.parse_obj({"name": "Name"}).extra_fields
set()