jsonweb.encode – encode your python classes

Often times in a web application the data you wish to return to users is described by some sort of data model or resource in the form of a class object. This module provides an easy way to encode your python class instances to JSON. Here is a quick example:

>>> from jsonweb.encode import to_object, dumper
>>> @to_object()
... class DataModel(object):
...      def __init__(self, id, value):
...          self.id = id
...          self.value = value
        
>>> data = DataModel(5, "foo")
>>> dumper(data)
'{"__type__": "DataModel", "id": 5, "value": "foo"}'

If you have a class you wish to serialize to a JSON object decorate it with to_object(). If your class should serialize into a JSON list decorate it with to_list().

dumper

jsonweb.encode.dumper(obj, **kw)

JSON encode your class instances by calling this function as you would call json.dumps(). kw args will be passed to the underlying json.dumps call.

Parameters:
  • handlers – A dict of type name/handler callable to use. ie {“Person:” person_handler}
  • cls – To override the given encoder. Should be a subclass of JsonWebEncoder.
  • suppress – A list of extra fields to suppress (as well as those suppressed by the class).
  • exclude_nulls – Set True to suppress keys with null (None) values from the JSON output. Defaults to False.

Decorators

jsonweb.encode.to_object(cls_type=None, suppress=None, handler=None, exclude_nulls=False)

To make your class instances JSON encodable decorate them with to_object(). The python built-in dir() is called on the class instance to retrieve key/value pairs that will make up the JSON object (Minus any attributes that start with an underscore or any attributes that were specified via the suppress keyword argument).

Here is an example:

>>> from jsonweb import to_object
>>> @to_object()
... class Person(object):
...     def __init__(self, first_name, last_name):
...         self.first_name = first_name
...         self.last_name = last_name
        
>>> person = Person("Shawn", "Adams")
>>> dumper(person)
'{"__type__": "Person", "first_name": "Shawn", "last_name": "Adams"}'

A __type__ key is automatically added to the JSON object. Its value should represent the object type being encoded. By default it is set to the value of the decorated class’s __name__ attribute. You can specify your own value with cls_type:

>>> from jsonweb import to_object
>>> @to_object(cls_type="PersonObject")
... class Person(object):
...     def __init__(self, first_name, last_name):
...         self.first_name = first_name
...         self.last_name = last_name
        
>>> person = Person("Shawn", "Adams")
>>> dumper(person)
'{"__type__": "PersonObject", "first_name": "Shawn", "last_name": "Adams"}'

If you would like to leave some attributes out of the resulting JSON simply use the suppress kw argument to pass a list of attribute names:

>>> from jsonweb import to_object
>>> @to_object(suppress=["last_name"])
... class Person(object):
...     def __init__(self, first_name, last_name):
...         self.first_name = first_name
...         self.last_name = last_name

>>> person = Person("Shawn", "Adams")
>>> dumper(person)
'{"__type__": "Person", "first_name": "Shawn"}'        

You can even suppress the __type__ attribute

@to_object(suppress=["last_name", "__type__"])
...

Sometimes it’s useful to suppress None values from your JSON output. Setting exclude_nulls to True will accomplish this

>>> from jsonweb import to_object
>>> @to_object(exclude_nulls=True)
... class Person(object):
...     def __init__(self, first_name, last_name):
...         self.first_name = first_name
...         self.last_name = last_name

>>> person = Person("Shawn", None)
>>> dumper(person)
'{"__type__": "Person", "first_name": "Shawn"}'

Note

You can also pass most of these arguments to dumper(). They will take precedence over what you passed to to_object() and only effects that one call.

If you need greater control over how your object is encoded you can specify a handler callable. It should accept one argument, which is the object to encode, and it should return a dict. This would override the default object handler JsonWebEncoder.object_handler().

Here is an example:

>>> from jsonweb import to_object
>>> def person_encoder(person):
...     return {"FirstName": person.first_name, 
...         "LastName": person.last_name}
...
>>> @to_object(handler=person_encoder)
... class Person(object):
...     def __init__(self, first_name, last_name):
...         self.guid = 12334
...         self.first_name = first_name
...         self.last_name = last_name
        
