Quick start

This a quick overview of the module adapted from the python-rapidjson quickstart documentation.

Installation

First install yggdrasil-python-rapidjson:

$ pip install yggdrasil-python-rapidjson

If possible this installs a binary wheel, containing the latest version of the package already compiled for your system. Otherwise it will download a source distribution and will try to compile it: as the module is written in C++, in this case you most probably will need to install a minimal C++ compiler toolchain on your system.

Alternatively it is also possible to install it using Conda.

Basic examples

yggdrasil-python-rapidjson makes use of the python-rapidjson method wrappers that try to be compatible with the standard library json.dumps() and json.loads() functions.

Basic usage looks like this (adapted from the python-rapidjson documentation):

>>> from pprint import pprint
>>> from yggdrasil_rapidjson import dumps, loads
>>> data = {'foo': 100, 'bar': 'baz'}
>>> dumps(data, sort_keys=True) # for doctest
'{"bar":"baz","foo":100}'
>>> pprint(loads('{"bar":"baz","foo":100}'))
{'bar': 'baz', 'foo': 100}

All JSON data types are supported using their native Python counterparts:

>>> int_number = 42
>>> float_number = 1.4142
>>> string = "√2 ≅ 1.4142"
>>> false = False
>>> true = True
>>> null = None
>>> array = [int_number, float_number, string, false, true, null]
>>> an_object = {'int': int_number, 'float': float_number,
...              'string': string,
...              'true': true, 'false': false,
...              'array': array }
>>> pprint(loads(dumps({'object': an_object})))
{'object': {'array': [42, 1.4142, '√2 ≅ 1.4142', False, True, None],
            'false': False,
            'float': 1.4142,
            'int': 42,
            'string': '√2 ≅ 1.4142',
            'true': True}}

Python’s lists, tuples and iterators get serialized as JSON arrays:

>>> names_t = ('Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat')
>>> names_l = list(names_t)
>>> names_i = iter(names_l)
>>> def names_g():
...     for name in names_t:
...         yield name
>>> dumps(names_t) == dumps(names_l) == dumps(names_i) == dumps(names_g())
True

From python-rapidjson, yggdrasil-python-rapidjson can also handle some other commonly used data types (e.g. bytes, datetime.datetime, uuid.UUID, decimal.Decimal). yggdrasil-python-rapidjson adds support for some additional types including numpy arrays, pandas dataframes, Python classes, Python functions, and the added wrapper classes for the YggdrasilRapidJSON extension types (yggdrasil_rapidjson.units.Quantity, yggdrasil_rapidjson.units.QuantityArray, yggdrasil_rapidjson.geometry.Ply, yggdrasil_rapidjson.geometry.ObjWavefront):

>>> import numpy as np
>>> import pandas as pd
>>> from yggdrasil_rapidjson import units, geometry
>>> some_array = np.array([[0, 1, 2, 3], [4, 5, 6, 7]], dtype='int8')
>>> dumps(some_array)
'"-YGG-eyJ0eXBlIjoibmRhcnJheSIsInN1YnR5cGUiOiJpbnQiLCJwcmVjaXNpb24iOjEsInNoYXBlIjpbMiw0XX0=-YGG-AAECAwQFBgc=-YGG-"'
>>> as_json = _
>>> pprint(loads(as_json))
array([[0, 1, 2, 3],
       [4, 5, 6, 7]], dtype=int8)
