diff --git a/CHANGELOG.rst b/CHANGELOG.rst index a314e62d..e33144c8 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -25,6 +25,17 @@ Releases prior to 0.3.0 were “best effort” filled out, but are missing some info. If you see your contribution missing info, please open a PR on the Changelog! +.. _section-1.2.0: +1.2.0 +----- +.. _bug_fixes-1.2.0 +Bug Fixes +~~~~~~~~~ + +:: + + * Fixing issue #177 to allow file list uploads, whilst other arugments are present. + .. _section-1.1.0: 1.1.0 ----- diff --git a/flask_restx/swagger.py b/flask_restx/swagger.py index ec0a1975..9f2fff72 100644 --- a/flask_restx/swagger.py +++ b/flask_restx/swagger.py @@ -504,6 +504,9 @@ def serialize_operation(self, doc, method): if all_params and any(p["in"] == "formData" for p in all_params): if any(p["type"] == "file" for p in all_params): operation["consumes"] = ["multipart/form-data"] + elif any(p["type"] == "array" and p["collectionFormat"] == "multi" for p in all_params + if "collectionFormat" in p): + operation["consumes"] = ["multipart/form-data"] else: operation["consumes"] = [ "application/x-www-form-urlencoded", diff --git a/tests/test_swagger.py b/tests/test_swagger.py index 8f181505..b15f82d1 100644 --- a/tests/test_swagger.py +++ b/tests/test_swagger.py @@ -791,6 +791,49 @@ def get(self): assert "consumes" in op assert op["consumes"] == ["multipart/form-data"] + def test_parser_parameter_in_files_append_only(self, api, client): + parser = api.parser() + parser.add_argument( + "in_files", type=FileStorage, location="files", action="append" + ) + + @api.route("/with-parser/", endpoint="with-parser") + class WithParserResource(restx.Resource): + @api.expect(parser) + def post(self): + return {} + + data = client.get_specs() + assert "/with-parser/" in data["paths"] + + path = data["paths"]["/with-parser/"] + op = path["post"] + assert op["consumes"][0] == "multipart/form-data" + + def test_parser_parameter_in_files_append_multiple_parameters(self, api, client): + parser = api.parser() + parser.add_argument( + "in_files", type=FileStorage, location="files", action="append" + ) + # Ensure that we have a second argument not of type file, and therefore will not have the collectionFormat + # attribute + parser.add_argument( + "arbitrary_arguments", type=str, location="form" + ) + + @api.route("/with-parser/", endpoint="with-parser") + class WithParserResource(restx.Resource): + @api.expect(parser) + def post(self): + return {} + + data = client.get_specs() + assert "/with-parser/" in data["paths"] + + path = data["paths"]["/with-parser/"] + op = path["post"] + assert op["consumes"][0] == "multipart/form-data" + def test_explicit_parameters(self, api, client): @api.route("/name//", endpoint="by-name") class ByNameResource(restx.Resource):