blob: ac2e1e9083f39d261f777991169203a688f1f4a7 [file] [log] [blame]
# -*- coding: utf-8 -*-
"""
webapp2_extras.json
===================
JSON helpers for webapp2.
:copyright: 2011 by tipfy.org.
:license: Apache Sotware License, see LICENSE for details.
"""
from __future__ import absolute_import
import base64
import urllib
try:
# Preference for installed library with updated fixes.
# Also available in Google App Engine SDK >= 1.4.2.
import simplejson as json
except ImportError: # pragma: no cover
try:
# Standard library module in Python >= 2.6.
import json
except ImportError: # pragma: no cover
raise RuntimeError(
'A JSON parser is required, e.g., simplejson at '
'http://pypi.python.org/pypi/simplejson/')
assert hasattr(json, 'loads') and hasattr(json, 'dumps'), \
'Expected a JSON module with the functions loads() and dumps().'
def encode(value, *args, **kwargs):
"""Serializes a value to JSON.
This comes from `Tornado`_.
:param value:
A value to be serialized.
:param args:
Extra arguments to be passed to `json.dumps()`.
:param kwargs:
Extra keyword arguments to be passed to `json.dumps()`.
:returns:
The serialized value.
"""
# By default encode using a compact format.
kwargs.setdefault('separators', (',', ':'))
# JSON permits but does not require forward slashes to be escaped.
# This is useful when json data is emitted in a <script> tag
# in HTML, as it prevents </script> tags from prematurely terminating
# the javascript. Some json libraries do this escaping by default,
# although python's standard library does not, so we do it here.
# See: http://goo.gl/WsXwv
return json.dumps(value, *args, **kwargs).replace("</", "<\\/")
def decode(value, *args, **kwargs):
"""Deserializes a value from JSON.
This comes from `Tornado`_.
:param value:
A value to be deserialized.
:param args:
Extra arguments to be passed to `json.loads()`.
:param kwargs:
Extra keyword arguments to be passed to `json.loads()`.
:returns:
The deserialized value.
"""
if isinstance(value, str):
value = value.decode('utf-8')
assert isinstance(value, unicode)
return json.loads(value, *args, **kwargs)
def b64encode(value, *args, **kwargs):
"""Serializes a value to JSON and encodes it using base64.
Parameters and return value are the same from :func:`encode`.
"""
return base64.b64encode(encode(value, *args, **kwargs))
def b64decode(value, *args, **kwargs):
"""Decodes a value using base64 and deserializes it from JSON.
Parameters and return value are the same from :func:`decode`.
"""
return decode(base64.b64decode(value), *args, **kwargs)
def quote(value, *args, **kwargs):
"""Serializes a value to JSON and encodes it using urllib.quote.
Parameters and return value are the same from :func:`encode`.
"""
return urllib.quote(encode(value, *args, **kwargs))
def unquote(value, *args, **kwargs):
"""Decodes a value using urllib.unquote and deserializes it from JSON.
Parameters and return value are the same from :func:`decode`.
"""
return decode(urllib.unquote(value), *args, **kwargs)