Skip to content

Instantly share code, notes, and snippets.

@lmmx
Created August 14, 2024 21:22
Show Gist options
  • Save lmmx/b4e3a70dbb0db58662c628eccbad1aea to your computer and use it in GitHub Desktop.
Save lmmx/b4e3a70dbb0db58662c628eccbad1aea to your computer and use it in GitHub Desktop.
Separating extra keys in an `extra` key (either implied by the validator or explicitly in the model)
from pydantic import BaseModel, model_validator
class Model(BaseModel, extra="allow"):
a: int
b: int
@model_validator(mode="before")
@classmethod
def pop_off_extra(cls, values: dict):
fields = list(cls.model_fields)
known, extra = {}, {}
for k,v in values.items():
target = known if k in fields else extra
target.update({k:v})
assert "extra" not in known, "The key 'extra' is a reserved field"
return dict(**known, extra=extra)
data = dict(a=1, b=2)
more = dict(a=1, b=2, c={"value": 3})
normal = Model.model_validate(data)
plus_c = Model.model_validate(more)
print(f"{normal=}") # normal=Model(a=1, b=2, extra={})
print(f"{plus_c=}") # plus_c=Model(a=1, b=2, extra={'c': {'value': 3}})
from pydantic import BaseModel, model_validator
class Model(BaseModel):
a: int
b: int
extra: dict
@model_validator(mode="before")
@classmethod
def pop_off_extra(cls, values: dict):
fields = list(cls.model_fields)
known, extra = {}, {}
for k,v in values.items():
target = known if k in fields else extra
target.update({k:v})
assert "extra" not in known, "The key 'extra' is a reserved field"
return dict(**known, extra=extra)
data = dict(a=1, b=2)
more = dict(a=1, b=2, c={"value": 3})
normal = Model.model_validate(data)
plus_c = Model.model_validate(more)
print(f"{normal=}") # normal=Model(a=1, b=2, extra={})
print(f"{plus_c=}") # plus_c=Model(a=1, b=2, extra={'c': {'value': 3}})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment