Skip to main content

A Python package to help with serialization and deserialization of dataclasses through the help of a common interface while also insuring the parsed data is properly typed and handled in many situations.

Project description

Mooss - Serialize

PyPI pyversions

  

PyPI status

PyPi version

  

PyPI download month

  

GitHub issues

  

PyPI license

⚠️ This package is a work-in-progress, it is not suitable nor reliable for any applications yet ⚠️

A Python package to help with serialization and deserialization of dataclasses through the help of a common interface

while also insuring the parsed data is properly typed and handled.

This package was created because I often found myself needing to deserialize nested dataclasses with slightly complex

value types, and because all other solutions I found were either too bloated or didn't work properly with what I had.

It is by no mean a replacement for other packages, but should suffice when dealing with slightly complex data

structures.

Setup

Requirements

  • Python 3.9 or newer.    (CPython and PyPy are both supported !)

Installation

Run one of the following commands to install the package:

python -m pip install --upgrade mooss-serialize

pip install --upgrade mooss-serialize

Usage

In order to use this package, you simply have to create a class that extends the provided ISerializable interface

that also has the dataclass decorator, add some variable annotations with the desired types, and then use the

provided class methods to serialize and deserialize it easily.

See the examples below for more information

Creating classes

The following classes have more complex and fluid typing for their variables that will help illustrate the main

advantage of this package over oneliners and other simpler deserializers.

from dataclasses import dataclass

from typing import Optional, Union



from mooss.serialize.interface import ISerializable



@dataclass

class Address(ISerializable):

    country: str

    city: str

    zip_code: Optional[int]

    # TODO: Implement non-serializable fields  (has_multiple_mailboxes: bool)

    street: str = "Unknown"



@dataclass

class Person(ISerializable):

    name: str

    address: Union[Address, str, None]

Preparing the raw data

We are preparing a dictionary that represent the non-deserialized data.

# Representing the 'Person' and 'Address' classes.

# The 'zip_code' field can be removed and will be 'None' since it uses the 'Optional' annotation.

data_person_full: dict = {

    "name": "John Smith",

    "address": {

        "country": "Belgium",

        "city": "Brussels",

        "zip_code": 1000,

        "street": "Rue de la Tribune",

    },

}



# Only representing the 'Person' class and replacing the 'Address' class by a string.

data_person_simple: dict = {

    "name": "John Smith",

    "address": "Rue de la Tribune, 1000 Brussels, Belgium"

}

This data can also be represented as a JSON string when using from_json in the next step.

Parsing the data

person_full = Person.from_dict(data_person_full)



print(person_full)

Other parameters

The from_dict and from_json methods features a couple of parameters that can help you influence the way it will react and process some

specific cases depending on your requirements.

<summary>Click here to expand list of all the available parameters</summary>

This information is also available in the methods' docstring.

<table>

    <tr>

        <td><b>Parameter</b></td>

        <td><b>Type</b></td>

        <td><b>Description</b></td>

        <td><b>Default</b></td>

    </tr>

    <tr>

        <td><code>data_dict</code></td>

        <td><code>dict</code></td>

        <td>Data to be deserialized</td>

        <td><i>Required</i></td>

    </tr>

    <tr>

        <td><code>data_json</code></td>

        <td><code>dict</code></td>

        <td>Data to be parsed into a dict and be deserialized</td>

        <td><i>Required</i></td>

    </tr>

    <tr>

        <td><code>allow_unknown</code></td>

        <td><code>bool</code></td>

        <td>Allow unknown fields to be processed instead of raising a <code>ValueError</code> exception,

other parameters will determine their use if True.

        <td><code>False</code></td>

    </tr>

    <tr>

        <td><code>add_unknown_as_is</code></td>

        <td><code>bool</code></td>

        <td>Adds unknown fields/values as-is in the final class if <code>allow_unknown</code> is also <code>True</code>.</td>

        <td><code>False</code></td>

    </tr>

    <tr>

        <td><code>allow_as_is_unknown_overloading</code></td>

        <td><code>bool</code></td>

        <td>Allow unknown fields/values to overload existing class attributes.</td>

        <td><code>False</code></td>

    </tr>

    <tr>

        <td><code>allow_missing_required</code></td>

        <td><code>bool</code></td>

        <td>TODO</td>

        <td><code>False</code></td>

    </tr>

    <tr>

        <td><code>allow_missing_nullable</code></td>

        <td><code>bool</code></td>

        <td>TODO</td>

        <td><code>False</code></td>

    </tr>

    <tr>

        <td><code>add_unserializable_as_dict</code></td>

        <td><code>bool</code></td>

        <td>TODO</td>

        <td><code>False</code></td>

    </tr>

    <tr>

        <td><code>validate_type</code></td>

        <td><code>bool</code></td>

        <td>Enables a strict type check between the class' serializable fields and the given data.</td>

        <td><code>True</code></td>

    </tr>

    <tr>

        <td><code>parsing_depth</code></td>

        <td><code>int</code></td>

        <td>The recursive depth to which the deserialization process will go.<br>(<code>-1</code> means infinite)</td>

        <td><code>-1</code></td>

    </tr>

    <tr>

        <td><code>do_deep_copy</code></td>

        <td><code>bool</code></td>

        <td>Performs a deep copy of the given 'data_dict' to prevent modifications from affecting other variables

