python-easy-json


Namepython-easy-json JSON
Version 1.2.0 PyPI version JSON
download
home_pagehttps://github.com/robabram/python-easy-json
SummaryA simple, yet powerful, JSON/python dictionary to object deserialization
upload_time2024-07-14 14:43:03
maintainerNone
docs_urlNone
authorRobert Abram
requires_python>=3.6
licenseMIT
keywords serialization rest json api marshal marshalling deserialization schema model models data
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            |badge1| |badge2| |badge3|

.. |badge1| image:: https://github.com/robabram/python-easy-json/actions/workflows/tests.yaml/badge.svg
  :alt: Unittest Completion Status
.. |badge2| image:: https://raw.githubusercontent.com/robabram/python-easy-json/coverage-badge/coverage.svg?raw=true
  :alt: Code Coverage Status
.. |badge3| image:: https://img.shields.io/badge/python-v3.7%20|%20v3.8%20|%20v3.9%20|%20v3.10%20|%20v3.11%20|%20v3.12-blue
  :alt: Python v3.7, v3.8, v3.9, v3.10, v3.11, v3.12


****************************************************************************************
python-easy-json: simple, yet powerful, JSON/python dictionary to object deserialization  
****************************************************************************************

**python-easy-json** is a recursive JSON to python object deserializer with support for defining data models 
and casting data to python using type hint annotations. 

The python-easy-json JSONObject class can be used to:

- **Deserialize:** Recursively convert a JSON string or python dictionary to a python object
- **Serialize:** Export the object data to a JSON string or python dictionary
- **Type Hinting Integration:** Convert JSON values to specific types by creating models and type hints.
- **Define Data Models:** Create simple, yet powerful data models for working with data from any source
- **IDE Auto Completion:** IDEs with auto-completion and support python type hinting will auto-complete model properties


Get It Now
==========

    $ pip install python-easy-json

Why a another JSON to Object library?
=====================================
After years of python development, I grew tired of receiving data from APIs, database, csv files and so on and working 
with them as python dictionaries. The "simple" JSON deserializer library options I saw really didn't fit how easy I felt
that deserializing to a JSON object should be.  Additionally, I wanted to create simple data model classes and 
using python "Type Hinting" to define property value types. 


Simple Examples
===============

Just pass a JSON string or python dict argument to the JSONObject constructor.  In this example, we can switch from using dict key lookups to an array of JSONObjects.  

::

    for row in results:
        if row['the_key'][0]['another_key'] == 'the_value':
            ...

With JSONObject this may be re-written as below, using list comprehension. This makes the code more readable and less cluttered when working with complex dictionary structures in code.

::

    from python_easy_json import JSONObject

    for row in [JSONObject(r) for r in results]:
        if row.the_key[0].another_key == 'the_value':
            ...

Data from a JSON String

::

    from python_easy_json import JSONObject
    
    # JSON string
    obj = JSONObject('{"test_key": "test_value"}')
    print(obj.to_json())

    {"test_key": "test_value"}

Data from a python dictionary

::

    # Python dictionary
    obj = JSONObject({'test_key': 'test_value'})
    print(obj.to_json())

    {"test_key": "test_value"}


Data Models For Anything
========================

Using the python-easy-json JSONObject class, you can create data models, including deeply nested models and arrays, from any
JSON string or dictionary. Additionally, python "Type Hints" may be used to cast values to the type defined by the type 
hint annotations.

As a bonus; IDEs with auto-completion and support for python type hinting will auto-complete model properties as you type. 

This example shows how to define nested/child data models, including lists of nested data models.

::

    # Represents json from 'tests/test_data/nested_data_1.json'
    class CakeToppingTypeModel(JSONObject):
        id: int = None
        type: str = None    
    
    class CakeBatterTypeModel(JSONObject):
        id: int = None
        type: str = None    
    
    class CakeBatterModel(JSONObject):
        batter: List[CakeBatterTypeModel] = None    
    
    class CakeModel(JSONObject):
        id: str = None
        type: str = None
        name: str = None
        ppu: float = None
        batters: CakeBatterModel = None
        topping: List[CakeToppingTypeModel]

    cake = CakeModel(data)
    print(f'Cake: {cake.name} ({len(cake.batters.batter)} ingredents).') 

    Cake: Devil's Food Cake (4 ingredients).


