You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Using reqparse.add_argument() with default location parameter to parse requests with Content-Type other than "application/json" raises an exception when using Werkzeug>=2.1.0
#963
Open
dlindquist opened this issue
Jun 9, 2023
· 3 comments
Request.get_json() will raise a 400 BadRequest error if the Content-Type header is not application/json. This makes a very common source of confusion more visible. :issue:2339
Werkzeug 2.3.0 changelog:
Request.get_json() will raise a 415 Unsupported Media Type error if the Content-Type header is not application/json, instead of a generic 400. :issue:2550
Issue
It seems that reqparse.add_argument() with a default location parameter will attempt to load JSON data regardless of the request Content-Type header. This causes Werkzeug to raise a Bad Request or Unsupported Media Type exception if a request is made with a Content-Type header that is not application/json.
$ pytest
======================================================================== test session starts ========================================================================
platform darwin -- Python 3.8.16, pytest-7.3.1, pluggy-1.0.0
collected 3 items
test_json_argument_without_json_content_type.py ..F [100%]
============================================================================= FAILURES ==============================================================================
___________________________________________________________ test_json_argument_without_json_content_type ____________________________________________________________
def test_json_argument_without_json_content_type():
'''
failed
'''
app = Flask(__name__)
parser = reqparse.RequestParser()
parser.add_argument("example_argument")
with app.test_request_context('/', method="post",
data={'example_argument': 'example_value'}):
> args = parser.parse_args()
test_json_argument_without_json_content_type.py:43:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
env/lib/python3.8/site-packages/flask_restful/reqparse.py:328: in parse_args
value, found = arg.parse(req, self.bundle_errors)
env/lib/python3.8/site-packages/flask_restful/reqparse.py:184: in parse
source = self.source(request)
env/lib/python3.8/site-packages/flask_restful/reqparse.py:125: in source
value = getattr(request, l, None)
env/lib/python3.8/site-packages/werkzeug/wrappers/request.py:561: in json
return self.get_json()
env/lib/python3.8/site-packages/werkzeug/wrappers/request.py:607: in get_json
return self.on_json_loading_failed(None)
env/lib/python3.8/site-packages/flask/wrappers.py:130: in on_json_loading_failed
return super().on_json_loading_failed(e)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <Request 'http://localhost/' [POST]>, e = None
def on_json_loading_failed(self, e: ValueError | None) -> t.Any:
"""Called if :meth:`get_json` 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
:exc:`~werkzeug.exceptions.BadRequest`.
:param e: If parsing failed, this is the exception. It will be
``None`` if the content type wasn't ``application/json``.
.. versionchanged:: 2.3
Raise a 415 error instead of 400.
"""
if e is not None:
raise BadRequest(f"Failed to decode JSON object: {e}")
> raise UnsupportedMediaType(
"Did not attempt to load JSON data because the request"
" Content-Type was not 'application/json'."
)
E werkzeug.exceptions.UnsupportedMediaType: 415 Unsupported Media Type: Did not attempt to load JSON data because the request Content-Type was not 'application/json'.
env/lib/python3.8/site-packages/werkzeug/wrappers/request.py:650: UnsupportedMediaType
====================================================================== short test summary info ======================================================================
FAILED test_json_argument_without_json_content_type.py::test_json_argument_without_json_content_type - werkzeug.exceptions.UnsupportedMediaType: 415 Unsupported Media Type: Did not attempt to load JSON data because the request Content-Type was not 'application/js...
==================================================================== 1 failed, 2 passed in 0.10s ====================================================================
The text was updated successfully, but these errors were encountered:
dlindquist
changed the title
Using reqparse.add_argument() with default location parameter to parse requests with Content-Type other than "application/json" raises an exception when Werkzeug>=2.1.0
Using reqparse.add_argument() with default location parameter to parse requests with Content-Type other than "application/json" raises an exception when using Werkzeug>=2.1.0
Jun 9, 2023
This bug is indeed real and quite annoying. A workaround is just to set location as follows:
parser.add_argument('whatever,' type=str, location=('values',))
Facing the same issue, the app seems to be working fine but suddenly everything freezes! @browell's method did fix the issue but it is cumbersome. Any update on when this will be resolved?
ZenithClown
added a commit
to ZenithClown/finfolio
that referenced
this issue
Apr 6, 2024
Background
Werkzeug 2.1.0 changelog:
Werkzeug 2.3.0 changelog:
Issue
It seems that reqparse.add_argument() with a default location parameter will attempt to load JSON data regardless of the request Content-Type header. This causes Werkzeug to raise a Bad Request or Unsupported Media Type exception if a request is made with a Content-Type header that is not application/json.
Ref:
flask-restful/flask_restful/reqparse.py
Line 127 in 88cce53
Reproduction
The text was updated successfully, but these errors were encountered: