jsonext

jsonext is a small library that collects commonly used implementations of JSON-serializers for various objects. A good example are datetime objects, which are commonly found in web applications. Since JSON does not know these types, they need to be serialized to strings - certainly not an impossible task, but tricky enough to get right when timezones are involved that it’s a turn off to reimplement them every time.

There are many other libraries on PyPI that somehow deal with this problem or a related one, though many of those are either dead or do a horrible job of wrapping the standard JSON library in funky ways.

Encoders and Mixins

jsonext works with the standard libraries facilities as closely as possible; new encoding methods are added as mixins:

from json import JSONEncoder
from jsonenc.mixins import JSONDateTimeMixin, JSONIterableMixin

class MyJSONEncoder(JSONDateTimeMixin, JSONIterableMixin, JSONEncoder):
    pass

# ...

enc = MyJSONEncoder()
enc.encode(data)

The example above will encode data as JSON, using JSONDateTimeMixin to encode any datetime objects found and any iterables using JSONIterableMixin. All these are just mixins for the stdlib’s JSONEncoder.

Behind the scene these mixins provide a default() method that will check for types it can encode and either return the result or call the superclasses default method. An example implementation for a custom class Foo is simple:

class JSONFooMixin(object):
    def default(self, o):
        if isinstance(o, Foo):
            # return anything composed of objects the encoder can handle
            return ('This is a Foo object as a tuple', Foo.value)
        return super(JSONFooMixin, self).default(o)

Shortcuts

Some shortcuts are provided if less customization is needed. The jsonext.JSONEncoder is a json.JSONEncoder with some commonly useful classes mixed in: JSONDateTimeMixin, JSONIterableMixin, JSONToDictMixin, JSONStringifyMixin and JSONEncoder.

In addition, the jsonext.dumps() function is the same as json.dumps(), except is uses jsonext.JSONEncoder as the encoder per default. This means that:

import jsonext

jsonext.dumps(some_data)

will just work.

API Reference

The following mixins are provided:

class jsonext.mixins.JSONDateTimeMixin

A mixin for JSONEncoders, encoding datetime.datetime and datetime.date objects by converting them to strings that can be parsed by all modern browsers JS Date() object.

All timestamps are converted to UTC before being serialized.

Date objects simply use isoformat().

>>> import jsonext
>>> from datetime import datetime
>>> dt = datetime(2013, 11, 17, 12, 00, 00)  # Python 3.3.3 release!
>>> jsonext.dumps(dt)
'"2013-11-17T12:00:00+00:00"'
>>> d = dt.date()
>>> d
datetime.date(2013, 11, 17)
>>> jsonext.dumps(d)
'"2013-11-17"'
class jsonext.mixins.JSONIterableMixin

A mixin for JSONEncoders, encoding any iterable type by converting it to a list.

Especially useful for SQLAlchemy results that look a lot like regular lists or iterators, but will trip up the encoder. Beware of infinite generators.

>>> import jsonext
>>> gen = (i**2 for i in range(10))
>>> jsonext.dumps(gen)
'[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]'
class jsonext.mixins.JSONStringifyMixin

A mixing for JSONEncoders, encoding any object that has a __str__ method with the return value of said function.

>>> import jsonext
>>> from decimal import Decimal as D
>>> x = D('123.456')
>>> jsonext.dumps(x)
'"123.456"'
>>> from datetime import timedelta
>>> t = timedelta(days=5, seconds=12345)
>>> jsonext.dumps(t)
'"5 days, 3:25:45"'
class jsonext.mixins.JSONToDictMixin

A mixin for JSONEncoders, encoding any object with a to_dict() method by calling that method and encoding the return value.

>>> import jsonext
>>> class Foo(object):
...   def __init__(self, a, b):
...     self.a = a
...     self.b = b
...   def to_dict(self):
...     return {'A': self.a, 'B': self.b}
...
>>> items = [Foo(1,2), Foo(3,4)]
>>> jsonext.dumps(items)
'[{"A": 1, "B": 2}, {"A": 3, "B": 4}]'

Table Of Contents

Related Topics

This Page