Type Hints Automatically Convert JSON Values
============================================
If a model has been defined and the properties have python Type Hint annotations, the JSONObject can convert values 
to the annotation types.

::

    from datetime import datetime 

    class TimestampModel(JSONObject):
        id: int = None
        timestamp: datetime = None

    data = {'id': "123", "timestamp": "2022-09-19 10:11:01.123456"}
    obj = TimestampModel(data, cast_types=True)

    if obj.id > 0:
        print(f"ID: {obj.id}: {obj.timestamp.strftime('%b %d, %Y @ %H:%M:%S %p')}")

    $ ID: 123: Sep 19, 2022 @ 10:11:01 AM

Documentation
=============

**JSONObject Class**

::

    JSONObject.__init__(data: Union[Dict, str, None] = None, cast_types: bool = False, ordered: bool = False)
        Load the dictionary or JSON string data argument into ourselves as properties.
        :param data: Dictionary or valid JSON string.
        :param cast_types: If properties of this class are type annotated, try to cast them.
        :param ordered: Use OrderedDict() if set, otherwise use dict(). For python <= 3.6.

    JSONObject.to_json(indent: int = None)
        Export stored data as a json string.
        :param indent: Positive integer value for formatting JSON string indenting.
        :returns: JSON string

    JSONObject.to_dict(recursive: bool = True, dates_to_str: bool = False)        
        Export stored data as a python dictionary object.
        :param recursive: Boolean, recursively convert nested JSONObjects to a dict
        :param dates_to_str: Boolean, convert all date or datetime values to string.
        :returns: dictionary object

    JSONObject.update([Dict|List|Tuple]) accepts either a dictionary object or an iterable of key/value
        pairs (as tuples or other iterables of length two). If keyword arguments are specified, the dictionary
        is then updated with those key/value pairs: obj.update(sky=1, cloud=2).

    Plus Operator: Two JSONObjects may be merged using the plus (+) operator: obj = obj + other_obj.

    Number of Properties: The number of managed properties may be determined by using the Python 'len()'
        function: len(obj) == 5.

Project Links
=============

- PyPI: https://pypi.python.org/pypi/python-easy-json
- Issues: https://github.com/robabram/python-easy-json/issues

License
=======

MIT licensed. See the bundled `LICENSE <https://github.com/robabram/python-easy-json/blob/main/LICENSE>` file for more details.


Unittest Data
-------------

