A dataclass model toolkit: serialization, validation, and more.
- Model definitions in pure Python.
- Validation showing up in code coverage.
- Type annotations for all public-facing APIs.
- (Optionally) ensures immutability.
- Easily extensible.
- Made for people.
- Documented rigorously.
Available from PyPI:
pip install seriousCentral part of Serious API are different Models.
Given a regular dataclass:
from dataclasses import dataclass @dataclass class Person: name: strLet’s create a JsonModel:
from serious.json import JsonModel model = JsonModel(Person)And use its dump/load methods:
person = Person('Albert Einstein') model.dump(person) # {"name": "Albert Einstein"}To add validation to the example above all we need is to add __validate__ method to person:
from dataclasses import dataclass from typing import Optional from serious import ValidationError, Email @dataclass class Person: name: str email: Optional[Email] phone: Optional[str] def __validate__(self): if len(self.name) == 0: raise ValidationError('Every person needs a name') if self.phone is None and self.email is None: raise ValidationError('At least some contact should be present')- JSON
- Python Dictionaries
- YAML
- Form data
- Other dataclasses
- Primitives:
str,int,float,bool - Dictionaries: only with string keys:
Dict[str, Any] - Lists, sets, deques: python collections of any serializable type
- Tuples both with and without ellipsis:
- tuples as set of independent elements (e.g.
Tuple[str, int, date]) - with ellipses, acting as a frozen list (
Tuple[str, ...])
- tuples as set of independent elements (e.g.
- Enumerations by value:
- of primitives (e.g.
OperatingSystem(Enum)) - typed enums (
Color(str, Enum)andFilePermission(IntFlag))
- of primitives (e.g.
- Decimal: encoded to JSON as string
- Datetime, date and time: encoded to the ISO 8601 formatted string
- UUID
serious.types.Timestamp: a UTC timestamp since UNIX epoch as float ms valueserious.types.Email: a string Tiny Type that supports validation and contains additional properties- custom immutable alternatives to native python types in
serious.types:FrozenList,FrozenDict
from dataclasses import dataclass from serious import JsonModel, ValidationError from typing import List from enum import Enum class Specialty(Enum): Worker = 1 Fool = 2 @dataclass(frozen=True) class Minion: name: str type: Specialty @dataclass(frozen=True) class Boss: name: str minions: List[Minion] def __validate__(self): if len(self.minions) < 2: raise ValidationError('What kind of boss are you?') boss = Boss("me", [Minion('evil minion', Specialty.Fool), Minion('very evil minion', Specialty.Worker)]) boss_json = """{ "name": "me", "minions": [ { "name": "evil minion", "type": "Fool" }, { "name": "very evil minion", "type": "Worker" } ] }""" model = JsonModel(Boss, indent=4) assert model.dump(boss) == boss_json assert model.load(boss_json) == bossInitially, a fork of @lidatong/dataclasses-json.