Skip to content

Commit

Permalink
Merge pull request #423 from stacywsmith/bugfix/handle_werkzeug_reque…
Browse files Browse the repository at this point in the history
…st_get_json_change

Handle change to Werkzeug 2.1.0 change to Request.get_json().
  • Loading branch information
ziirish committed Sep 13, 2022
2 parents 88497ce + 57c5beb commit 4e7c306
Show file tree
Hide file tree
Showing 2 changed files with 94 additions and 23 deletions.
15 changes: 12 additions & 3 deletions flask_restx/reqparse.py
Expand Up @@ -106,7 +106,10 @@ def __init__(
required=False,
ignore=False,
type=text_type,
location=("json", "values",),
location=(
"json",
"values",
),
choices=(),
action="store",
help=None,
Expand Down Expand Up @@ -138,15 +141,21 @@ def source(self, request):
:param request: The flask request object to parse arguments from
"""
if isinstance(self.location, six.string_types):
value = getattr(request, self.location, MultiDict())
if self.location in {"json", "get_json"}:
value = request.get_json(silent=True)
else:
value = getattr(request, self.location, MultiDict())
if callable(value):
value = value()
if value is not None:
return value
else:
values = MultiDict()
for l in self.location:
value = getattr(request, l, None)
if l in {"json", "get_json"}:
value = request.get_json(silent=True)
else:
value = getattr(request, l, None)
if callable(value):
value = value()
if value is not None:
Expand Down
102 changes: 82 additions & 20 deletions tests/test_reqparse.py
Expand Up @@ -41,8 +41,9 @@ def test_help(self, app, mocker):
)
parser = RequestParser()
parser.add_argument("foo", choices=("one", "two"), help="Bad choice.")
req = mocker.Mock(["values"])
req = mocker.Mock(["values", "get_json"])
req.values = MultiDict([("foo", "three")])
req.get_json.return_value = None
with pytest.raises(BadRequest):
parser.parse_args(req)
expected = {
Expand All @@ -58,7 +59,8 @@ def test_no_help(self, app, mocker):
)
parser = RequestParser()
parser.add_argument("foo", choices=["one", "two"])
req = mocker.Mock(["values"])
req = mocker.Mock(["values", "get_json"])
req.get_json.return_value = None
req.values = MultiDict([("foo", "three")])
with pytest.raises(BadRequest):
parser.parse_args(req)
Expand All @@ -76,9 +78,9 @@ def test_viewargs(self, mocker):
args = parser.parse_args(req)
assert args["foo"] == "bar"

req = mocker.Mock()
req = mocker.Mock(["get_json"])
req.values = ()
req.json = None
req.get_json.return_value = None
req.view_args = {"foo": "bar"}
parser = RequestParser()
parser.add_argument("foo", store_missing=True)
Expand All @@ -101,11 +103,12 @@ def test_parse_unicode_app(self, app):
args = parser.parse_args()
assert args["foo"] == "barß"

@pytest.mark.request_context("/bubble", method="post")
@pytest.mark.request_context(
"/bubble", method="post", content_type="application/json"
)
def test_json_location(self):
parser = RequestParser()
parser.add_argument("foo", location="json", store_missing=True)

args = parser.parse_args()
assert args["foo"] is None

Expand Down Expand Up @@ -856,7 +859,8 @@ def test_source_bad_location(self, mocker):
assert len(arg.source(req)) == 0 # yes, basically you don't find it

def test_source_default_location(self, mocker):
req = mocker.Mock(["values"])
req = mocker.Mock(["values", "get_json"])
req.get_json.return_value = None
req._get_child_mock = lambda **kwargs: MultiDict()
arg = Argument("foo")
assert arg.source(req) == req.values
Expand Down Expand Up @@ -910,28 +914,47 @@ def test_unknown_type(self):
parser = RequestParser()
parser.add_argument("unknown", type=lambda v: v)
assert parser.__schema__ == [
{"name": "unknown", "type": "string", "in": "query",}
{
"name": "unknown",
"type": "string",
"in": "query",
}
]

def test_required(self):
parser = RequestParser()
parser.add_argument("int", type=int, required=True)
assert parser.__schema__ == [
{"name": "int", "type": "integer", "in": "query", "required": True,}
{
"name": "int",
"type": "integer",
"in": "query",
"required": True,
}
]

def test_default(self):
parser = RequestParser()
parser.add_argument("int", type=int, default=5)
assert parser.__schema__ == [
{"name": "int", "type": "integer", "in": "query", "default": 5,}
{
"name": "int",
"type": "integer",
"in": "query",
"default": 5,
}
]

def test_default_as_false(self):
parser = RequestParser()
parser.add_argument("bool", type=inputs.boolean, default=False)
assert parser.__schema__ == [
{"name": "bool", "type": "boolean", "in": "query", "default": False,}
{
"name": "bool",
"type": "boolean",
"in": "query",
"default": False,
}
]

def test_choices(self):
Expand All @@ -954,31 +977,59 @@ def test_location(self):
parser.add_argument("in_headers", type=int, location="headers")
parser.add_argument("in_cookie", type=int, location="cookie")
assert parser.__schema__ == [
{"name": "default", "type": "integer", "in": "query",},
{"name": "in_values", "type": "integer", "in": "query",},
{"name": "in_query", "type": "integer", "in": "query",},
{"name": "in_headers", "type": "integer", "in": "header",},
{
"name": "default",
"type": "integer",
"in": "query",
},
{
"name": "in_values",
"type": "integer",
"in": "query",
},
{
"name": "in_query",
"type": "integer",
"in": "query",
},
{
"name": "in_headers",
"type": "integer",
"in": "header",
},
]

def test_location_json(self):
parser = RequestParser()
parser.add_argument("in_json", type=str, location="json")
assert parser.__schema__ == [
{"name": "in_json", "type": "string", "in": "body",}
{
"name": "in_json",
"type": "string",
"in": "body",
}
]

def test_location_form(self):
parser = RequestParser()
parser.add_argument("in_form", type=int, location="form")
assert parser.__schema__ == [
{"name": "in_form", "type": "integer", "in": "formData",}
{
"name": "in_form",
"type": "integer",
"in": "formData",
}
]

def test_location_files(self):
parser = RequestParser()
parser.add_argument("in_files", type=FileStorage, location="files")
assert parser.__schema__ == [
{"name": "in_files", "type": "file", "in": "formData",}
{
"name": "in_files",
"type": "file",
"in": "formData",
}
]

def test_form_and_body_location(self):
Expand Down Expand Up @@ -1008,7 +1059,13 @@ def test_models(self):
)
parser = RequestParser()
parser.add_argument("todo", type=todo_fields)
assert parser.__schema__ == [{"name": "todo", "type": "Todo", "in": "body",}]
assert parser.__schema__ == [
{
"name": "todo",
"type": "Todo",
"in": "body",
}
]

def test_lists(self):
parser = RequestParser()
Expand Down Expand Up @@ -1061,5 +1118,10 @@ def test_callable_default(self):
parser = RequestParser()
parser.add_argument("int", type=int, default=lambda: 5)
assert parser.__schema__ == [
{"name": "int", "type": "integer", "in": "query", "default": 5,}
{
"name": "int",
"type": "integer",
"in": "query",
"default": 5,
}
]

0 comments on commit 4e7c306

Please sign in to comment.