Dictionary deserializer is a package that aides in the deserializing of JSON (or other structures) that are converted to dicts, into composite classes.
Project description
Dictionary deserializer
Dictionary deserializer is a project built to convert dictionaries into composite classes in an intuitive way. Special attention was also paid to being friendly to static type-checkers and IDE autocompletes.
It is expected that this library is used together with a JSON-to-dict
deserializer like json.loads
.
Installation
In order to use it, simply add the dependency dictionary-deserializer
to your
requirements file:
Pipenv
pipenv install dictionary-deserializer
Pip
pip install dictionary-deserializer
pip freeze > requirements.txt
Design
This project was originally meant as a proof of concept, to be used to find other projects that would be able to replace this, with the required feature set. That project was not found, and therefore, this project was expanded.
Requirements
- Use type hints for type validation
- Allow polymorphism
- Through
typing.Union
s - Through subclassing
- Through
- Support a large part of the
typing
module's types - Allow validations on values
- Be able to validate and deserialize any compliant JSON structure
- Be compatible with static type checkers and IDE hinting
- Have a small impact on existing code starting to use this library
Examples
None of this code is actually useful if you don't understand how to use it. It is very simple. Here are some examples:
Specifying a structure
from typing import Optional
from dict_deserializer.deserializer import Deserializable
class User(Deserializable):
email: str # Type must be a string
username: str # Type must be a string
password: Optional[str] # Type must either be a string or a None
Deserialization
from dict_deserializer.deserializer import deserialize, Rule
# Successful
deserialize(Rule(User), {
'email': 'pypi@rolfvankleef.nl',
'username': 'rkleef',
})
# Fails because optional type is wrong
deserialize(Rule(User), {
'email': 'pypi@rolfvankleef.nl',
'username': 'rkleef',
'password': 9.78,
})
Polymorphic structures
from typing import Optional, Any, List
from dict_deserializer.deserializer import Deserializable
from dict_deserializer.annotations import abstract
@abstract
class DirectoryObject(Deserializable):
name: str
meta: Any
class User(DirectoryObject):
full_name: str
first_name: Optional[str]
class Group(DirectoryObject):
members: List[DirectoryObject]
If you deserialize into Rule(DirectoryObject)
, the matching class will
automatically be selected. If none of the subclasses match, an error is thrown
since the DirectoryObject is declared abstract.
If you want to discriminate not by field names or types, but by their values,
one can choose to define a @discriminator
annotation.
Value validations
The syntax for validating the value of a key is currently a bit weird. It is incompatible with existing syntax for defaults, but the type syntax is the same.
Example:
from typing import Optional
from dict_deserializer.deserializer import Deserializable
from dict_deserializer.annotations import validated
class Test(Deserializable):
name: Optional[str]
@validated(default='Unknown')
def name(self, value):
if len(value) > 20:
raise TypeError('Name may not be longer than 20 characters.')
Limitations
This library uses the typing
module extensively. It does, however, only
support some of its types. This is a list of verified composite types:
Union
(IncludingOptional
)Dict
List
Tuple
Any
dict_deserializer.deserializer.Deserializable
dict
list
It supports these types as terminal types:
int
float
str
NoneType
bool
Planned features
- NamedTuples
- The anonymous namedtuple and the class-namedtuples with (optionally) type annotations.
- Dataclasses
- A way to allow deserializing into a class not extending
Deserializable
- Enums
- Sets
- From lists
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
File details
Details for the file Dictionary deserializer-0.0.6.tar.gz
.
File metadata
- Download URL: Dictionary deserializer-0.0.6.tar.gz
- Upload date:
- Size: 7.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/1.12.1 pkginfo/1.4.2 requests/2.20.1 setuptools/40.5.0 requests-toolbelt/0.8.0 tqdm/4.28.1 CPython/3.6.8
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 749bba068d7f677a225e8a11646e4c24cfabfc3096f98e43aa9417483fa15314 |
|
MD5 | 1d7f36b5516278e588e9d46846dd7e3d |
|
BLAKE2b-256 | d65afbeacc0fe0888dc9a5654689b7c7c85139274c509baf7dd110b6a6e0e24f |
File details
Details for the file Dictionary_deserializer-0.0.6-py3-none-any.whl
.
File metadata
- Download URL: Dictionary_deserializer-0.0.6-py3-none-any.whl
- Upload date:
- Size: 9.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/1.12.1 pkginfo/1.4.2 requests/2.20.1 setuptools/40.5.0 requests-toolbelt/0.8.0 tqdm/4.28.1 CPython/3.6.8
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | cbed3e316912ed72a05afeda5e24aa7195c9e073eb473e9f4eca94020a3f1c99 |
|
MD5 | 7873cc1b3258d1b1e8187b81b4e7d66f |
|
BLAKE2b-256 | 9b0f1b0f7146e66bba176a5ece5877d1518f2f2df8669c95ec11b14c9f2cc3b3 |