Skip to main content

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

ReadTheDocs GitHub issues GitHub pull requests PyPI PyPI - Downloads GitHub

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.Unions
    • Through subclassing
  • 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 (Including Optional)
  • 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

Dictionary deserializer-0.0.6.tar.gz (7.5 kB view details)

Uploaded Source

Built Distribution

Dictionary_deserializer-0.0.6-py3-none-any.whl (9.1 kB view details)

Uploaded Python 3

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

Hashes for Dictionary deserializer-0.0.6.tar.gz
Algorithm Hash digest
SHA256 749bba068d7f677a225e8a11646e4c24cfabfc3096f98e43aa9417483fa15314
MD5 1d7f36b5516278e588e9d46846dd7e3d
BLAKE2b-256 d65afbeacc0fe0888dc9a5654689b7c7c85139274c509baf7dd110b6a6e0e24f

See more details on using hashes here.

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

Hashes for Dictionary_deserializer-0.0.6-py3-none-any.whl
Algorithm Hash digest
SHA256 cbed3e316912ed72a05afeda5e24aa7195c9e073eb473e9f4eca94020a3f1c99
MD5 7873cc1b3258d1b1e8187b81b4e7d66f
BLAKE2b-256 9b0f1b0f7146e66bba176a5ece5877d1518f2f2df8669c95ec11b14c9f2cc3b3

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page