From 224996f8c5663a333675b9b98bbffb6b1fe3220c Mon Sep 17 00:00:00 2001 From: Tyler Weiss Date: Sun, 29 Sep 2019 16:42:21 -0700 Subject: [PATCH 1/2] Fixed issue with Swagger json bodies --- .gitignore | 3 +++ flask_restplus/swagger.py | 31 ++++++++++++++++++++++++++++++- 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 04ee8bf7..4de80dac 100644 --- a/.gitignore +++ b/.gitignore @@ -62,3 +62,6 @@ doc/_build/ # Specifics flask_restplus/static node_modules + +# PyCharm +.idea* diff --git a/flask_restplus/swagger.py b/flask_restplus/swagger.py index 77c364bf..c1b84c69 100644 --- a/flask_restplus/swagger.py +++ b/flask_restplus/swagger.py @@ -143,6 +143,31 @@ def is_hidden(resource, route_doc=None): return hasattr(resource, "__apidoc__") and resource.__apidoc__ is False +def rparser_to_swagger_body_param(request_parser): + """ + If any parameters are in the request body then return the swagger representation for the requests json body + :param request_parser: The request parser containing params for the request + :return: + """ + json_body_list = [p for p in request_parser.__schema__ if p['in'] == 'body'] + if not json_body_list: + return + + properties = {} + for param in json_body_list: + properties[param['name']] = { + 'type': 'string' if 'type' not in param else param['type'] + } + + return { + 'name': 'payload', + 'required': True, + 'in': 'body', + 'type': 'object', + 'schema': {'properties': properties} + } + + class Swagger(object): ''' A Swagger documentation wrapper for an API instance. @@ -329,8 +354,12 @@ def expected_params(self, doc): for expect in doc.get('expect', []): if isinstance(expect, RequestParser): - parser_params = OrderedDict((p['name'], p) for p in expect.__schema__) + parser_params = OrderedDict((p['name'], p) for p in expect.__schema__ if p['in'] != 'body') params.update(parser_params) + + payload = rparser_to_swagger_body_param(expect) + if payload: + params['payload'] = payload elif isinstance(expect, ModelBase): params['payload'] = not_none({ 'name': 'payload', From 1ad99695e23eca46c3e660aa06258d45d65f1a35 Mon Sep 17 00:00:00 2001 From: Tyler Weiss Date: Sun, 29 Sep 2019 23:24:20 -0700 Subject: [PATCH 2/2] Added tests to address coveralls check --- tests/test_swagger.py | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/tests/test_swagger.py b/tests/test_swagger.py index 9e583f55..05b55abc 100644 --- a/tests/test_swagger.py +++ b/tests/test_swagger.py @@ -623,6 +623,7 @@ def get(self, age): def test_expect_parser(self, api, client): parser = api.parser() parser.add_argument('param', type=int, help='Some param') + parser.add_argument('jsonparam', type=str, location='json', help='Some param') @api.route('/with-parser/', endpoint='with-parser') class WithParserResource(restplus.Resource): @@ -634,14 +635,21 @@ def get(self): assert '/with-parser/' in data['paths'] op = data['paths']['/with-parser/']['get'] - assert len(op['parameters']) == 1 + assert len(op['parameters']) == 2 - parameter = op['parameters'][0] + parameter = [o for o in op['parameters'] if o['in'] == 'query'][0] assert parameter['name'] == 'param' assert parameter['type'] == 'integer' assert parameter['in'] == 'query' assert parameter['description'] == 'Some param' + parameter = [o for o in op['parameters'] if o['in'] == 'body'][0] + assert parameter['name'] == 'payload' + assert parameter['required'] + assert parameter['in'] == 'body' + print(parameter) + assert parameter['schema']['properties']['jsonparam']['type'] == 'string' + def test_expect_parser_on_class(self, api, client): parser = api.parser() parser.add_argument('param', type=int, help='Some param') @@ -3265,6 +3273,23 @@ def post(self, age): assert parameter['in'] == 'query' assert parameter['description'] == 'Overriden description' + def test_rparser_to_swagger_body_param(self): + parser = restplus.reqparse.RequestParser() + parser.add_argument('test', type=int, location='headers') + + assert not restplus.swagger.rparser_to_swagger_body_param(parser) + + parser.add_argument('test1', type=int, location='json') + parser.add_argument('test2', location='json') + + result = restplus.swagger.rparser_to_swagger_body_param(parser) + + assert result['name'] == 'payload' + assert result['required'] + assert result['in'] == 'body' + assert result['schema']['properties']['test1']['type'] == 'integer' + assert result['schema']['properties']['test2']['type'] == 'string' + class SwaggerDeprecatedTest(object): def test_doc_parser_parameters(self, api):