update json docs

This commit is contained in:
David Lord 2020-04-07 12:33:00 -07:00
parent 8b5f760b72
commit 756902cca1
No known key found for this signature in database
GPG key ID: 7A1C87E3F5BC42A8
4 changed files with 140 additions and 133 deletions

View file

@ -6,6 +6,9 @@ Version 2.0.0
Unreleased Unreleased
- Drop support for Python 2 and 3.5. - Drop support for Python 2 and 3.5.
- JSON support no longer uses simplejson. To use another JSON module,
override ``app.json_encoder`` and ``json_decoder``. :issue:`3555`
- The ``encoding`` option to JSON functions is deprecated. :pr:`3562`
- Add :meth:`sessions.SessionInterface.get_cookie_name` to allow - Add :meth:`sessions.SessionInterface.get_cookie_name` to allow
setting the session cookie name dynamically. :pr:`3369` setting the session cookie name dynamically. :pr:`3369`
- Add :meth:`Config.from_file` to load config using arbitrary file - Add :meth:`Config.from_file` to load config using arbitrary file
@ -19,9 +22,6 @@ Unreleased
200 OK and an empty file. :issue:`3358` 200 OK and an empty file. :issue:`3358`
- When using ad-hoc certificates, check for the cryptography library - When using ad-hoc certificates, check for the cryptography library
instead of PyOpenSSL. :pr:`3492` instead of PyOpenSSL. :pr:`3492`
- JSON support no longer uses simplejson if it's installed. To use
another JSON module, override ``app.json_encoder`` and
``json_decoder``. :issue:`3555`
Version 1.1.2 Version 1.1.2

View file

