Model-lib - pydantic base models with convenient dump methods
Installation
pip install 'model-lib[toml]'
Model-lib tutorial: What classes to use as base classes, how to serialize them, and add metadata
- A library built on top of pydantic
- Both pydantic v1 and v2 are supported
- The models:
EventandEntityare subclassing pydantic.BaseModel- Event is immutable
- Entity is mutable
- The specific configuration are:
- Automatic registering for dumping to the various formats
- Support different serializers for yaml/json/pretty_json/toml
- use_enum_values
- Use
dump(model|payload, format) -> str- if using an
Event|Entityit should "just-work" - Alternatively, support custom dumping with
register_dumper(instance_type: Type[T],dump_call: DumpCall)(see example below)
- if using an
- Use
parse_payload(payload, format)to parse to adictorlist- bytes
- str
- pathlib.Path (format not necessary if file has extension:
.yaml|.yml|json|toml|.env) - dict|list will be returned directly
- supports
register_parserfor adding e.g., a parser for KafkaMessage .envfiles parse to a flatdict[str, str]; keys are read verbatim, so mapUPPER_CASEkeys to fields withField(alias=...)parse_modelon a.envfile drops keys the model does not declare, so unrelated secrets never reach the model or its errors
- Use
parse_model(payload, t=Type, format)to parse and create a modeltnot necessary if class name stored inmetadata.model_name(see example below)- format not necessary if parsing from a file with extension
from datetime import datetime
from freezegun import freeze_time
from pydantic import Field
from model_lib import (
Entity,
Event,
dump,
dump_with_metadata,
parse_model,
FileFormat,
register_dumper,
)
from model_lib.serialize.parse import register_parser, parse_payload
dump_formats = list(FileFormat)
expected_dump_formats: list[str] = [
"json",
"pretty_json",
"yaml",
"yml",
"json_pydantic",
"pydantic_json",
"toml",
"toml_compact",
]
missing_dump_formats = set(FileFormat) - set(expected_dump_formats)
assert not missing_dump_formats, f"found missing dump formats: {missing_dump_formats}"
class Birthday(Event):
"""
>>> birthday = Birthday()
"""
date: datetime = Field(default_factory=datetime.utcnow)
class Person(Entity):
"""
>>> person = Person(name="espen", age=99)
>>> person.age += 1 # mutable
>>> person.age
100
"""
name: str
age: int
_pretty_person = """\
{
"age": 99,
"name": "espen"
}"""
def test_show_dumping():
with freeze_time("2020-01-01"):
birthday = Birthday(date=datetime.utcnow())
# can dump non-primitives e.g., datetime
assert dump(birthday, "json") == '{"date":"2020-01-01T00:00:00"}'
person = Person(name="espen", age=99)
assert dump(person, "yaml") == "name: espen\nage: 99\n"
assert dump(person, "pretty_json") == _pretty_person
_metadata_dump = """\
model:
name: espen
age: 99
metadata:
model_name: Person
"""
def test_show_parsing(tmp_path):
path_json = tmp_path / "example.json"
path_json.write_text(_pretty_person)
person = Person(name="espen", age=99)
assert parse_model(path_json, t=Person) == person
assert dump_with_metadata(person, format="yaml") == _metadata_dump
path_yaml = tmp_path / "example.yaml"
path_yaml.write_text(_metadata_dump)
assert parse_model(path_yaml) == person # metadata is used to find the class
class CustomDumping:
def __init__(self, first_name: str, last_name: str):
self.first_name = first_name
self.last_name = last_name
def __eq__(self, other):
if isinstance(other, CustomDumping):
return self.__dict__ == other.__dict__
return super().__eq__(other)
def custom_dump(custom: CustomDumping) -> dict:
return dict(full_name=f"{custom.first_name} {custom.last_name}")
register_dumper(CustomDumping, custom_dump)
class CustomKafkaPayload:
def __init__(self, body: str, topic: str):
self.topic = topic
self.body = body
def custom_parse_kafka(payload: CustomKafkaPayload, format: str) -> dict | list: # use Union[dict, list] if py3.9
return parse_payload(payload.body, format)
register_parser(CustomKafkaPayload, custom_parse_kafka)
def test_custom_dump():
instance = CustomDumping("Espen", "Python")
assert dump(instance, "json") == '{"full_name":"Espen Python"}'
payload = CustomKafkaPayload(body='{"first_name": "Espen", "last_name": "Python"}', topic="some-topic")
assert parse_model(payload, t=CustomDumping) == instance
Metadata
Release files for model-lib 0.103.3
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| model_lib-0.103.3.tar.gz | 21.4 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| model_lib-0.103.3-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 50.5 kB
Release files / model_lib-0.103.3.tar.gz
| Download URL | model_lib-0.103.3.tar.gz |
|---|---|
| Size | 21.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
fab02aa6d91bf3f0db653de63d8c20f27f5865b3603fb3474e63274fb5c78330
|
|
BLAKE2b-256 checksum How to use checksums |
9fc342670c8c85e47b1495f89080f67156e3d7cb2f9b8cba49d66d59853d42db
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 5, 2026.
Transparency logRelease files / model_lib-0.103.3-py3-none-any.whl
| Download URL | model_lib-0.103.3-py3-none-any.whl |
|---|---|
| Size | 29.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
febd012bfe8949b7748a69ee585e109ba1b11041daf105c8c502f92e16a0e1ed
|
|
BLAKE2b-256 checksum How to use checksums |
5abff02d251a84d2571ddef13d4bd437571d029cebf14b4d61efcb72f0bba8e5
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 5, 2026.
Transparency log