>>> person = Person("Shawn", "Adams")
>>> dumper(person)
'{"FirstName": "Shawn", "LastName": "Adams"}'

You can also use the alternate decorator syntax to accomplish this. See jsonweb.encode.handler().

jsonweb.encode.to_list(handler=None)

If your class instances should serialize into a JSON list decorate it with to_list(). By default The python built in list will be called with your class instance as its argument. ie list(obj). This means your class needs to define the __iter__ method.

Here is an example:

@to_object(suppress=["__type__"])
class Person(object):
    def __init__(self, first_name, last_name):
        self.first_name = first_name
        self.last_name = last_name
        
@to_list()
class People(object):
    def __init__(self, *persons):
        self.persons = persons
        
    def __iter__(self):
        for p in self.persons:
            yield p
            
people = People(
    Person("Luke", "Skywalker"),
    Person("Darth", "Vader"),
    Person("Obi-Wan" "Kenobi")
)

Encoding people produces this JSON:

[
    {"first_name": "Luke", "last_name": "Skywalker"}, 
    {"first_name": "Darth", "last_name": "Vader"}, 
    {"first_name": "Obi-Wan", "last_name": "Kenobi"}
]    

New in version 0.6.0: You can now specify a custom handler callable with the handler kw argument. It should accept one argument, your class instance. You can also use the jsonweb.encode.handler() decorator to mark one of the class’s methods as the list handler.

jsonweb.encode.handler(func)

Use this decorator to mark a method on a class as being its jsonweb encode handler. It will be called any time your class is serialized to a JSON string.

>>> from jsonweb import encode           
>>> @encode.to_object()
... class Person(object):
...     def __init__(self, first_name, last_name):
...         self.first_name = first_name
...         self.last_name = last_name
...     @encode.handler
...     def to_obj(self):
...         return {"FirstName": person.first_name, 
...             "LastName": person.last_name}
...
>>> @encode.to_list()
... class People(object):
...     def __init__(self, *persons):
...         self.persons = persons        
...     @encode.handler
...     def to_list(self):
...         return self.persons
...
>>> people = People(
...     Person("Luke", "Skywalker"),
...     Person("Darth", "Vader"),
...     Person("Obi-Wan" "Kenobi")
... )
...
>>> print dumper(people, indent=2)
[
  {
    "FirstName": "Luke", 
    "LastName": "Skywalker"
  }, 
  {
    "FirstName": "Darth", 
    "LastName": "Vader"
  }, 
  {
    "FirstName": "Obi-Wan", 
    "LastName": "Kenobi"
  }
]

JsonWebEncoder

class jsonweb.encode.JsonWebEncoder(**kw)

This json.JSONEncoder subclass is responsible for encoding instances of classes that have been decorated with to_object() or to_list(). Pass JsonWebEncoder as the value for the cls keyword argument to json.dump() or json.dumps().

Example:

json.dumps(obj_instance, cls=JsonWebEncoder)

Using dumper() is a shortcut for the above call to json.dumps()

dumper(obj_instance) #much nicer!
default(o)

Implement this method in a subclass such that it returns a serializable object for o, or calls the base implementation (to raise a TypeError).

For example, to support arbitrary iterators, you could implement default like this:

def default(self, o):
    try:
        iterable = iter(o)
    except TypeError:
        pass
    else:
        return list(iterable)
    # Let the base class default method raise the TypeError
    return JSONEncoder.default(self, o)
list_handler(obj)

Handles encoding instance objects of classes decorated by to_list(). Simply calls list on obj.

Note

Override this method if you wish to change how ALL objects are encoded into JSON lists.

object_handler(obj)

Handles encoding instance objects of classes decorated by to_object(). Returns a dict containing all the key/value pairs in obj.__dict__. Excluding attributes that

  • start with an underscore.
  • were specified with the suppress keyword argument.

The returned dict will be encoded into JSON.

Note

Override this method if you wish to change how ALL objects are encoded into JSON objects.