@ -279,45 +279,34 @@ Message Flashing
.. autofunction:: get_flashed_messages .. autofunction:: get_flashed_messages
JSON Support JSON Support
------------ ------------
.. module:: flask.json .. module:: flask.json
Flask uses the built-in :mod:`json` module for the JSON implementation. Flask uses the built-in :mod:`json` module for handling JSON. It will
It will delegate access to the current application's JSON encoders and use the current blueprint's or application's JSON encoder and decoder
decoders for easier customization. for easier customization. By default it handles some extra data types:
For usage examples, read the :mod:`json` documentation in the standard - :class:`datetime.datetime` and :class:`datetime.date` are serialized
library. The following extensions are by default applied to the stdlib's to :rfc:`822` strings. This is the same as the HTTP date format.
JSON module: - :class:`uuid.UUID` is serialized to a string.
- :class:`dataclasses.dataclass` is passed to
:func:`dataclasses.asdict`.
- :class:`~markupsafe.Markup` (or any object with a ``__html__``
method) will call the ``__html__`` method to get a string.
1. ``datetime`` objects are serialized as :rfc:`822` strings. :func:`~htmlsafe_dumps` is also available as the ``|tojson`` template
2. Any object with an ``__html__`` method (like :class:`~flask.Markup`) filter. The filter marks the output with ``|safe`` so it can be used
will have that method called and then the return value is serialized inside ``script`` tags.
as string.
The :func:`~htmlsafe_dumps` function of this json module is also available
as a filter called ``|tojson`` in Jinja2. Note that in versions of Flask prior
to Flask 0.10, you must disable escaping with ``|safe`` if you intend to use
``|tojson`` output inside ``script`` tags. In Flask 0.10 and above, this
happens automatically (but it's harmless to include ``|safe`` anyway).
.. sourcecode:: html+jinja .. sourcecode:: html+jinja
<script type=text/javascript> <script type=text/javascript>
doSomethingWith({{ user.username|tojson|safe }}); renderChart({{ axis_data|tojson }});
</script> </script>
.. admonition:: Auto-Sort JSON Keys
The configuration variable :data:`JSON_SORT_KEYS` can be set to
``False`` to stop Flask from auto-sorting keys. By default sorting
is enabled and outside of the app context sorting is turned on.
Notice that disabling key sorting can cause issues when using
content based HTTP caches and Python's hash randomization feature.
.. autofunction:: jsonify .. autofunction:: jsonify
.. autofunction:: dumps .. autofunction:: dumps
@ -336,6 +325,7 @@ happens automatically (but it's harmless to include ``|safe`` anyway).
.. automodule:: flask.json.tag .. automodule:: flask.json.tag
Template Rendering Template Rendering
------------------ ------------------

View file

@ -19,33 +19,27 @@ except ImportError:
class JSONEncoder(_json.JSONEncoder): class JSONEncoder(_json.JSONEncoder):
"""The default Flask JSON encoder. This one extends the default """The default JSON encoder. Handles extra types compared to the
encoder by also supporting ``datetime``, ``UUID``, ``dataclasses``, built-in :class:`json.JSONEncoder`.
and ``Markup`` objects.
``datetime`` objects are serialized as RFC 822 datetime strings. - :class:`datetime.datetime` and :class:`datetime.date` are
This is the same as the HTTP date format. serialized to :rfc:`822` strings. This is the same as the HTTP
date format.
- :class:`uuid.UUID` is serialized to a string.
- :class:`dataclasses.dataclass` is passed to
:func:`dataclasses.asdict`.
- :class:`~markupsafe.Markup` (or any object with a ``__html__``
method) will call the ``__html__`` method to get a string.
In order to support more data types, override the :meth:`default` Assign a subclass of this to :attr:`flask.Flask.json_encoder` or
method. :attr:`flask.Blueprint.json_encoder` to override the default.
""" """
def default(self, o): def default(self, o):
"""Implement this method in a subclass such that it returns a """Convert ``o`` to a JSON serializable type. See
serializable object for ``o``, or calls the base implementation (to :meth:`json.JSONEncoder.default`. Python does not support
raise a :exc:`TypeError`). overriding how basic types like ``str`` or ``list`` are
serialized, they are handled before this method.
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): if isinstance(o, datetime):
return http_date(o.utctimetuple()) return http_date(o.utctimetuple())
@ -61,10 +55,13 @@ class JSONEncoder(_json.JSONEncoder):
class JSONDecoder(_json.JSONDecoder): class JSONDecoder(_json.JSONDecoder):
"""The default JSON decoder. This one does not change the behavior from """The default JSON decoder.
the default decoder. Consult the :mod:`json` documentation
for more information. This decoder is not only used for the load This does not change any behavior from the built-in
functions of this module but also :attr:`~flask.Request`. :class:`json.JSONDecoder`.
Assign a subclass of this to :attr:`flask.Flask.json_decoder` or
:attr:`flask.Blueprint.json_decoder` to override the default.
""" """
@ -98,22 +95,20 @@ def _load_arg_defaults(kwargs, app=None):
def dumps(obj, app=None, **kwargs): def dumps(obj, app=None, **kwargs):
"""Serialize ``obj`` to a JSON-formatted string. If there is an """Serialize an object to a string of JSON.
app context pushed, use the current app's configured encoder
(:attr:`~flask.Flask.json_encoder`), or fall back to the default
:class:`JSONEncoder`.
Takes the same arguments as the built-in :func:`json.dumps`, and Takes the same arguments as the built-in :func:`json.dumps`, with
does some extra configuration based on the application. some defaults from application configuration.
:param obj: Object to serialize to JSON. :param obj: Object to serialize to JSON.
:param app: App instance to use to configure the JSON encoder. :param app: Use this app's config instead of the active app context
Uses ``current_app`` if not given, and falls back to the default or defaults.
encoder when not in an app context. :param kwargs: Extra arguments passed to func:`json.dumps`.
:param kwargs: Extra arguments passed to :func:`json.dumps`.
.. versionchanged:: 2.0
``encoding`` is deprecated and will be removed in 2.1.
.. versionchanged:: 1.0.3 .. versionchanged:: 1.0.3
``app`` can be passed directly, rather than requiring an app ``app`` can be passed directly, rather than requiring an app
context for configuration. context for configuration.
""" """
@ -135,7 +130,21 @@ def dumps(obj, app=None, **kwargs):
def dump(obj, fp, app=None, **kwargs): def dump(obj, fp, app=None, **kwargs):
"""Like :func:`dumps` but writes into a file object.""" """Serialize an object to JSON written to a file object.
Takes the same arguments as the built-in :func:`json.dump`, with
some defaults from application configuration.
:param obj: Object to serialize to JSON.
:param fp: File object to write JSON to.
:param app: Use this app's config instead of the active app context
or defaults.
:param kwargs: Extra arguments passed to func:`json.dump`.
.. versionchanged:: 2.0
Writing to a binary file, and the ``encoding`` argument, is
deprecated and will be removed in 2.1.
"""
_dump_arg_defaults(kwargs, app=app) _dump_arg_defaults(kwargs, app=app)
encoding = kwargs.pop("encoding", None) encoding = kwargs.pop("encoding", None)
show_warning = encoding is not None show_warning = encoding is not None
@ -158,22 +167,21 @@ def dump(obj, fp, app=None, **kwargs):
def loads(s, app=None, **kwargs): def loads(s, app=None, **kwargs):
"""Deserialize an object from a JSON-formatted string ``s``. If """Deserialize an object from a string of JSON.
there is an app context pushed, use the current app's configured
decoder (:attr:`~flask.Flask.json_decoder`), or fall back to the
default :class:`JSONDecoder`.
Takes the same arguments as the built-in :func:`json.loads`, and Takes the same arguments as the built-in :func:`json.loads`, with
does some extra configuration based on the application. some defaults from application configuration.
:param s: JSON string to deserialize. :param s: JSON string to deserialize.
:param app: App instance to use to configure the JSON decoder. :param app: Use this app's config instead of the active app context
Uses ``current_app`` if not given, and falls back to the default or defaults.
encoder when not in an app context. :param kwargs: Extra arguments passed to func:`json.dump`.
:param kwargs: Extra arguments passed to :func:`json.dumps`.
.. versionchanged:: 2.0
``encoding`` is deprecated and will be removed in 2.1. The data
must be a string or UTF-8 bytes.
.. versionchanged:: 1.0.3 .. versionchanged:: 1.0.3
``app`` can be passed directly, rather than requiring an app ``app`` can be passed directly, rather than requiring an app
context for configuration. context for configuration.
""" """
@ -195,7 +203,20 @@ def loads(s, app=None, **kwargs):
def load(fp, app=None, **kwargs): def load(fp, app=None, **kwargs):
"""Like :func:`loads` but reads from a file object.""" """Deserialize an object from JSON read from a file object.
Takes the same arguments as the built-in :func:`json.load`, with
some defaults from application configuration.
:param fp: File object to read JSON from.
:param app: Use this app's config instead of the active app context
or defaults.
:param kwargs: Extra arguments passed to func:`json.load`.
.. versionchanged:: 2.0
``encoding`` is deprecated and will be removed in 2.1. The file
must be text mode, or binary mode with UTF-8 bytes.
"""
_load_arg_defaults(kwargs, app=app) _load_arg_defaults(kwargs, app=app)
encoding = kwargs.pop("encoding", None) encoding = kwargs.pop("encoding", None)
@ -219,84 +240,80 @@ _htmlsafe_map = str.maketrans(
def htmlsafe_dumps(obj, **kwargs): def htmlsafe_dumps(obj, **kwargs):
"""Works exactly like :func:`dumps` but is safe for use in ``<script>`` """Serialize an object to a string of JSON, replacing HTML-unsafe
tags. It accepts the same arguments and returns a JSON string. Note that characters with Unicode escapes. Otherwise behaves the same as
this is available in templates through the ``|tojson`` filter which will :func:`dumps`.
also mark the result as safe. Due to how this function escapes certain
characters this is safe even if used outside of ``<script>`` tags.
The following characters are escaped in strings: This is available in templates as the ``|tojson`` filter, which will
also mark the result with ``|safe``.
- ``<`` The returned string is safe to render in HTML documents and
- ``>`` ``<script>`` tags. The exception is in HTML attributes that are
- ``&`` double quoted; either use single quotes or the ``|forceescape``
- ``'`` filter.
This makes it safe to embed such strings in any place in HTML with the
notable exception of double quoted attributes. In that case single
quote your attributes or HTML escape it in addition.
.. versionchanged:: 0.10 .. versionchanged:: 0.10
This function's return value is now always safe for HTML usage, even Single quotes are escaped, making this safe to use in HTML,
if outside of script tags or if used in XHTML. This rule does not ``<script>`` tags, and single-quoted attributes without further
hold true when using this function in HTML attributes that are double escaping.
quoted. Always single quote attributes if you use the ``|tojson``
filter. Alternatively use ``|tojson|forceescape``.
""" """
return dumps(obj, **kwargs).translate(_htmlsafe_map) return dumps(obj, **kwargs).translate(_htmlsafe_map)
def htmlsafe_dump(obj, fp, **kwargs): def htmlsafe_dump(obj, fp, **kwargs):
"""Like :func:`htmlsafe_dumps` but writes into a file object.""" """Serialize an object to JSON written to a file object, replacing
HTML-unsafe characters with Unicode escapes. See
:func:`htmlsafe_dumps` and :func:`dumps`.
"""
fp.write(htmlsafe_dumps(obj, **kwargs)) fp.write(htmlsafe_dumps(obj, **kwargs))
def jsonify(*args, **kwargs): def jsonify(*args, **kwargs):
"""This function wraps :func:`dumps` to add a few enhancements that make """Serialize data to JSON and wrap it in a :class:`~flask.Response`
life easier. It turns the JSON output into a :class:`~flask.Response` with the :mimetype:`application/json` mimetype.
object with the :mimetype:`application/json` mimetype. For convenience, it
also converts multiple arguments into an array or multiple keyword arguments
into a dict. This means that both ``jsonify(1,2,3)`` and
``jsonify([1,2,3])`` serialize to ``[1,2,3]``.
For clarity, the JSON serialization behavior has the following differences Uses :func:`dumps` to serialize the data, but ``args`` and
from :func:`dumps`: ``kwargs`` are treated as data rather than arguments to
:func:`json.dumps`.
1. Single argument: Passed straight through to :func:`dumps`. 1. Single argument: Treated as a single value.
2. Multiple arguments: Converted to an array before being passed to 2. Multiple arguments: Treated as a list of values.
:func:`dumps`. ``jsonify(1, 2, 3)`` is the same as ``jsonify([1, 2, 3])``.
3. Multiple keyword arguments: Converted to a dict before being passed to 3. Keyword arguments: Treated as a dict of values.
:func:`dumps`. ``jsonify(data=data, errors=errors)`` is the same as
4. Both args and kwargs: Behavior undefined and will throw an exception. ``jsonify({"data": data, "errors": errors})``.
4. Passing both arguments and keyword arguments is not allowed as
it's not clear what should happen.
Example usage:: .. code-block:: python
from flask import jsonify from flask import jsonify
@app.route('/_get_current_user') @app.route("/users/me")
def get_current_user(): def get_current_user():
return jsonify(username=g.user.username, return jsonify(
email=g.user.email, username=g.user.username,
id=g.user.id) email=g.user.email,
id=g.user.id,
)
This will send a JSON response like this to the browser:: Will return a JSON response like this:
.. code-block:: javascript
{ {
"username": "admin", "username": "admin",
"email": "admin@localhost", "email": "admin@localhost",
"id": 42 "id": 42
} }
The default output omits indents and spaces after separators. In
debug mode or if :data:`JSONIFY_PRETTYPRINT_REGULAR` is ``True``,
the output will be formatted to be easier to read.
.. versionchanged:: 0.11 .. versionchanged:: 0.11
Added support for serializing top-level arrays. This introduces Added support for serializing top-level arrays. This introduces
a security risk in ancient browsers. See :ref:`security-json` a security risk in ancient browsers. See :ref:`security-json`.
for details.
This function's response will be pretty printed if the
``JSONIFY_PRETTYPRINT_REGULAR`` config parameter is set to True or the
Flask app is running in debug mode. Compressed (not pretty) formatting
currently means no indents and no spaces after separators.
.. versionadded:: 0.2 .. versionadded:: 0.2
""" """

View file

@ -45,7 +45,7 @@ from base64 import b64encode
from datetime import datetime from datetime import datetime
from uuid import UUID from uuid import UUID
from jinja2 import Markup from markupsafe import Markup
from werkzeug.http import http_date from werkzeug.http import http_date
from werkzeug.http import parse_date from werkzeug.http import parse_date
@ -167,9 +167,9 @@ class TagBytes(JSONTag):
class TagMarkup(JSONTag): class TagMarkup(JSONTag):
"""Serialize anything matching the :class:`~flask.Markup` API by """Serialize anything matching the :class:`~markupsafe.Markup` API by
having a ``__html__`` method to the result of that method. Always having a ``__html__`` method to the result of that method. Always
deserializes to an instance of :class:`~flask.Markup`.""" deserializes to an instance of :class:`~markupsafe.Markup`."""
__slots__ = () __slots__ = ()
key = " m" key = " m"
@ -222,7 +222,7 @@ class TaggedJSONSerializer:
* :class:`dict` * :class:`dict`
* :class:`tuple` * :class:`tuple`
* :class:`bytes` * :class:`bytes`
* :class:`~flask.Markup` * :class:`~markupsafe.Markup`
* :class:`~uuid.UUID` * :class:`~uuid.UUID`
* :class:`~datetime.datetime` * :class:`~datetime.datetime`
""" """