that may reference it.

        <td><code>False</code></td>

    </tr>

</table>

Type annotations

Since the dataclass decorator is required on any class that extends ISerializable, the methods can easily detect

and validate the different types for the given data, which in turn can help you reduce the amount of check you will

have to perform on the final deserialized data.

This approach was used due to the fact that many one-liners and small helpers available on the internet do not

implement this type of checks and usually leave you with potentially invalidly-typed data, or simply data that is not

deserialized properly in the case of nested deserializable classes.

It should be noted that undefined fields can also be supported and copied as-is if the right parameters are given

to the methods, but this isn't done by default to prevent silent errors and overloading existing attributes !

Supported types

These types should cover 99% of the uses cases for this package, however, in the event you would wish to use

unsupported types, you can always do so by using the Any type to skip type checking for a given field.

  • Primitives:

str, int, float, bool

  • Simple sets:

list, dict, tuple, set

  • Composed sets*:

list[...], dict[...], tuple[...], set[...]

  • Variable types*:

Union, Optional, Any

*: Has some limitations on what can be contained between the square brackets.

Limitations

These limitations are put in place due to the fact that I don't have the time to implement a proper way to

support weird and unusual data types.

[...] If you want to handle these, you can either add support for it yourself or use a specialized and bulkier

package.

  • Mixed complex types: list[ISerializable, primitive]

    • A mix of primitives and sets should work but should preferably not be used.

More specific and rare types

Types and utilities such as the ones listed below should be supported at some point, but since it is not urgent,

there is no set timeline for their implementation.

List of types and utilities that may be supported:

Set, Collection, NamedTuple, NewType, Mapping, Sequence, TypeVar and Iterable.

Contributing

If you want more information on how to contribute to this package, you should refer to develop.md.

License

Unlicense

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

mooss-serialize-0.0.5.tar.gz (18.3 kB view details)

Uploaded Source

Built Distribution

mooss_serialize-0.0.5-py3-none-any.whl (11.3 kB view details)

Uploaded Python 3

File details

Details for the file mooss-serialize-0.0.5.tar.gz.

File metadata

  • Download URL: mooss-serialize-0.0.5.tar.gz
  • Upload date:
  • Size: 18.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.8.0 pkginfo/1.8.2 readme-renderer/29.0 requests/2.27.1 requests-toolbelt/0.9.1 urllib3/1.26.5 tqdm/4.61.1 importlib-metadata/4.5.0 keyring/23.0.1 rfc3986/1.5.0 colorama/0.4.4 CPython/3.9.4

File hashes

Hashes for mooss-serialize-0.0.5.tar.gz
Algorithm Hash digest
SHA256 5468c65d851e65f35e67fbf0f7b6e66d6d1c3383d6be8402dfc2425440b95d97
MD5 2963391ce30e68259ca88c73fafb7b22
BLAKE2b-256 a1f1a66bce5eb7baee19a12a3f1b8b99d8cc3007591e330ce62a4825dd0d27c3

See more details on using hashes here.

Provenance

File details

Details for the file mooss_serialize-0.0.5-py3-none-any.whl.

File metadata

  • Download URL: mooss_serialize-0.0.5-py3-none-any.whl
  • Upload date:
  • Size: 11.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.8.0 pkginfo/1.8.2 readme-renderer/29.0 requests/2.27.1 requests-toolbelt/0.9.1 urllib3/1.26.5 tqdm/4.61.1 importlib-metadata/4.5.0 keyring/23.0.1 rfc3986/1.5.0 colorama/0.4.4 CPython/3.9.4

File hashes

Hashes for mooss_serialize-0.0.5-py3-none-any.whl
Algorithm Hash digest
SHA256 2c2ac67c0de0fba71a43b53f56d5544c1f2e700a422f2e2d0d25fd7a58767c29
MD5 476431e166629b291b7437516a11bd5e
BLAKE2b-256 3f6e6957e359b2578b8dd019cc9ccd50c81112b1f544d1113ca0dac3ca45f9ac

See more details on using hashes here.

Provenance

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