Testing JSON data for examples and unittests sourced from: https://opensource.adobe.com/Spry/samples/data_region/JSONDataSetSample.html

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/robabram/python-easy-json",
    "name": "python-easy-json",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.6",
    "maintainer_email": null,
    "keywords": "serialization, rest, json, api, marshal, marshalling, deserialization, schema, model, models, data",
    "author": "Robert Abram",
    "author_email": "rabram991@gmail.com",
    "download_url": "https://files.pythonhosted.org/packages/fd/d7/5982f24b5cacd68c19903f28c7d8dba679b151886fb9901def2db4a65fd7/python_easy_json-1.2.0.tar.gz",
    "platform": null,
    "description": "|badge1| |badge2| |badge3|\n\n.. |badge1| image:: https://github.com/robabram/python-easy-json/actions/workflows/tests.yaml/badge.svg\n  :alt: Unittest Completion Status\n.. |badge2| image:: https://raw.githubusercontent.com/robabram/python-easy-json/coverage-badge/coverage.svg?raw=true\n  :alt: Code Coverage Status\n.. |badge3| image:: https://img.shields.io/badge/python-v3.7%20|%20v3.8%20|%20v3.9%20|%20v3.10%20|%20v3.11%20|%20v3.12-blue\n  :alt: Python v3.7, v3.8, v3.9, v3.10, v3.11, v3.12\n\n\n****************************************************************************************\npython-easy-json: simple, yet powerful, JSON/python dictionary to object deserialization  \n****************************************************************************************\n\n**python-easy-json** is a recursive JSON to python object deserializer with support for defining data models \nand casting data to python using type hint annotations. \n\nThe python-easy-json JSONObject class can be used to:\n\n- **Deserialize:** Recursively convert a JSON string or python dictionary to a python object\n- **Serialize:** Export the object data to a JSON string or python dictionary\n- **Type Hinting Integration:** Convert JSON values to specific types by creating models and type hints.\n- **Define Data Models:** Create simple, yet powerful data models for working with data from any source\n- **IDE Auto Completion:** IDEs with auto-completion and support python type hinting will auto-complete model properties\n\n\nGet It Now\n==========\n\n    $ pip install python-easy-json\n\nWhy a another JSON to Object library?\n=====================================\nAfter years of python development, I grew tired of receiving data from APIs, database, csv files and so on and working \nwith them as python dictionaries. The \"simple\" JSON deserializer library options I saw really didn't fit how easy I felt\nthat deserializing to a JSON object should be.  Additionally, I wanted to create simple data model classes and \nusing python \"Type Hinting\" to define property value types. \n\n\nSimple Examples\n===============\n\nJust pass a JSON string or python dict argument to the JSONObject constructor.  In this example, we can switch from using dict key lookups to an array of JSONObjects.  \n\n::\n\n    for row in results:\n        if row['the_key'][0]['another_key'] == 'the_value':\n            ...\n\nWith JSONObject this may be re-written as below, using list comprehension. This makes the code more readable and less cluttered when working with complex dictionary structures in code.\n\n::\n\n    from python_easy_json import JSONObject\n\n    for row in [JSONObject(r) for r in results]:\n        if row.the_key[0].another_key == 'the_value':\n            ...\n\nData from a JSON String\n\n::\n\n    from python_easy_json import JSONObject\n    \n    # JSON string\n    obj = JSONObject('{\"test_key\": \"test_value\"}')\n    print(obj.to_json())\n\n    {\"test_key\": \"test_value\"}\n\nData from a python dictionary\n\n::\n\n    # Python dictionary\n    obj = JSONObject({'test_key': 'test_value'})\n    print(obj.to_json())\n\n    {\"test_key\": \"test_value\"}\n\n\nData Models For Anything\n========================\n\nUsing the python-easy-json JSONObject class, you can create data models, including deeply nested models and arrays, from any\nJSON string or dictionary. Additionally, python \"Type Hints\" may be used to cast values to the type defined by the type \nhint annotations.\n\nAs a bonus; IDEs with auto-completion and support for python type hinting will auto-complete model properties as you type. \n\nThis example shows how to define nested/child data models, including lists of nested data models.\n\n::\n\n    # Represents json from 'tests/test_data/nested_data_1.json'\n    class CakeToppingTypeModel(JSONObject):\n        id: int = None\n        type: str = None    \n    \n    class CakeBatterTypeModel(JSONObject):\n        id: int = None\n        type: str = None    \n    \n    class CakeBatterModel(JSONObject):\n        batter: List[CakeBatterTypeModel] = None    \n    \n    class CakeModel(JSONObject):\n        id: str = None\n        type: str = None\n        name: str = None\n        ppu: float = None\n        batters: CakeBatterModel = None\n        topping: List[CakeToppingTypeModel]\n\n    cake = CakeModel(data)\n    print(f'Cake: {cake.name} ({len(cake.batters.batter)} ingredents).') \n\n    Cake: Devil's Food Cake (4 ingredients).\n\n\nType Hints Automatically Convert JSON Values\n============================================\nIf a model has been defined and the properties have python Type Hint annotations, the JSONObject can convert values \nto the annotation types.\n\n::\n\n    from datetime import datetime \n\n    class TimestampModel(JSONObject):\n        id: int = None\n        timestamp: datetime = None\n\n    data = {'id': \"123\", \"timestamp\": \"2022-09-19 10:11:01.123456\"}\n    obj = TimestampModel(data, cast_types=True)\n\n    if obj.id > 0:\n        print(f\"ID: {obj.id}: {obj.timestamp.strftime('%b %d, %Y @ %H:%M:%S %p')}\")\n\n    $ ID: 123: Sep 19, 2022 @ 10:11:01 AM\n\nDocumentation\n=============\n\n**JSONObject Class**\n\n::\n\n    JSONObject.__init__(data: Union[Dict, str, None] = None, cast_types: bool = False, ordered: bool = False)\n        Load the dictionary or JSON string data argument into ourselves as properties.\n        :param data: Dictionary or valid JSON string.\n        :param cast_types: If properties of this class are type annotated, try to cast them.\n        :param ordered: Use OrderedDict() if set, otherwise use dict(). For python <= 3.6.\n\n    JSONObject.to_json(indent: int = None)\n        Export stored data as a json string.\n        :param indent: Positive integer value for formatting JSON string indenting.\n        :returns: JSON string\n\n    JSONObject.to_dict(recursive: bool = True, dates_to_str: bool = False)        \n        Export stored data as a python dictionary object.\n        :param recursive: Boolean, recursively convert nested JSONObjects to a dict\n        :param dates_to_str: Boolean, convert all date or datetime values to string.\n        :returns: dictionary object\n\n    JSONObject.update([Dict|List|Tuple]) accepts either a dictionary object or an iterable of key/value\n        pairs (as tuples or other iterables of length two). If keyword arguments are specified, the dictionary\n        is then updated with those key/value pairs: obj.update(sky=1, cloud=2).\n\n    Plus Operator: Two JSONObjects may be merged using the plus (+) operator: obj = obj + other_obj.\n\n    Number of Properties: The number of managed properties may be determined by using the Python 'len()'\n        function: len(obj) == 5.\n\nProject Links\n=============\n\n- PyPI: https://pypi.python.org/pypi/python-easy-json\n- Issues: https://github.com/robabram/python-easy-json/issues\n\nLicense\n=======\n\nMIT licensed. See the bundled `LICENSE <https://github.com/robabram/python-easy-json/blob/main/LICENSE>` file for more details.\n\n\nUnittest Data\n-------------\n\nTesting JSON data for examples and unittests sourced from: https://opensource.adobe.com/Spry/samples/data_region/JSONDataSetSample.html\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "A simple, yet powerful, JSON/python dictionary to object deserialization",
    "version": "1.2.0",
    "project_urls": {
        "Changelog": "https://pypi.python.org/pypi/python-easy-json",
        "Homepage": "https://github.com/robabram/python-easy-json",
        "Issues": "https://github.com/robabram/python-easy-json/issues"
    },
    "split_keywords": [
        "serialization",
        " rest",
        " json",
        " api",
        " marshal",
        " marshalling",
        " deserialization",
        " schema",
        " model",
        " models",
        " data"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "9bd580200cf116782fc6af5218aaa9c1d0d7bab0ed9820943048f03f7e14090f",
                "md5": "935d0dbc27ec2740d7a01893e2235275",
                "sha256": "6ad5e7fae840e0019c2789283ca3005289cc74a0dc10bb651076f6e6abf8a3fc"
            },
            "downloads": -1,
            "filename": "python_easy_json-1.2.0-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "935d0dbc27ec2740d7a01893e2235275",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.6",
            "size": 8698,
            "upload_time": "2024-07-14T14:43:01",
            "upload_time_iso_8601": "2024-07-14T14:43:01.891854Z",
            "url": "https://files.pythonhosted.org/packages/9b/d5/80200cf116782fc6af5218aaa9c1d0d7bab0ed9820943048f03f7e14090f/python_easy_json-1.2.0-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "fdd75982f24b5cacd68c19903f28c7d8dba679b151886fb9901def2db4a65fd7",
                "md5": "0476b688e8a7c2773af029c676619e4c",
                "sha256": "964c5e1be1a3adcd1dd14e5ffb922ab708c2ec5471a28ba0949b3b5ff28fb8b6"
            },
            "downloads": -1,
            "filename": "python_easy_json-1.2.0.tar.gz",
            "has_sig": false,
            "md5_digest": "0476b688e8a7c2773af029c676619e4c",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.6",
            "size": 17713,
            "upload_time": "2024-07-14T14:43:03",
            "upload_time_iso_8601": "2024-07-14T14:43:03.201203Z",
            "url": "https://files.pythonhosted.org/packages/fd/d7/5982f24b5cacd68c19903f28c7d8dba679b151886fb9901def2db4a65fd7/python_easy_json-1.2.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-07-14 14:43:03",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "robabram",
    "github_project": "python-easy-json",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "requirements": [],
    "lcname": "python-easy-json"
}
        
Elapsed time: 4.16782s