Use Werkzeug's JSONMixin class and update tests

Flask's JSONMixin class was moved to Werkzeug>=0.15

Co-authored-by: Jeffrey Eliasen <jeff@jke.net>
This commit is contained in:
EtiennePelletier 2019-05-06 14:59:43 -04:00 committed by David Lord
parent d0bfb065e5
commit 8590d65a57
No known key found for this signature in database
GPG key ID: 7A1C87E3F5BC42A8
5 changed files with 18 additions and 131 deletions

View file

@ -11,99 +11,17 @@
from werkzeug.exceptions import BadRequest
from werkzeug.wrappers import Request as RequestBase, Response as ResponseBase
from werkzeug.wrappers.json import JSONMixin as _JSONMixin
from flask import json
from flask.globals import current_app
class JSONMixin(object):
"""Common mixin for both request and response objects to provide JSON
parsing capabilities.
.. versionadded:: 1.0
"""
_cached_json = (Ellipsis, Ellipsis)
@property
def is_json(self):
"""Check if the mimetype indicates JSON data, either
:mimetype:`application/json` or :mimetype:`application/*+json`.
.. versionadded:: 0.11
"""
mt = self.mimetype
return (
mt == "application/json"
or (mt.startswith("application/"))
and mt.endswith("+json")
)
@property
def json(self):
"""This will contain the parsed JSON data if the mimetype indicates
JSON (:mimetype:`application/json`, see :meth:`is_json`), otherwise it
will be ``None``.
"""
return self.get_json()
def _get_data_for_json(self, cache):
return self.get_data(cache=cache)
def get_json(self, force=False, silent=False, cache=True):
"""Parse and return the data as JSON. If the mimetype does not
indicate JSON (:mimetype:`application/json`, see
:meth:`is_json`), this returns ``None`` unless ``force`` is
true. If parsing fails, :meth:`on_json_loading_failed` is called
and its return value is used as the return value.
:param force: Ignore the mimetype and always try to parse JSON.
:param silent: Silence parsing errors and return ``None``
instead.
:param cache: Store the parsed JSON to return for subsequent
calls.
"""
if cache and self._cached_json[silent] is not Ellipsis:
return self._cached_json[silent]
if not (force or self.is_json):
return None
data = self._get_data_for_json(cache=cache)
try:
rv = json.loads(data)
except ValueError as e:
if silent:
rv = None
if cache:
normal_rv, _ = self._cached_json
self._cached_json = (normal_rv, rv)
else:
rv = self.on_json_loading_failed(e)
if cache:
_, silent_rv = self._cached_json
self._cached_json = (rv, silent_rv)
else:
if cache:
self._cached_json = (rv, rv)
return rv
class JSONMixin(_JSONMixin):
json_module = json
def on_json_loading_failed(self, e):
"""Called if :meth:`get_json` parsing fails and isn't silenced. If
this method returns a value, it is used as the return value for
:meth:`get_json`. The default implementation raises a
:class:`BadRequest` exception.
.. versionchanged:: 0.10
Raise a :exc:`BadRequest` error instead of returning an error
message as JSON. If you want that behavior you can add it by
subclassing.
.. versionadded:: 0.8
"""
if current_app is not None and current_app.debug:
if current_app and current_app.debug:
raise BadRequest("Failed to decode JSON object: {0}".format(e))
raise BadRequest()