An utility class for creating instances of dataclasses
Project description
dataclass_factory
Dataclass instance creation library
You can convert dataclass to dict using asdict
method, but cannot convert back.
This module provides ParserFactory
method for such task.
It is very useful in combination with json
What's supported
dataclass
from dictEnum
from its valueList
,Set
,FrozenSet
,Dict
Tuple
with specified types or ellipsisOptional
with specified typeUnion
parsed in order of given typesAny
returned as isint
/float
/decimal
also parsed from string- other classes based on their
__init__
method - custom parser if specified
Usage
Install:
pip install dataclass_factory
Code:
@dataclass
class Book:
title: str
author: str = "Unknown author"
data = {
"title": "Fahrenheit 451"
}
parserFactory = dataclass_factory.ParserFactory()
obj = parserFactory.get_parser(Book)(data) # Same as Book(title="Fahrenheit 451")
You need to create parserFactory only once at the startup of your app. It caches created parsers and it will be significantly quicker than creating parser each time.
Extended usage
Parser factory provides some useful options:
trim_trailing_underscore
(enabled by default) - allows to trim trailing unders score in dataclass field names when looking them in corresponding dictionary.
For example fieldid_
can be stored isid
debug_path
- allows to see path to an element, that cannot be parsed in raised Exception.
This causes some performance decreasetype_factories
- dictionary with type as a key and functions that can be used to create instances of corresponding types as value.
See below.naming_policies
- names conversion policies
Naming Policies
You can use different naming styles in python dataclasses and corresponding dict. Following styles are supported:
- kebab-case
- snake_case
- camelCaseLower
- CamelCase
Note that field names in python code should use only(!) snake_case, but in style in dict can vary. Example:
@dataclass
class Data:
some_var: int
other: int
UnsupportedVar: int
data = {
"some-var": 1,
"other": 2,
"UnsupportedVar": 3
}
parser = ParserFactory(name_styles={Data: NameStyle.kebab}).get_parser(Data)
assert parser(data) == Data(1, 2, 3)
Serializing
SerializerFactory
includes features same as parsers, but converts data back.
It is much faster (up to 10 times) than standard asdict
function.
@dataclass
class Data:
some_var: int
other_: int
UnsupportedVar: int
data = {
"some-var": 1,
"other_": 2,
"UnsupportedVar": 3
}
serializer = SerializerFactory(
trim_trailing_underscore=True,
name_styles={Data: NameStyle.kebab}
).get_serializer(Data)
assert data == serializer(Data(1, 2, 3))
Custom parsers
You can provide your parsers for types that are not supported. For example, you can parse datetime
from iso format.
Also you can pass type_serializers
when creating SerializerFactory
from dataclass_factory import ParserFactory, dict_factory
from datetime import datetime
import dateutil.parser
from dataclasses import dataclass, asdict
parserFactory = ParserFactory(type_factories={datetime: dateutil.parser.parse})
@dataclass
class Todo:
id_: int
title: str
deadline: datetime
data = {
"id": 1,
"deadline": "2025-12-31T00:00:00",
"title": "Release 1.0"
}
todo = Todo(
id_=1,
title="Release 1.0",
deadline=datetime(2025, 12, 31, 0, 0, 0)
)
assert todo == parserFactory.get_parser(Todo)(data)
Compatibility
In versions below 1.0 there was a simple parse
method.
It is still provided for compatibility, but is not recommended because it recreates ParserFactory each time it is called It can be removed in some future version
In versions below 1.1 there was dict_factory, which was used with standard asdict method. It is still provided for compatibility, but will be removed in future versions. Please, use SerializerFactory
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.