diff --git a/connexion/decorators/parameter.py b/connexion/decorators/parameter.py index 21e020294..6515ad2b0 100644 --- a/connexion/decorators/parameter.py +++ b/connexion/decorators/parameter.py @@ -29,7 +29,7 @@ def get_function_arguments(function): # pragma: no cover return inspect.getargspec(function).args -def parameter_to_arg(body_schema, parameters, function): +def parameter_to_arg(parameters, function): """ Pass query and body parameters as keyword arguments to handler function. @@ -37,9 +37,8 @@ def parameter_to_arg(body_schema, parameters, function): :type body_schema: dict|None :type parameters: dict|None """ - body_schema = body_schema or {} # type: dict - body_properties = body_schema.get('properties', {}) - body_types = {name: properties['type'] for name, properties in body_properties.items()} # type: dict[str, str] + body_parameters = [parameter for parameter in parameters if parameter['in'] == 'body'] or [{}] + body_name = body_parameters[0].get('name') query_types = {parameter['name']: parameter['type'] for parameter in parameters if parameter['in'] == 'query'} # type: dict[str, str] arguments = get_function_arguments(function) @@ -49,20 +48,17 @@ def wrapper(*args, **kwargs): logger.debug('Function Arguments: %s', arguments) try: - body_parameters = flask.request.json or {} # type: dict + request_body = flask.request.json except exceptions.BadRequest: - body_parameters = {} + request_body = None # Add body parameters - for key, value in body_parameters.items(): - if key not in arguments: - logger.debug("Body parameter '%s' not in function arguments", key) + if request_body is not None: + if body_name not in arguments: + logger.debug("Body parameter '%s' not in function arguments", body_name) else: - logger.debug("Body parameter '%s' in function arguments", key) - key_type = body_types[key] - logger.debug('%s is a %s', key, key_type) - type_func = TYPE_MAP[key_type] # convert value to right type - kwargs[key] = type_func(value) + logger.debug("Body parameter '%s' in function arguments", body_name) + kwargs[body_name] = request_body # Add query parameters for key, value in flask.request.args.items(): diff --git a/connexion/decorators/validation.py b/connexion/decorators/validation.py index f45d69314..5e674a357 100644 --- a/connexion/decorators/validation.py +++ b/connexion/decorators/validation.py @@ -240,7 +240,6 @@ def validate_path_parameter(self, args, param): def validate_header_parameter(self, param): val = flask.request.headers.get(param['name']) - print(val, param) return self.validate_parameter('header', val, param) def __call__(self, function): diff --git a/connexion/operation.py b/connexion/operation.py index 3f4821b98..745bc0fc6 100644 --- a/connexion/operation.py +++ b/connexion/operation.py @@ -14,7 +14,6 @@ import functools import logging import os - from .decorators.parameter import parameter_to_arg from .decorators.produces import BaseSerializer, Produces, Jsonifier from .decorators.security import security_passthrough, verify_oauth @@ -143,7 +142,15 @@ def function(self): :rtype: types.FunctionType """ - function = parameter_to_arg(self.body_schema, self.parameters, self.__undecorated_function) + parameters = [] + for param in self.parameters: # resolve references + param = param.copy() + schema = param.get('schema') + if schema: + schema = self.resolve_reference(schema) + param['schema'] = schema + parameters.append(param) + function = parameter_to_arg(parameters, self.__undecorated_function) produces_decorator = self.__content_type_decorator logger.debug('... Adding produces decorator (%r)', produces_decorator, extra=vars(self)) diff --git a/tests/fakeapi/api.yaml b/tests/fakeapi/api.yaml index 77daccf82..bc41e6555 100644 --- a/tests/fakeapi/api.yaml +++ b/tests/fakeapi/api.yaml @@ -293,6 +293,36 @@ paths: in: query type: number required: true + /schema_array: + get: + tags: + description: test schema array + operationId: fakeapi.hello.test_schema_array + parameters: + - name: test_array + in: body + required: true + schema: + type: array + items: + type: string + responses: + 200: + description: OK + /schema_int: + get: + tags: + description: test schema int + operationId: fakeapi.hello.test_schema_int + parameters: + - name: test_int + in: body + required: true + schema: + type: integer + responses: + 200: + description: OK definitions: new_stack: type: object diff --git a/tests/fakeapi/hello.py b/tests/fakeapi/hello.py index c7cc47808..6c2f7b8c7 100755 --- a/tests/fakeapi/hello.py +++ b/tests/fakeapi/hello.py @@ -56,8 +56,8 @@ def empty(): return None, 204 -def schema(image_version): - return {'image_version': image_version} +def schema(new_stack): + return new_stack def schema_query(image_version=None): @@ -78,3 +78,11 @@ def test_parameter_validation(): def test_required_query_param(): return '' + + +def test_schema_array(test_array): + return test_array + + +def test_schema_int(test_int): + return test_int diff --git a/tests/test_app.py b/tests/test_app.py index 7cfd703ef..ec467079d 100644 --- a/tests/test_app.py +++ b/tests/test_app.py @@ -5,7 +5,6 @@ import requests import logging import _pytest.monkeypatch - from connexion.app import App logging.basicConfig(level=logging.DEBUG) @@ -385,3 +384,27 @@ def test_required_query_param(app): response = app_client.get(url, query_string={'n': '1.23'}) assert response.status_code == 200 + + +def test_test_schema_array(app): + app_client = app.app.test_client() + headers = {'Content-type': 'application/json'} + + array_request = app_client.get('/v1.0/schema_array', headers=headers, + data=json.dumps(['list', 'hello'])) # type: flask.Response + assert array_request.status_code == 200 + assert array_request.content_type == 'application/json' + array_response = json.loads(array_request.data.decode()) # type: list + assert array_response == ['list', 'hello'] + + +def test_test_schema_int(app): + app_client = app.app.test_client() + headers = {'Content-type': 'application/json'} + + array_request = app_client.get('/v1.0/schema_int', headers=headers, + data=json.dumps(42)) # type: flask.Response + assert array_request.status_code == 200 + assert array_request.content_type == 'application/json' + array_response = json.loads(array_request.data.decode()) # type: list + assert array_response == 42 diff --git a/tests/test_operation.py b/tests/test_operation.py index f046dce12..915322831 100644 --- a/tests/test_operation.py +++ b/tests/test_operation.py @@ -1,7 +1,6 @@ import pathlib import pytest import types - from connexion.exceptions import InvalidSpecification from connexion.operation import Operation from connexion.decorators.security import security_passthrough, verify_oauth