Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle change to Werkzeug 2.1.0 change to Request.get_json(). #423

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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,
}
]