[enh] Implement an extended JSON encoder and support sets

This commit is contained in:
Jérôme Lebleu 2014-12-04 23:34:53 +01:00
parent ab6d8c529f
commit 5d92898ee7
3 changed files with 35 additions and 2 deletions

View file

@ -16,6 +16,7 @@ from bottle import run, request, response, Bottle, HTTPResponse
from moulinette.core import MoulinetteError, clean_session
from moulinette.interfaces import (BaseActionsMapParser, BaseInterface)
from moulinette.utils.serialize import JSONExtendedEncoder
logger = logging.getLogger('moulinette.interface.api')
@ -462,7 +463,7 @@ def format_for_response(content):
# Return JSON-style response
response.content_type = 'application/json'
return json_encode(content)
return json_encode(content, cls=JSONExtendedEncoder)
# API Classes Implementation -------------------------------------------

View file

@ -48,6 +48,8 @@ def pretty_print_dict(d, depth=0):
"""
for k,v in sorted(d.items(), key=lambda x: x[0]):
k = colorize(str(k), 'purple')
if isinstance(v, (tuple, set)):
v = list(v)
if isinstance(v, list) and len(v) == 1:
v = v[0]
if isinstance(v, dict):
@ -202,7 +204,8 @@ class Interface(BaseInterface):
# Format and print result
if print_json:
import json
print(json.dumps(ret))
from moulinette.utils.serialize import JSONExtendedEncoder
print(json.dumps(ret, cls=JSONExtendedEncoder))
elif isinstance(ret, dict):
pretty_print_dict(ret)
else:

View file

@ -0,0 +1,29 @@
import logging
from json.encoder import JSONEncoder
logger = logging.getLogger('moulinette.utils.serialize')
# JSON utilities -------------------------------------------------------
class JSONExtendedEncoder(JSONEncoder):
"""Extended JSON encoder
Extend default JSON encoder to recognize more types and classes. It
will never raise if the object can't be encoded and return its repr
instead.
The following objects and types are supported:
- set: converted into list
"""
def default(self, o):
"""Return a serializable object"""
# Convert compatible containers into list
if isinstance(o, set) or (
hasattr(o, '__iter__') and hasattr(o, 'next')):
return list(o)
# Return the repr for object that json can't encode
logger.warning('cannot properly encode in JSON the object %s, '
'returned repr is: %r', type(o), o)
return repr(o)