Skip to content

Commit

Permalink
fix flask ImmutableMultiDict and EnvironHeaders parser (#205)
Browse files Browse the repository at this point in the history
* fix parse json error

* fix flask multidict and headers

* release 0.7.5
  • Loading branch information
kemingy authored Feb 21, 2022
1 parent 3c191c5 commit 6025aea
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 12 deletions.
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

setup(
name="spectree",
version="0.7.4",
version="0.7.5",
license="Apache-2.0",
author="Keming Yang",
author_email="[email protected]",
Expand Down
31 changes: 20 additions & 11 deletions spectree/plugins/flask_plugin.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from pydantic import ValidationError

from ..utils import get_multidict_items
from .base import BasePlugin, Context


Expand Down Expand Up @@ -128,22 +129,30 @@ def parse_path(self, route, path_parameter_descriptions):
return "".join(subs), parameters

def request_validation(self, request, query, json, headers, cookies):
req_query = request.args or {}
"""
req_query: werkzeug.datastructures.ImmutableMultiDict
req_json: dict
req_headers: werkzeug.datastructures.EnvironHeaders
req_cookies: werkzeug.datastructures.ImmutableMultiDict
"""
req_query = get_multidict_items(request.args) or {}
if request.mimetype in self.FORM_MIMETYPE:
req_json = request.form or {}
req_json = get_multidict_items(request.form) or {}
if request.files:
req_json = dict(
list(request.form.items()) + list(request.files.items())
)
req_json = {
**req_json,
**get_multidict_items(request.files),
}
else:
req_json = request.get_json(silent=True) or {}
req_headers = request.headers or {}
req_cookies = request.cookies or {}
req_headers = dict(iter(request.headers)) or {}
req_cookies = get_multidict_items(request.cookies) or {}

request.context = Context(
query.parse_obj(req_query.items()) if query else None,
json.parse_obj(req_json.items()) if json else None,
headers.parse_obj(req_headers.items()) if headers else None,
cookies.parse_obj(req_cookies.items()) if cookies else None,
query.parse_obj(req_query) if query else None,
json.parse_obj(req_json) if json else None,
headers.parse_obj(req_headers) if headers else None,
cookies.parse_obj(req_cookies) if cookies else None,
)

def validate(
Expand Down
14 changes: 14 additions & 0 deletions spectree/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -245,3 +245,17 @@ def get_security(security):
security = [security]

return security


def get_multidict_items(multidict):
"""
return the items of a :class:`werkzeug.datastructures.ImmutableMultiDict`
"""
res = {}
for key in multidict:
if len(multidict.getlist(key)) > 1:
res[key] = multidict.getlist(key)
else:
res[key] = multidict.get(key)

return res
2 changes: 2 additions & 0 deletions tests/test_plugin_flask.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,13 +144,15 @@ def test_flask_validate(client):
data=json.dumps(dict(name="flask", limit=10)),
content_type="application/json",
)
assert resp.status_code == 200, resp.json
assert resp.json["score"] == sorted(resp.json["score"], reverse=False)

resp = client.post(
f"/api/{fragment}/flask?order=0",
data="name=flask&limit=10",
content_type="application/x-www-form-urlencoded",
)
assert resp.status_code == 200, resp.json
assert resp.json["score"] == sorted(resp.json["score"], reverse=False)


Expand Down

0 comments on commit 6025aea

Please sign in to comment.