# -*- coding: utf-8 -*-
from distutils.core import setup

packages = \
['typed_json_dataclass']

package_data = \
{'': ['*']}

install_requires = \
['flake8-tuple>=0.4.0,<0.5.0']

setup_kwargs = {
    'name': 'typed-json-dataclass',
    'version': '1.2.0',
    'description': 'Make your dataclasses automatically validate their types',
    'long_description': '# typed_json_dataclass\n[![Codacy Badge](https://api.codacy.com/project/badge/Grade/4344420de20b4262a4912d81cb28d175)](https://www.codacy.com/app/abatilo/typed-json-dataclass?utm_source=github.com&amp;utm_medium=referral&amp;utm_content=abatilo/typed-json-dataclass&amp;utm_campaign=Badge_Grade)\n[![Actions Status](https://wdp9fww0r9.execute-api.us-west-2.amazonaws.com/production/badge/abatilo/typed-json-dataclass?style=flat)](https://wdp9fww0r9.execute-api.us-west-2.amazonaws.com/production/badge/abatilo/typed-json-dataclass?branch=master)\n[![codecov](https://codecov.io/gh/abatilo/typed-json-dataclass/branch/master/graph/badge.svg)](https://codecov.io/gh/abatilo/typed-json-dataclass)\n[![PyPI status](https://img.shields.io/pypi/status/typed_json_dataclass.svg)](https://pypi.python.org/pypi/typed_json_dataclass/)\n[![PyPI version](https://badge.fury.io/py/typed-json-dataclass.svg)](https://badge.fury.io/py/typed-json-dataclass)\n[![PyPI pyversions](https://img.shields.io/pypi/pyversions/typed-json-dataclass.svg)](https://pypi.python.org/pypi/typed-json-dataclass/)\n![PyPI - Downloads](https://img.shields.io/pypi/dm/typed-json-dataclass.svg)\n[![MIT license](http://img.shields.io/badge/license-MIT-brightgreen.svg)](http://opensource.org/licenses/MIT)\n\n`typed_json_dataclass` is a library that augments the Python3.7\n[dataclass](https://docs.python.org/3/library/dataclasses.html) feature in two\nmajor ways:\n1. Add a way to recursively grab class dictionary definitions, thus making your\n   dataclass JSON serializable\n2. Add a light amount of type validation to your dataclasses, so that you can\n   validate that the JSON you\'re being given matches the data types that you\'re\n   expecting.\n\nBy expressing your data as dataclasses, and by having your incoming data\nvalidated as it is received, you can easily implement the [Data Transfer Object\n(DTO)](https://martinfowler.com/eaaCatalog/dataTransferObject.html) pattern in\nyour Python code.\n\nThis library can be thought of as a combination of\n[attrs](https://github.com/python-attrs/attrs),\n[cattrs](https://github.com/Tinche/cattrs), and\n[marshamllow](https://github.com/marshmallow-code/marshmallow)\n\n## Getting Started\n\nInstall the library from PyPI:\n```\npip install typed_json_dataclass\n```\n\nUse the dataclass decorator just like normal, but add the `TypedJsonMixin` from\nthis library, to your class definition. This will add 4 new methods to all of your dataclasses:\n1. from_dict()\n```python\n@classmethod\ndef from_dict(cls, raw_dict, *, mapping_mode=MappingMode.NoMap):\n    """Given a python dict, create an instance of the implementing class.\n\n    :raw_dict: A dictionary that represents the DTO to create\n    :mapping_mode: Format for properties\n    :returns: Returns an instance of the DTO, instantiated via the dict\n    """\n```\n2. from_json()\n```python\n@classmethod\ndef from_json(cls, raw_json, *, mapping_mode=MappingMode.NoMap):\n    """Given a raw json string, create an instance of the implementing class.\n\n    :raw_json: A json string that represents the DTO to create\n    :mapping_mode: Format for properties\n    :returns: Returns an instance of the DTO, instantiated via the json\n    """\n```\n3. to_dict()\n```python\ndef to_dict(self, *, keep_none=False, mapping_mode=MappingMode.NoMap, warn_on_initvar=True):\n    """Express the DTO as a dictionary.\n\n    :keep_none: Filter keys that are None\n    :mapping_mode: Format for properties\n    :warn_on_initvar: Emit a warning if the instance contains non-default\n                      init-only variables.\n    :returns: Returns the instantiated DTO as a dictionary\n    """\n```\n4. to_json()\n```python\ndef to_json(self, *, keep_none=False, mapping_mode=MappingMode.NoMap, warn_on_initvar=True):\n    """Express the DTO as a json string.\n\n    :keep_none: Filter keys that are None\n    :mapping_mode: Format for properties\n    :warn_on_initvar: Emit a warning if the instance contains non-default\n                      init-only variables.\n    :returns: Returns the instantiated DTO as a json string\n    """\n```\n\n## Examples\n\n### Converting your dataclass to a JSON serializable format\n```python\nfrom typing import List\nfrom dataclasses import dataclass\nfrom typed_json_dataclass import TypedJsonMixin\n\n@dataclass\nclass Person(TypedJsonMixin):\n    name: str\n    age: int\n\n@dataclass\nclass Family(TypedJsonMixin):\n    people: List[Person]\n\nbob = Person(name=\'Bob\', age=24)\nalice = Person(name=\'Alice\', age=32)\nfamily = Family(people=[bob, alice])\n\nprint(family.to_json())\n# => {"people": [{"name": "Bob", "age": 24}, {"name": "Alice", "age": 32}]}\n```\n\n\nIf your data doesn\'t match the type definitions, you\'ll get a helpful error:\n```python\nfrom dataclasses import dataclass\nfrom typed_json_dataclass import TypedJsonMixin\n\n@dataclass\nclass Person(TypedJsonMixin):\n    name: str\n    age: int\n\nrequest_data = \'{"name":"Bob","age":"24"}\'\n\nbob = Person.from_json(request_data)\n# => TypeError: Person.age is expected to be <class \'int\'>, but value 24 with type <class \'str\'> was found instead\n```\n\nAnd you can parse data from a Python `dict` as well. Just use the `.from_dict()` function instead:\n```python\nfrom dataclasses import dataclass\nfrom typed_json_dataclass import TypedJsonMixin\n\n@dataclass\nclass Person(TypedJsonMixin):\n    name: str\n    age: int\n\nrequest_data_as_dict = {\n    \'name\': \'Alice\',\n    \'age\': \'32\'\n}\n\nalice = Person.from_dict(request_data_as_dict)\n# => TypeError: Person.age is expected to be <class \'int\'>, but value 32 with type <class \'str\'> was found instead\n```\n\n### Setting a mapping_mode for auto mapping\n```python\nfrom dataclasses import dataclass\nfrom typed_json_dataclass import TypedJsonMixin, MappingMode\n\n@dataclass\nclass Person(TypedJsonMixin):\n    person_name: str\n    person_age: int\n\nrequest_data_as_dict = {\n    \'personName\': \'Alice\',\n    \'personAge\': 32\n}\n\nalice = Person.from_dict(request_data_as_dict, mapping_mode=MappingMode.SnakeCase)\n# => Person(person_name=\'Alice\', person_age=32)\n```\n\nThis mapping mode is useful for when you get requests that have the JSON in a\ncamel case format, but you want your objects to be snake case and stay PEP8\ncompliant.\n\n## Limitations and Caveats\n\n### Dataclasses with init-only variables\n\nSupport for dataclasses with [init-only variables](https://docs.python.org/3/library/dataclasses.html#init-only-variables)\nis limited. Although `to_dict` and `to_json` will convert the dataclass, the\nresulting dict or JSON string will not contain the init-only variables, since\ntheir values are not available after initialization. This also means that such\ndataclasses cannot later be instantiated from a dict or JSON string, since the\ninit-only variables are a required parameter in the dataclass\' `__init__`\nmethod. `TypedJsonMixin` detects the usage of dataclasses with init-only\nvariables, emits a warning when it is converted to a dict or JSON string, and\nrefuses to instantiate a dataclass with init-only variables.\n\nA first workaround consists of providing a default value to the init-only\nvariables:\n\n```python\n@dataclass\nclass Person(TypedJsonMixin):\n    person_name: InitVar[str] = \'\'\n    person_first_name: str = \'\'\n    person_last_name: str = \'\'\n\n    def __post_init__(self, person_name):\n        if person_name:\n            # Instantiated directly\n            self.person_first_name, self.person_last_name = person_name.split()\n        # Call TypedJsonMixin __post_init__ method\n        super().__post_init__()\n```\n**Note**: Instantiations without arguments, such as `Person()`, are now\npossible, although the created instance would then be invalid.\n\nThe second workaround is to remove init-only variables from the dataclass, and\nperform the `__post_init__` instantiation using a class method instead:\n\n```python\n@dataclass\nclass Person(TypedJsonMixin):\n    person_first_name: str\n    person_last_name: str\n\n    @classmethod\n    def create(cls, person_name):\n        first_name, last_name = person_name.split()\n        cls(first_name, last_name)\n```\n\nFinally, if the dataclass is not meant to ever be instantiated from a dict or\nJSON string, and only the `to_dict` or `to_json` methods are called, the\nwarnings can be suppressed by passing `warn_on_initvar=False` as a keyword\nargument in the method call.\n',
    'author': 'Aaron',
    'author_email': 'AaronBatilo@gmail.com',
    'url': 'http://github.com/abatilo/typed_json_dataclass',
    'packages': packages,
    'package_data': package_data,
    'install_requires': install_requires,
    'python_requires': '>=3.7.0,<3.8.0',
}


setup(**setup_kwargs)