>>> some_structured_array = np.array([('Rex', 9, 81.0), ('Fido', 3, 27.0)], dtype=[('name', 'U10'), ('age', 'i4'), ('weight', 'f4')])
>>> dumps(some_structured_array)
'["-YGG-eyJ0eXBlIjoibmRhcnJheSIsInN1YnR5cGUiOiJzdHJpbmciLCJwcmVjaXNpb24iOjQwLCJzaGFwZSI6WzJdLCJlbmNvZGluZyI6IlVDUzQiLCJ0aXRsZSI6Im5hbWUifQ==-YGG-UgAAAGUAAAB4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEYAAABpAAAAZAAAAG8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=-YGG-","-YGG-eyJ0eXBlIjoibmRhcnJheSIsInN1YnR5cGUiOiJpbnQiLCJwcmVjaXNpb24iOjQsInNoYXBlIjpbMl0sInRpdGxlIjoiYWdlIn0=-YGG-CQAAAAMAAAA=-YGG-","-YGG-eyJ0eXBlIjoibmRhcnJheSIsInN1YnR5cGUiOiJmbG9hdCIsInByZWNpc2lvbiI6NCwic2hhcGUiOlsyXSwidGl0bGUiOiJ3ZWlnaHQifQ==-YGG-AACiQgAA2EE=-YGG-"]'
>>> as_json = _
>>> pprint(loads(as_json))
array([('Rex', 9, 81.), ('Fido', 3, 27.)],
      dtype=[('name', '<U10'), ('age', '<i4'), ('weight', '<f4')])
>>> some_dataframe = pd.DataFrame(some_structured_array)
>>> dumps(some_dataframe)
'["-YGG-eyJ0eXBlIjoibmRhcnJheSIsInN1YnR5cGUiOiJzdHJpbmciLCJwcmVjaXNpb24iOjE2LCJzaGFwZSI6WzJdLCJlbmNvZGluZyI6IlVDUzQiLCJ0aXRsZSI6Im5hbWUifQ==-YGG-UgAAAGUAAAB4AAAAAAAAAEYAAABpAAAAZAAAAG8AAAA=-YGG-","-YGG-eyJ0eXBlIjoibmRhcnJheSIsInN1YnR5cGUiOiJpbnQiLCJwcmVjaXNpb24iOjQsInNoYXBlIjpbMl0sInRpdGxlIjoiYWdlIn0=-YGG-CQAAAAMAAAA=-YGG-","-YGG-eyJ0eXBlIjoibmRhcnJheSIsInN1YnR5cGUiOiJmbG9hdCIsInByZWNpc2lvbiI6NCwic2hhcGUiOlsyXSwidGl0bGUiOiJ3ZWlnaHQifQ==-YGG-AACiQgAA2EE=-YGG-"]'
>>> as_json = _
>>> pprint(loads(as_json))
array([('Rex', 9, 81.), ('Fido', 3, 27.)],
      dtype=[('name', '<U4'), ('age', '<i4'), ('weight', '<f4')])
>>> some_speed = units.Quantity(3.2, 'cm/s')
>>> dumps({'a speed': some_speed})
'{"a speed":"-YGG-eyJ0eXBlIjoic2NhbGFyIiwic3VidHlwZSI6ImZsb2F0IiwicHJlY2lzaW9uIjo4LCJ1bml0cyI6ImNtKihzKiotMSkifQ==-YGG-mpmZmZmZCUA=-YGG-"}'
>>> as_json = _
>>> pprint(loads(as_json))
{'a speed': Quantity(3.2, 'cm*(s**-1)')}
>>> vertices = np.array([[0, 0, 0, 0], [0, 0, 1, 1], [0, 1, 1, 0]])
>>> faces =  np.array([[0, 0], [1, 2], [2, 3]])
>>> some_geometry = geometry.ObjWavefront()
>>> some_geometry.add_elements('vertices', vertices)
>>> some_geometry.add_elements('faces', faces)
>>> dumps(some_geometry)
'"-YGG-eyJ0eXBlIjoib2JqIn0=-YGG-diAwLjAgMC4wIDAuMCAwLjAKdiAwLjAgMC4wIDEuMCAxLjAKdiAwLjAgMS4wIDEuMCAwLjAKZiAxIDEKZiAyIDMKZiAzIDQK-YGG-"'
>>> as_json = _
>>> pprint(loads(as_json))
<yggdrasil_rapidjson.geometry.ObjWavefront object at ...>