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-indir()
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 thesuppress
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 withcls_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. Settingexclude_nulls
toTrue
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 toto_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 handlerJsonWebEncoder.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 inlist
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 thejsonweb.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 withto_object()
orto_list()
. PassJsonWebEncoder
as the value for thecls
keyword argument tojson.dump()
orjson.dumps()
.Example:
json.dumps(obj_instance, cls=JsonWebEncoder)
Using
dumper()
is a shortcut for the above call tojson.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 aTypeError
).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 callslist
onobj
.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 inobj.__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.
-