# -*- coding: utf-8 -*-"""flask.json~~~~~~~~~~:copyright: © 2010 by the Pallets team.:license: BSD, see LICENSE for more details."""import codecsimport ioimport uuidfrom datetime import date, datetimefrom flask.globals import current_app, requestfrom flask._compat import text_type, PY2from werkzeug.http import http_datefrom jinja2 import Markup# Use the same json implementation as itsdangerous on which we# depend anyways.from itsdangerous import json 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']def _wrap_reader_for_text(fp, encoding):if isinstance(fp.read(0), bytes):fp = io.TextIOWrapper(io.BufferedReader(fp), encoding)return fpdef _wrap_writer_for_text(fp, encoding):try:fp.write('')except TypeError:fp = io.TextIOWrapper(fp, encoding)return fpclass JSONEncoder(_json.JSONEncoder):"""The default Flask JSON encoder. This one extends the default simplejsonencoder by also supporting ``datetime`` objects, ``UUID`` as well as``Markup`` objects which are serialized as RFC 822 datetime strings (sameas 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 aserializable object for ``o``, or calls the base implementation (toraise a :exc:`TypeError`).For example, to support arbitrary iterators, you could implementdefault like this::def default(self, o):try:iterable = iter(o)except TypeError:passelse:return list(iterable)return JSONEncoder.default(self, o)"""if isinstance(o, datetime):return http_date(o.utctimetuple())if isinstance(o, date):return http_date(o.timetuple())if isinstance(o, uuid.UUID):return str(o)if hasattr(o, '__html__'):return text_type(o.__html__())return _json.JSONEncoder.default(self, o)class JSONDecoder(_json.JSONDecoder):"""The default JSON decoder. This one does not change the behavior fromthe default simplejson decoder. Consult the :mod:`json` documentationfor more information. This decoder is not only used for the loadfunctions of this module but also :attr:`~flask.Request`."""def _dump_arg_defaults(kwargs):"""Inject default arguments for dump functions."""if current_app:bp = current_app.blueprints.get(request.blueprint) if request else Nonekwargs.setdefault('cls',bp.json_encoder if bp and bp.json_encoderelse current_app.json_encoder)if not current_app.config['JSON_AS_ASCII']:kwargs.setdefault('ensure_ascii', False)kwargs.setdefault('sort_keys', current_app.config['JSON_SORT_KEYS'])else:kwargs.setdefault('sort_keys', True)kwargs.setdefault('cls', JSONEncoder)def _load_arg_defaults(kwargs):"""Inject default arguments for load functions."""if current_app:bp = current_app.blueprints.get(request.blueprint) if request else Nonekwargs.setdefault('cls',bp.json_decoder if bp and bp.json_decoderelse current_app.json_decoder)else:kwargs.setdefault('cls', JSONDecoder)def detect_encoding(data):"""Detect which UTF codec was used to encode the given bytes.The latest JSON standard (:rfc:`8259`) suggests that only UTF-8 isaccepted. Older documents allowed 8, 16, or 32. 16 and 32 can be bigor little endian. Some editors or libraries may prepend a BOM.:param data: Bytes in unknown UTF encoding.:return: UTF encoding name"""head = data[:4]if head[:3] == codecs.BOM_UTF8:return 'utf-8-sig'if b'\x00' not in head:return 'utf-8'if head in (codecs.BOM_UTF32_BE, codecs.BOM_UTF32_LE):return 'utf-32'if head[:2] in (codecs.BOM_UTF16_BE, codecs.BOM_UTF16_LE):return 'utf-16'if len(head) == 4:if head[:3] == b'\x00\x00\x00':return 'utf-32-be'if head[::2] == b'\x00\x00':return 'utf-16-be'if head[1:] == b'\x00\x00\x00':return 'utf-32-le'if head[1::2] == b'\x00\x00':return 'utf-16-le'if len(head) == 2:return 'utf-16-be' if head.startswith(b'\x00') else 'utf-16-le'return 'utf-8'def dumps(obj, **kwargs):"""Serialize ``obj`` to a JSON formatted ``str`` by using the application'sconfigured encoder (:attr:`~flask.Flask.json_encoder`) if there is anapplication on the stack.This function can return ``unicode`` strings or ascii-only bytestrings bydefault which coerce into unicode strings automatically. That behavior bydefault is controlled by the ``JSON_AS_ASCII`` configuration variableand can be overridden by the simplejson ``ensure_ascii`` parameter."""_dump_arg_defaults(kwargs)encoding = kwargs.pop('encoding', None)rv = _json.dumps(obj, **kwargs)if encoding is not None and isinstance(rv, text_type):rv = rv.encode(encoding)return rvdef dump(obj, fp, **kwargs):"""Like :func:`dumps` but writes into a file object."""_dump_arg_defaults(kwargs)encoding = kwargs.pop('encoding', None)if encoding is not None:fp = _wrap_writer_for_text(fp, encoding)_json.dump(obj, fp, **kwargs)def loads(s, **kwargs):"""Unserialize a JSON object from a string ``s`` by using the application'sconfigured decoder (:attr:`~flask.Flask.json_decoder`) if there is anapplication on the stack."""_load_arg_defaults(kwargs)if isinstance(s, bytes):encoding = kwargs.pop('encoding', None)if encoding is None:encoding = detect_encoding(s)s = s.decode(encoding)return _json.loads(s, **kwargs)def load(fp, **kwargs):"""Like :func:`loads` but reads from a file object."""_load_arg_defaults(kwargs)if not PY2:fp = _wrap_reader_for_text(fp, kwargs.pop('encoding', None) or 'utf-8')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 thatthis is available in templates through the ``|tojson`` filter which willalso mark the result as safe. Due to how this function escapes certaincharacters this is safe even if used outside of ``<script>`` tags.The following characters are escaped in strings:- ``<``- ``>``- ``&``- ``'``This makes it safe to embed such strings in any place in HTML with thenotable exception of double quoted attributes. In that case singlequote your attributes or HTML escape it in addition... versionchanged:: 0.10This function's return value is now always safe for HTML usage, evenif outside of script tags or if used in XHTML. This rule does nothold true when using this function in HTML attributes that are doublequoted. Always single quote attributes if you use the ``|tojson``filter. Alternatively use ``|tojson|forceescape``."""rv = dumps(obj, **kwargs) \.replace(u'<', u'\\u003c') \.replace(u'>', u'\\u003e') \.replace(u'&', u'\\u0026') \.replace(u"'", u'\\u0027')if not _slash_escape:rv = rv.replace('\\/', '/')return rvdef htmlsafe_dump(obj, fp, **kwargs):"""Like :func:`htmlsafe_dumps` but writes into a file object."""fp.write(text_type(htmlsafe_dumps(obj, **kwargs)))def jsonify(*args, **kwargs):"""This function wraps :func:`dumps` to add a few enhancements that makelife easier. It turns the JSON output into a :class:`~flask.Response`object with the :mimetype:`application/json` mimetype. For convenience, italso converts multiple arguments into an array or multiple keyword argumentsinto 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 differencesfrom :func:`dumps`:1. Single argument: Passed straight through to :func:`dumps`.2. Multiple arguments: Converted to an array before being passed to:func:`dumps`.3. Multiple keyword arguments: Converted to a dict before being passed to:func:`dumps`.4. Both args and kwargs: Behavior undefined and will throw an exception.Example usage::from flask import jsonify@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}.. versionchanged:: 0.11Added support for serializing top-level arrays. This introduces asecurity risk in ancient browsers. See :ref:`json-security` for details.This function's response will be pretty printed if the``JSONIFY_PRETTYPRINT_REGULAR`` config parameter is set to True or theFlask app is running in debug mode. Compressed (not pretty) formattingcurrently means no indents and no spaces after separators... versionadded:: 0.2"""indent = Noneseparators = (',', ':')if current_app.config['JSONIFY_PRETTYPRINT_REGULAR'] or current_app.debug:indent = 2separators = (', ', ': ')if args and kwargs:raise TypeError('jsonify() behavior undefined when passed both args and kwargs')elif len(args) == 1: # single args are passed directly to dumps()data = args[0]else:data = args or kwargsreturn current_app.response_class(dumps(data, indent=indent, separators=separators) + '\n',mimetype=current_app.config['JSONIFY_MIMETYPE'])def tojson_filter(obj, **kwargs):return Markup(htmlsafe_dumps(obj, **kwargs))
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。