Pydantic partial model class, with ability to easily dynamically omit fields when serializing a model.
Project description
Pydantic Partials
An easy way to add or create partials for Pydantic models.
Documentation
📄 Detailed Documentation | 🐍 PyPi
Quick Start
poetry install pydantic-partials
or
pip install pydantic-partials
By default, all fields without a default value will have the ability to be partial, and can be missing from both validation and serialization.
Very basic example is below:
from pydantic_partials import PartialModel, Missing
class MyModel(PartialModel):
some_attr: str
another_field: str
# By default, Partial fields without any value will get set to a special `Missing` type.
# Any field that is set to Missing is excluded from the model_dump/model_dump_json
obj = MyModel()
assert obj.some_attr is Missing
assert obj.model_dump() == {}
# You can set the real value at any time, and it will behave like expected.
obj.some_attr = 'hello'
assert obj.some_attr is 'hello'
assert obj.model_dump() == {'some_attr': 'hello'}
# You can always manually set a field to `Missing` directly.
obj.some_attr = Missing
# And now it's removed from the model-dump.
assert obj.model_dump() == {}
# The json dump is also affected in the same way.
assert obj.model_dump_json() == '{}'
# Any non-missing fields will be included when dumping/serializing model.
obj.another_field = 'assigned-value'
# And now it's removed from the model-dump.
assert obj.model_dump() == {'another_field': 'assigned-value'}
You can turn off this default behavior by via auto_partials
class argument or modeL_config option:
from pydantic_partials import PartialModel, PartialConfigDict
class TestModel1(PartialModel, auto_partials=False):
...
class TestModel2(PartialModel):
model_config = PartialConfigDict(auto_partials=False)
...
You can disable this automatic function. This means you have complete control of exactly which field
can be partial or not. You can use either the generic Partial[...]
generic or a union with MissingType
to mark a field as a partial field. The generic simple makes the union to MissingType for you.
Example of disabling auto_partials:
from pydantic_partials import PartialModel, Missing, MissingType, Partial
from decimal import Decimal
from pydantic import ValidationError
class TestModel(PartialModel, auto_partials=False):
# Can use `Partial` generic type
partial_int: Partial[int] = Missing
# Or union with `MissingType`
partial_str: str | MissingType
required_decimal: Decimal
try:
TestModel()
except ValidationError as e:
print(f'Pydantic will state `required_decimal` is required: {e}')
else:
raise Exception('Pydantic should have required `required_decimal`.')
obj = TestModel(required_decimal='1.34')
# You can find out at any time if a field is missing or not:
assert obj.partial_int is Missing
assert obj.partial_str is Missing
assert obj.required_decimal == Decimal('1.34')
You can inherit from a model to make a partial-version of the inherited fields:
from pydantic_partials import PartialModel, Missing
from pydantic import ValidationError, BaseModel
class TestModel(BaseModel):
name: str
value: str
some_null_by_default_field: str | None = None
try:
TestModel()
except ValidationError as e:
print(f'Pydantic will state `name` + `value` are required: {e}')
else:
raise Exception('Pydantic should have required `required_decimal`.')
class PartialTestModel(PartialModel, TestModel):
pass
obj = PartialTestModel(name='a-name')
assert obj.name == 'a-name'
assert obj.value is Missing
assert obj.some_null_by_default_field is None
Notice that if a field has a default value, it's used instead of marking it as Missing
.
Also, the Missing
sentinel value is a separate value vs None
, allowing one to easily
know if a value is truly just missing or is None
/Null
.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Hashes for pydantic_partials-1.0.4-py3-none-any.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 8e6c369f396ae7e67222c7bfb3779faa01b9669198e2ef36e309621efca3729c |
|
MD5 | 501996f96009219f12e8550c9d157591 |
|
BLAKE2b-256 | 0abb20cfa40c80c47a064bb29be31afa209f19e58dee784a4735664ea1101998 |