Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added wrapper module around simplejson/json for much simplified custo…
…mization.
- Loading branch information
Showing
9 changed files
with
224 additions
and
81 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -0,0 +1,146 @@ | |||
# -*- coding: utf-8 -*- | |||
""" | |||
flask.jsonimpl | |||
~~~~~~~~~~~~~~ | |||
Implementation helpers for the JSON support in Flask. | |||
:copyright: (c) 2012 by Armin Ronacher. | |||
:license: BSD, see LICENSE for more details. | |||
""" | |||
from datetime import datetime | |||
from .globals import current_app, request | |||
|
|||
from werkzeug.http import http_date | |||
|
|||
# Use the same json implementation as itsdangerous on which we | |||
# depend anyways. | |||
from itsdangerous import simplejson as _json | |||
|
|||
|
|||
# figure out if simplejson escapes slashes. This behavior was changed | |||
# from one version to another without reason. | |||
_slash_escape = '\\/' not in _json.dumps('/') | |||
|
|||
|
|||
__all__ = ['dump', 'dumps', 'load', 'loads', 'htmlsafe_dump', | |||
'htmlsafe_dumps', 'JSONDecoder', 'JSONEncoder', | |||
'jsonify'] | |||
|
|||
|
|||
class JSONEncoder(_json.JSONEncoder): | |||
"""The default Flask JSON encoder. This one extends the default simplejson | |||
encoder by also supporting ``datetime`` objects as well as ``Markup`` | |||
objects which are serialized as RFC 822 datetime strings (same as the HTTP | |||
date format). In order to support more data types override the | |||
:meth:`default` method. | |||
""" | |||
|
|||
def default(self, 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) | |||
return JSONEncoder.default(self, o) | |||
""" | |||
if isinstance(o, datetime): | |||
return http_date(o) | |||
if hasattr(o, '__html__'): | |||
return unicode(o.__html__()) | |||
return _json.JSONEncoder.default(self, o) | |||
|
|||
|
|||
class JSONDecoder(_json.JSONDecoder): | |||
"""The default JSON decoder. This one does not change the behavior from | |||
the default simplejson encoder. Consult the :mod:`json` documentation | |||
for more information. This decoder is not only used for the load | |||
functions of this module but also :attr:`~flask.Request`. | |||
""" | |||
|
|||
|
|||
def dumps(obj, **kwargs): | |||
"""Serialize ``obj`` to a JSON formatted ``str`` by using the application's | |||
configured encoder (:attr:`~flask.Flask.json_encoder`). | |||
""" | |||
kwargs.setdefault('cls', current_app.json_encoder) | |||
return _json.dumps(obj, **kwargs) | |||
|
|||
|
|||
def dump(obj, fp, **kwargs): | |||
"""Like :func:`dumps` but writes into a file object.""" | |||
kwargs.setdefault('cls', current_app.json_encoder) | |||
return _json.dump(obj, fp, **kwargs) | |||
|
|||
|
|||
def loads(s, **kwargs): | |||
"""Unserialize a JSON object from a string ``s`` by using the application's | |||
configured decoder (:attr:`~flask.Flask.json_decoder`). | |||
""" | |||
kwargs.setdefault('cls', current_app.json_decoder) | |||
return _json.loads(s, **kwargs) | |||
|
|||
|
|||
def load(fp, **kwargs): | |||
"""Like :func:`loads` but reads from a file object. | |||
""" | |||
kwargs.setdefault('cls', current_app.json_decoder) | |||
return _json.load(fp, **kwargs) | |||
|
|||
|
|||
def htmlsafe_dumps(obj, **kwargs): | |||
"""Works exactly like :func:`dumps` but is safe for use in ``<script>`` | |||
tags. It accepts the same arguments and returns a JSON string. Note that | |||
this is available in templates through the ``|tojson`` filter but it will | |||
have to be wrapped in ``|safe`` unless **true** XHTML is being used. | |||
""" | |||
rv = dumps(obj, **kwargs) | |||
if _slash_escape: | |||
rv = rv.replace('/', '\\/') | |||
return rv.replace('<!', '<\\u0021') | |||
|
|||
|
|||
def htmlsafe_dump(obj, fp, **kwargs): | |||
"""Like :func:`htmlsafe_dumps` but writes into a file object.""" | |||
fp.write(htmlsafe_dumps(obj, **kwargs)) | |||
|
|||
|
|||
def jsonify(*args, **kwargs): | |||
"""Creates a :class:`~flask.Response` with the JSON representation of | |||
the given arguments with an `application/json` mimetype. The arguments | |||
to this function are the same as to the :class:`dict` constructor. | |||
Example usage:: | |||
@app.route('/_get_current_user') | |||
def get_current_user(): | |||
return jsonify(username=g.user.username, | |||
email=g.user.email, | |||
id=g.user.id) | |||
This will send a JSON response like this to the browser:: | |||
{ | |||
"username": "admin", | |||
"email": "admin@localhost", | |||
"id": 42 | |||
} | |||
This requires Python 2.6 or an installed version of simplejson. For | |||
security reasons only objects are supported toplevel. For more | |||
information about this, have a look at :ref:`json-security`. | |||
.. versionadded:: 0.2 | |||
""" | |||
return current_app.response_class(dumps(dict(*args, **kwargs), | |||
indent=None if request.is_xhr else 2), | |||
mimetype='application/json') |
Oops, something went wrong.
Something about the wording here sounds weird. Could anyone fix this?