Metadata-Version: 2.1
Name: jsondaora
Version: 0.3.2
Summary: Interoperates @dataclass with json objects
Home-page: https://github.com/dutradda/jsondaora
License: UNKNOWN
Author: Diogo Dutra
Author-email: diogodutradamata@gmail.com
Requires-Python: >=3.8
Description-Content-Type: text/markdown
Classifier: License :: OSI Approved :: MIT License
Classifier: Development Status :: 1 - Planning
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3.7
Classifier: Programming Language :: Python :: 3.8
Classifier: Topic :: Software Development :: Libraries
Requires-Dist: orjson
Requires-Dist: mkdocs; extra == "doc"
Requires-Dist: mkdocs-material; extra == "doc"
Requires-Dist: markdown-include; extra == "doc"
Requires-Dist: black; extra == "test"
Requires-Dist: flake8; extra == "test"
Requires-Dist: isort; extra == "test"
Requires-Dist: ipython; extra == "test"
Requires-Dist: mypy; extra == "test"
Requires-Dist: pytest-cov; extra == "test"
Requires-Dist: pytest-mock; extra == "test"
Requires-Dist: pytest>=5.1.1; extra == "test"
Requires-Dist: tox; extra == "test"
Project-URL: Documentation, https://dutradda.github.io/jsondaora/
Provides-Extra: doc
Provides-Extra: test

# jsondaora

<p align="center" style="margin: 3em">
  <a href="https://github.com/dutradda/jsondaora">
    <img src="https://dutradda.github.io/jsondaora/jsondaora.svg" alt="jsondaora" width="300"/>
  </a>
</p>

<p align="center">
    <em>Interoperates <b>dataclasses</b> and <b>TypedDict</b> annotations with <b>json objects for python</b></em>
</p>

---

**Documentation**: <a href="https://dutradda.github.io/jsondaora" target="_blank">https://dutradda.github.io/jsondaora</a>

**Source Code**: <a href="https://github.com/dutradda/jsondaora" target="_blank">https://github.com/dutradda/jsondaora</a>

---


## Key Features

- Full compatibility with [dataclasses](https://docs.python.org/3/library/dataclasses.html) module and [TypedDict](https://www.python.org/dev/peps/pep-0589/) annotation
- Deserialize values from dict
- Deserialize values from bytes*
- Deserialization/serialization of choosen fields
- Dict serialization
- Direct json serialization with [orjson](https://github.com/ijl/orjson) (don't convert to dict recursively before serialization)
- Optional validation according with the [json-schema](https://json-schema.org/) specification*

*\* feature in development.*


## Requirements

 - Python 3.8+
 - [orjson](https://github.com/ijl/orjson) for json serialization


## Instalation
```
$ pip install jsondaora
```


## Basic example

```python
from dataclasses import dataclass
from typing import List, TypedDict

from jsondaora import (
    as_typed_dict,
    asdataclass,
    dataclass_asjson,
    jsondaora,
    typed_dict_asjson,
)


# dataclass


@dataclass
class Music:
    name: str


# if 'Person' is not a dataclass the
# 'jsondaora' decorator will call the
# 'dataclass' decorator
@jsondaora
class Person:
    name: str
    age: int
    musics: List[Music]


jsondict = dict(name=b'John', age='40', musics=[dict(name='Imagine')])
person = asdataclass(jsondict, Person)

print('dataclass:')
print(person)
print(dataclass_asjson(person))
print()


# TypedDict


@jsondaora
class Music(TypedDict):
    name: str


# This decorator is required because
# we need to track the annotations
@jsondaora
class Person(TypedDict):
    name: str
    age: int
    musics: List[Music]


jsondict = dict(name=b'John', age='40', musics=[dict(name='Imagine')])
person = as_typed_dict(jsondict, Person)

print('TypedDict:')
print(person)
print(typed_dict_asjson(person, Person))

```

```
dataclass:
Person(name='John', age=40, musics=[Music(name='Imagine')])
b'{"name":"John","age":40,"musics":[{"name":"Imagine"}]}'

TypedDict:
{'name': 'John', 'age': 40, 'musics': [{'name': 'Imagine'}]}
b'{"name":"John","age":40,"musics":[{"name":"Imagine"}]}'

```


## Example for choose fields to deserialize

```python
from dataclasses import dataclass
from typing import List, TypedDict

from jsondaora import (
    as_typed_dict,
    asdataclass,
    dataclass_asjson,
    jsondaora,
    typed_dict_asjson,
)


@dataclass
class Music:
    name: str


@jsondaora(deserialize_fields=('name'))
class Person:
    name: str
    age: int
    musics: List[Music]


jsondict = dict(name=b'John', age='40', musics=[dict(name='Imagine')])
person = asdataclass(jsondict, Person)

print('dataclass:')
print(person)
print(dataclass_asjson(person))
print()


# TypedDict


@jsondaora
class Music(TypedDict):
    name: str


@jsondaora(deserialize_fields=('name'))
class Person(TypedDict):
    name: str
    age: int
    musics: List[Music]


jsondict = dict(name=b'John', age='40', musics=[dict(name='Imagine')])
person = as_typed_dict(jsondict, Person)

print('TypedDict:')
print(person)
print(typed_dict_asjson(person, Person))

```

```
dataclass:
Person(name='John', age='40', musics=[{'name': 'Imagine'}])
b'{"name":"John","age":"40","musics":[{"name":"Imagine"}]}'

TypedDict:
{'name': 'John', 'musics': [{'name': 'Imagine'}], 'age': '40'}
b'{"name":"John","musics":[{"name":"Imagine"}],"age":"40"}'

```


## Example for choose fields to serialize

```python
from dataclasses import dataclass
from typing import List, TypedDict

from jsondaora import (
    as_typed_dict,
    asdataclass,
    dataclass_asjson,
    jsondaora,
    typed_dict_asjson,
)


@dataclass
class Music:
    name: str


@jsondaora(serialize_fields=('name', 'age'))
@dataclass
class Person:
    name: str
    age: int
    musics: List[Music]


jsondict = dict(name='John', age=40, musics=[dict(name='Imagine')])
person = asdataclass(jsondict, Person)

print('dataclass:')
print(person)
print(dataclass_asjson(person))
print()


# TypedDict


@jsondaora
class Music(TypedDict):
    name: str


@jsondaora(serialize_fields=('age'))
class Person(TypedDict):
    name: str
    age: int
    musics: List[Music]


jsondict = dict(name=b'John', age='40', musics=[dict(name='Imagine')])
person = as_typed_dict(jsondict, Person)

print('TypedDict:')
print(person)
print(typed_dict_asjson(person, Person))

```

```
dataclass:
Person(name='John', age=40, musics=[Music(name='Imagine')])
b'{"age":40,"name":"John"}'

TypedDict:
{'name': 'John', 'age': 40, 'musics': [{'name': 'Imagine'}]}
b'{"age":40}'

```


## Wins [Pydantic](https://github.com/samuelcolvin/pydantic) Benchmark

`jsondaora` is up to *5.6 times* faster than pydantic on it's benchmark

![pydantic benchmark](https://dutradda.github.io/jsondaora/benchmark.png "Pydantic Benchmark")

