def swagger_validated_function(*args, **kwargs):
     converted_uri = request.path
     # convert /pet/mypetsid to /pet/{petId}
     for key, value in request.view_args.items():
         target = '{{{0}}}'.format(key)
         converted_uri = converted_uri.replace(str(value), target)
     # Grab the swagger spec for this specific uri and request type
     request_spec = spec.get_op_for_request(
         request.method.lower(), converted_uri)
     # cycle through the params and check any params that are set or required
     # by the schema
     for param in request_spec.params.values():
         param_spec = get_param_type_spec(param)
         # TODO - grab out other request types that we care about
         param_value = None
         if param.location == 'formData':
             param_value = request.form.get(param.name)
         elif param.location == 'path':
             param_value = request.view_args.get(param.name)
         if param_value or param.required:
             try:
                 validate_schema_object(spec, param_spec, param_value)
             except Exception as e:
                 abort(400, str(e))
     return f(*args, **kwargs)
Пример #2
0
def unmarshal_response(response, op):
    """Unmarshal incoming http response into a value based on the
    response specification.

    :type response: :class:`bravado_core.response.IncomingResponse`
    :type op: :class:`bravado_core.operation.Operation`
    :returns: value where type(value) matches response_spec['schema']['type']
        if it exists, None otherwise.
    """
    response_spec = get_response_spec(response.status_code, op)

    def has_content(response_spec):
        return 'schema' in response_spec

    if not has_content(response_spec):
        return None

    # TODO: Non-json response contents
    content_spec = response_spec['schema']
    content_value = response.json()

    if op.swagger_spec.config['validate_responses']:
        validate_schema_object(op.swagger_spec, content_spec, content_value)

    return unmarshal_schema_object(op.swagger_spec, content_spec,
                                   content_value)
Пример #3
0
def unmarshal_response(response, op):
    """Unmarshal incoming http response into a value based on the
    response specification.

    :type response: :class:`bravado_core.response.IncomingResponse`
    :type op: :class:`bravado_core.operation.Operation`
    :returns: value where type(value) matches response_spec['schema']['type']
        if it exists, None otherwise.
    """
    deref = op.swagger_spec.deref
    response_spec = get_response_spec(response.status_code, op)

    if 'schema' not in response_spec:
        # If response spec does not define schema
        return None

    content_type = response.headers.get('content-type', '').lower()

    if content_type.startswith(APP_JSON) or content_type.startswith(
            APP_MSGPACK):
        content_spec = deref(response_spec['schema'])
        if content_type.startswith(APP_JSON):
            content_value = response.json()
        else:
            content_value = msgpack.loads(response.raw_bytes, raw=False)
        if op.swagger_spec.config['validate_responses']:
            validate_schema_object(op.swagger_spec, content_spec,
                                   content_value)

        return unmarshal_schema_object(op.swagger_spec, content_spec,
                                       content_value)

    # TODO: Non-json response contents
    return response.text
Пример #4
0
def validate_response_body(op, response_spec, response):
    """Validate an outgoing response's body against the response's Swagger
    specification.

    :type op: :class:`bravado_core.operation.Operation`
    :type response_spec: dict
    :type response: :class:`bravado_core.response.OutgoingResponse`

    :raises: SwaggerMappingError
    """
    deref = op.swagger_spec.deref

    # response that returns nothing in the body
    response_body_spec = deref(response_spec.get("schema"))
    if response_body_spec is None:
        if response.text in EMPTY_BODIES:
            return
        raise SwaggerMappingError("Response body should be empty: {0}".format(response.text))

    if response.content_type not in op.produces:
        raise SwaggerMappingError(
            "Response content-type '{0}' is not supported by the Swagger "
            "specification's content-types '{1}".format(response.content_type, op.produces)
        )

    if response.content_type == APP_JSON:
        response_value = response.json()
        validate_schema_object(op.swagger_spec, response_body_spec, response_value)
    else:
        # TODO: Expand content-type support for non-json types
        raise SwaggerMappingError("Unsupported content-type in response: {0}".format(response.content_type))
Пример #5
0
def unmarshal_response(response, op):
    """Unmarshal incoming http response into a value based on the
    response specification.

    :type response: :class:`bravado_core.response.IncomingResponse`
    :type op: :class:`bravado_core.operation.Operation`
    :returns: value where type(value) matches response_spec['schema']['type']
        if it exists, None otherwise.
    """
    deref = op.swagger_spec.deref
    response_spec = get_response_spec(response.status_code, op)

    def has_content(response_spec):
        return "schema" in response_spec

    if not has_content(response_spec):
        return None

    # TODO: Non-json response contents
    content_spec = deref(response_spec["schema"])
    content_value = response.json()

    if op.swagger_spec.config["validate_responses"]:
        validate_schema_object(op.swagger_spec, content_spec, content_value)

    return unmarshal_schema_object(op.swagger_spec, content_spec, content_value)
Пример #6
0
def unmarshal_response_inner(response, op):
    """
    Unmarshal incoming http response into a value based on the
    response specification.
    :type response: :class:`bravado_core.response.IncomingResponse`
    :type op: :class:`bravado_core.operation.Operation`
    :returns: value where type(value) matches response_spec['schema']['type']
        if it exists, None otherwise.
    """
    deref = op.swagger_spec.deref
    response_spec = get_response_spec(status_code=response.status_code, op=op)

    if 'schema' not in response_spec:
        return None

    content_type = response.headers.get('content-type', '').lower()

    if content_type.startswith(APP_JSON) or content_type.startswith(APP_MSGPACK):
        content_spec = deref(response_spec['schema'])
        if content_type.startswith(APP_JSON):
            content_value = response.json()
        else:
            content_value = unpackb(response.raw_bytes, encoding='utf-8')

        if op.swagger_spec.config.get('validate_responses', False):
            validate_schema_object(op.swagger_spec, content_spec, content_value)

        return unmarshal_schema_object(
            swagger_spec=op.swagger_spec,
            schema_object_spec=content_spec,
            value=content_value,
        )

    # TODO: Non-json response contents
    return response.text
Пример #7
0
def unmarshal_param(param, request):
    """Unmarshal the given parameter from the passed in request like object.

    :type param: :class:`bravado_core.param.Param`
    :type request: :class:`bravado_core.request.IncomingRequest`
    :return: value of parameter
    """
    swagger_spec = param.swagger_spec
    deref = swagger_spec.deref
    param_spec = deref(get_param_type_spec(param))
    location = param.location
    param_type = deref(param_spec.get('type'))
    cast_param = partial(cast_request_param, param_type, param.name)

    default_value = schema.get_default(swagger_spec, param_spec)

    if location == 'path':
        raw_value = cast_param(request.path.get(param.name, None))
    elif location == 'query':
        raw_value = cast_param(request.query.get(param.name, default_value))
    elif location == 'header':
        raw_value = cast_param(request.headers.get(param.name, default_value))
    elif location == 'formData':
        if param_type == 'file':
            raw_value = request.files.get(param.name, None)
        else:
            raw_value = cast_param(request.form.get(param.name, default_value))
    elif location == 'body':
        try:
            # TODO: verify content-type header
            raw_value = request.json()
        except ValueError as json_error:
            # If the body parameter is required then we should make sure that an exception
            # is thrown, instead if the body parameter is optional is OK-ish to assume that
            # raw_value is the default_value
            if param.required:
                raise SwaggerMappingError(
                    "Error reading request body JSON: {0}".format(str(json_error)),
                )
            else:
                raw_value = default_value
    else:
        raise SwaggerMappingError(
            "Don't know how to unmarshal_param with location {0}".format(location),
        )

    if raw_value is None and not param.required:
        return None

    if param_type == 'array' and location != 'body':
        raw_value = unmarshal_collection_format(
            swagger_spec, param_spec,
            raw_value,
        )

    if swagger_spec.config['validate_requests']:
        validate_schema_object(swagger_spec, param_spec, raw_value)

    value = unmarshal_schema_object(swagger_spec, param_spec, raw_value)
    return value
Пример #8
0
def validate_response_headers(op, response_spec, response):
    """Validate an outgoing response's headers against the response's Swagger
    specification.

    :type op: :class:`bravado_core.operation.Operation`
    :type response_spec: dict
    :type response: :class:`bravado_core.response.OutgoingResponse`
    """
    deref = op.swagger_spec.deref

    headers_spec = deref(response_spec.get('headers'))
    if not headers_spec:
        return

    for header_name, header_spec in iteritems(headers_spec):
        header_spec = deref(header_spec)
        try:
            validate_schema_object(
                op.swagger_spec,
                header_spec,
                response.headers.get(header_name),
            )
        except ValidationError as e:
            e.message = "{0} for header '{1}'".format(e.message, header_name)
            raise e
Пример #9
0
def validate_response_body(op, response_spec, response):
    """
    Validate an outgoing response's body against the response's Swagger
    specification.

    :type op: :class:`bravado_core.operation.Operation`
    :type response_spec: dict
    :type response: :class:`bravado_core.response.OutgoingResponse`
    :raises: SwaggerMappingError
    """
    # response that returns nothing in the body
    response_body_spec = response_spec.get('schema')
    if response_body_spec is None:
        if response.text in EMPTY_BODIES:
            return
        raise SwaggerMappingError("Response body should be empty: {0}".format(
            response.text))

    if response.content_type not in op.produces:
        raise SwaggerMappingError(
            "Response content-type '{0}' is not supported by the Swagger "
            "specification's content-types '{1}".format(
                response.content_type, op.produces))

    if response.content_type == APP_JSON:
        response_value = response.json()
        validate_schema_object(op.swagger_spec, response_body_spec,
                               response_value)
    else:
        # TODO: Expand content-type support for non-json types
        raise SwaggerMappingError(
            "Unsupported content-type in response: {0}".format(
                response.content_type))
def test_unmarshal_with_object_default(empty_swagger_spec, nullable, required):
    """With a value set, validation should always pass: (2), (5), (8), (11)"""
    content_spec = content_spec_factory(required, nullable)
    value = {'x': 'y'}

    validate_schema_object(empty_swagger_spec, content_spec, value)
    result = unmarshal_schema_object(empty_swagger_spec, content_spec, value)
    assert result == value
Пример #11
0
def test_allOf_with_ref(composition_spec):
    pongclone_spec = composition_spec.spec_dict['definitions']['pongClone']
    value = {
        'additionalFeature': 'Badges',
        'gameSystem': 'NES',
        'pang': 'value',
        'releaseDate': 'October',
    }
    validate_schema_object(composition_spec, pongclone_spec, value)
def test_allOf_with_ref(composition_spec):
    pongclone_spec = composition_spec.spec_dict['definitions']['pongClone']
    value = {
        'additionalFeature': 'Badges',
        'gameSystem': 'NES',
        'pang': 'value',
        'releaseDate': 'October',
    }
    validate_schema_object(composition_spec, pongclone_spec, value)
def test_unmarshal_with_primitive_pass(empty_swagger_spec, value, nullable):
    """Test scenarios in which validation should pass: (1), (3), (4)"""
    content_spec = {
        'type': 'string',
        'x-nullable': nullable,
    }
    validate_schema_object(empty_swagger_spec, content_spec, value)
    result = unmarshal_schema_object(empty_swagger_spec, content_spec, value)
    assert result == value
Пример #14
0
def marshal_param(param, value, request):
    """Given an operation's parameter and its value, marshal the value and
    place it in the proper request destination.

    Destination is one of:
        - path - can accept primitive and array of primitive types
        - query - can accept primitive and array of primitive types
        - header - can accept primitive and array of primitive types
        - body - can accept any type
        - formData - can accept primitive and array of primitive types

    :type param: :class:`bravado_core.param.Param`
    :param value: The value to assign to the parameter
    :type request: dict
    """
    swagger_spec = param.swagger_spec
    deref = swagger_spec.deref

    param_spec = deref(get_param_type_spec(param))
    location = param.location

    # Rely on unmarshalling behavior on the other side of the pipe to use
    # the default value if one is available.
    if value is None and not param.required:
        return

    value = marshal_schema_object(swagger_spec, param_spec, value)

    if swagger_spec.config['validate_requests']:
        validate_schema_object(swagger_spec, param_spec, value)

    param_type = param_spec.get('type')
    if param_type == 'array' and location != 'body':
        value = marshal_collection_format(swagger_spec, param_spec, value)

    encode_param = partial(encode_request_param, param_type, param.name)
    if location == 'path':
        token = u'{%s}' % param.name
        quoted_value = quote(six.text_type(value).encode('utf8'), safe=',')
        request['url'] = request['url'].replace(token, quoted_value)
    elif location == 'query':
        request['params'][param.name] = encode_param(value)
    elif location == 'header':
        request['headers'][param.name] = encode_param(value)
    elif location == 'formData':
        if param_type == 'file':
            add_file(param, value, request)
        else:
            request.setdefault('data', {})[param.name] = value
    elif location == 'body':
        request['headers']['Content-Type'] = APP_JSON
        request['data'] = json.dumps(value)
    else:
        raise SwaggerMappingError(
            "Don't know how to marshal_param with location {0}".
            format(location))
def test_unmarshal_with_object_no_req_no_value(empty_swagger_spec, nullable):
    """When the value is not required and not set at all, validation
    should pass: (1), (7)
    """
    content_spec = content_spec_factory(False, nullable=nullable)
    value = {}

    validate_schema_object(empty_swagger_spec, content_spec, value)
    result = unmarshal_schema_object(empty_swagger_spec, content_spec, value)
    assert result == {'x': None}  # Missing parameters are re-introduced
def test_unmarshal_with_object_null_value_none(empty_swagger_spec, required):
    """When nullable is `True` and the value is set to `None`, validation
    should pass: (9), (12)
    """
    content_spec = content_spec_factory(required, True)
    value = {'x': None}

    validate_schema_object(empty_swagger_spec, content_spec, value)
    result = unmarshal_schema_object(empty_swagger_spec, content_spec, value)
    assert result == {'x': None}
Пример #17
0
def marshal_param(param, value, request):
    """Given an operation's parameter and its value, marshal the value and
    place it in the proper request destination.

    Destination is one of:
        - path - can accept primitive and array of primitive types
        - query - can accept primitive and array of primitive types
        - header - can accept primitive and array of primitive types
        - body - can accept any type
        - formData - can accept primitive and array of primitive types

    :type param: :class:`bravado_core.param.Param`
    :param value: The value to assign to the parameter
    :type request: dict
    """
    swagger_spec = param.swagger_spec
    deref = swagger_spec.deref

    param_spec = deref(get_param_type_spec(param))
    location = param.location

    # Rely on unmarshalling behavior on the other side of the pipe to use
    # the default value if one is availabe.
    if value is None and not schema.is_required(swagger_spec, param_spec):
        return

    value = marshal_schema_object(swagger_spec, param_spec, value)

    if swagger_spec.config['validate_requests']:
        validate_schema_object(swagger_spec, param_spec, value)

    param_type = param_spec.get('type')
    if param_type == 'array' and location != 'body':
        value = marshal_collection_format(swagger_spec, param_spec, value)

    if location == 'path':
        token = u'{%s}' % param.name
        # Don't do any escaping/encoding - http_client will take care of it
        request['url'] = request['url'].replace(token, six.text_type(value))
    elif location == 'query':
        request['params'][param.name] = value
    elif location == 'header':
        request['headers'][param.name] = value
    elif location == 'formData':
        if param_type == 'file':
            add_file(param, value, request)
        else:
            request.setdefault('data', {})[param.name] = value
    elif location == 'body':
        request['headers']['Content-Type'] = APP_JSON
        request['data'] = json.dumps(value)
    else:
        raise SwaggerMappingError(
            "Don't know how to marshal_param with location {0}".
            format(location))
def test_unmarshal_with_object_req_no_value(empty_swagger_spec, nullable):
    """When the value is required but not set at all, validation
    should fail: (4), (10)
    """
    content_spec = content_spec_factory(True, nullable)
    value = {}

    with pytest.raises(ValidationError) as excinfo:
        validate_schema_object(empty_swagger_spec, content_spec, value)
        unmarshal_schema_object(empty_swagger_spec, content_spec, value)
    assert excinfo.value.message == "'x' is a required property"
def test_unmarshal_with_object_no_null_value_none(empty_swagger_spec, required):
    """When nullable is `False` and the value is set to `None`, validation
    should fail: (3), (6)
    """
    content_spec = content_spec_factory(required, False)
    value = {'x': None}

    with pytest.raises(ValidationError) as excinfo:
        validate_schema_object(empty_swagger_spec, content_spec, value)
        unmarshal_schema_object(empty_swagger_spec, content_spec, value)
    assert excinfo.value.message == "None is not of type 'string'"
def test_unmarshal_with_primitive_fail(empty_swagger_spec):
    """Test scenarios in which validation should fail: (2)"""
    content_spec = {
        'type': 'string',
        'x-nullable': False,
    }
    value = None
    with pytest.raises(ValidationError) as excinfo:
        validate_schema_object(empty_swagger_spec, content_spec, value)
        unmarshal_schema_object(empty_swagger_spec, content_spec, value)
    assert excinfo.value.message == "None is not of type 'string'"
Пример #21
0
def unmarshal_response_inner(
    response,  # type: IncomingResponse
    op,  # type: Operation
):
    # type: (...) -> typing.Optional[T]
    """
    Unmarshal incoming http response into a value based on the
    response specification.
    :type response: :class:`bravado_core.response.IncomingResponse`
    :type op: :class:`bravado_core.operation.Operation`
    :returns: value where type(value) matches response_spec['schema']['type']
        if it exists, None otherwise.
    """

    content_type = response.headers.get('content-type', '').lower()
    if content_type.startswith(APP_JSON) or content_type.startswith(APP_MSGPACK):
        use_models = op.swagger_spec.config.get('use_models', True)
        if content_type.startswith(APP_JSON):
            content_value = response.json()
        else:
            content_value = unpackb(response.raw_bytes)

        try:
            response_spec = get_response_spec(
                status_code=response.status_code, op=op)
        except MatchingResponseNotFound:
            if not use_models:
                return content_value

            six.reraise(*sys.exc_info())

        if 'schema' not in response_spec:
            if not use_models:
                return content_value

            return None

        content_spec = op.swagger_spec.deref(response_spec['schema'])
        if op.swagger_spec.config.get('validate_responses', False):
            validate_schema_object(op.swagger_spec, content_spec, content_value)

        return unmarshal_schema_object(
            swagger_spec=op.swagger_spec,
            schema_object_spec=content_spec,
            value=content_value,
        )

    if content_type.startswith('application'):
        return response.raw_bytes

    # TODO: Non-json response contents
    return response.text
Пример #22
0
async def unmarshal_param(param, request):
    """Unmarshal the given parameter from the passed in request like object.

    :type param: :class:`bravado_core.param.Param`
    :type request: :class:`bravado_core.request.IncomingRequest`
    :return: value of parameter
    """
    swagger_spec = param.swagger_spec
    deref = swagger_spec.deref
    param_spec = deref(get_param_type_spec(param))
    location = param.location
    param_type = deref(param_spec.get('type'))
    cast_param = partial(cast_request_param, param_type, param.name)

    default_value = schema.get_default(swagger_spec, param_spec)

    if location == Location.path:
        raw_value = cast_param(request.match_info.get(param.name, None))
    elif location == Location.query:
        raw_value = cast_param(request.query.get(param.name, default_value))
    elif location == Location.header:
        raw_value = cast_param(request.headers.get(param.name, default_value))
    elif location == Location.form_data:
        if param_type == 'file':
            raw_value = request.files.get(param.name, None)
        else:
            raw_value = cast_param(request.form.get(param.name, default_value))
    elif location == Location.body:
        # TODO: verify content-type header
        try:
            raw_value = request.json()
        except ValueError as json_error:
            raise SwaggerMappingError(
                "Error reading request body JSON: {0}".format(str(json_error)))
    else:
        raise SwaggerMappingError(
            "Don't know how to unmarshal_param with location {0}".format(
                location))

    if raw_value is None and not schema.is_required(swagger_spec, param_spec):
        return None

    if param_type == 'array' and location != Location.body:
        raw_value = unmarshal_collection_format(swagger_spec, param_spec,
                                                raw_value)

    if swagger_spec.config['validate_requests']:
        validate_schema_object(swagger_spec, param_spec, raw_value)

    value = unmarshal_schema_object(swagger_spec, param_spec, raw_value)
    return value
Пример #23
0
def unmarshal_param(param, request):
    """Unmarshal the given parameter from the passed in request like object.

    :type param: :class:`bravado_core.param.Param`
    :type request: :class:`bravado_core.request.IncomingRequest`
    :return: value of parameter
    """
    swagger_spec = param.swagger_spec
    deref = swagger_spec.deref
    param_spec = deref(get_param_type_spec(param))
    location = param.location
    param_type = deref(param_spec.get('type'))
    cast_param = partial(cast_request_param, param_type, param.name)

    default_value = schema.get_default(swagger_spec, param_spec)

    if location == 'path':
        raw_value = cast_param(request.path.get(param.name, None))
    elif location == 'query':
        raw_value = cast_param(request.query.get(param.name, default_value))
    elif location == 'header':
        raw_value = cast_param(request.headers.get(param.name, default_value))
    elif location == 'formData':
        if param_type == 'file':
            raw_value = request.files.get(param.name, None)
        else:
            raw_value = cast_param(request.form.get(param.name, default_value))
    elif location == 'body':
        # TODO: verify content-type header
        try:
            raw_value = request.json()
        except ValueError as json_error:
            raise SwaggerMappingError("Error reading request body JSON: {0}".
                                      format(str(json_error)))
    else:
        raise SwaggerMappingError(
            "Don't know how to unmarshal_param with location {0}".
            format(location))

    if raw_value is None and not schema.is_required(swagger_spec, param_spec):
        return None

    if param_type == 'array' and location != 'body':
        raw_value = unmarshal_collection_format(swagger_spec, param_spec,
                                                raw_value)

    if swagger_spec.config['validate_requests']:
        validate_schema_object(swagger_spec, param_spec, raw_value)

    value = unmarshal_schema_object(swagger_spec, param_spec, raw_value)
    return value
Пример #24
0
def validate_response_headers(response_spec, response):
    """
    Validate an outgoing response's headers against the response's Swagger
    specification.

    :type response_spec: dict
    :type response: :class: `bravado_core.response.OutgoingResponse`
    """
    headers_spec = response_spec.get('headers')
    if not headers_spec:
        return

    for header_name, header_spec in headers_spec.iteritems():
        validate_schema_object(header_spec, response.headers.get(header_name))
Пример #25
0
def marshal_param(param, value, request):
    """Given an operation's parameter and its value, marshal the value and
    place it in the proper request destination.

    Destination is one of:
        - path - can accept primitive and array of primitive types
        - query - can accept primitive and array of primitive types
        - header - can accept primitive and array of primitive types
        - body - can accept any type
        - formData - can accept primitive and array of primitive types

    :type param: :class:`bravado_core.param.Param`
    :param value: The value to assign to the parameter
    :type request: dict
    """
    swagger_spec = param.swagger_spec
    deref = swagger_spec.deref

    spec = deref(get_param_type_spec(param))
    location = param.location
    value = marshal_schema_object(swagger_spec, spec, value)

    if swagger_spec.config['validate_requests']:
        validate_schema_object(swagger_spec, spec, value)

    param_type = spec.get('type')
    if param_type == 'array' and location != 'body':
        value = marshal_collection_format(swagger_spec, spec, value)

    if location == 'path':
        token = u'{%s}' % param.name
        # Don't do any escaping/encoding - http_client will take care of it
        request['url'] = request['url'].replace(token, six.text_type(value))
    elif location == 'query':
        request['params'][param.name] = value
    elif location == 'header':
        request['headers'][param.name] = value
    elif location == 'formData':
        if param_type == 'file':
            add_file(param, value, request)
        else:
            request.setdefault('data', {})[param.name] = value
    elif location == 'body':
        request['headers']['Content-Type'] = APP_JSON
        request['data'] = json.dumps(value)
    else:
        raise SwaggerMappingError(
            "Don't know how to marshal_param with location {0}".
            format(location))
Пример #26
0
def validate_response_headers(op, response_spec, response):
    """
    Validate an outgoing response's headers against the response's Swagger
    specification.

    :type op: :class:`bravado_core.operation.Operation`
    :type response_spec: dict
    :type response: :class:`bravado_core.response.OutgoingResponse`
    """
    headers_spec = response_spec.get('headers')
    if not headers_spec:
        return

    for header_name, header_spec in iteritems(headers_spec):
        validate_schema_object(op.swagger_spec, header_spec,
                               response.headers.get(header_name))
def parse_and_validate_parameters(raw_params):
    initialize_specification()

    clean_params = {}
    for parameter in _parsed_spec.spec_dict['parameters']:
        parameter_spec = _parsed_spec.spec_dict['parameters'][parameter]
        parameter_type = parameter_spec['type']
        parameter_name = parameter_spec['name']
        try:
            value = param.cast_request_param(parameter_type, parameter, raw_params.get(parameter_name))
            validate.validate_schema_object(_parsed_spec, parameter_spec, value)
            clean_params[parameter] = marshal.marshal_schema_object(_parsed_spec, parameter_spec, value)
        except Exception as e:
            raise ValueError(e)

    return clean_params
Пример #28
0
 def validate(self, model_name, object):
     """Validate an object against its swagger model"""
     if model_name not in self.swagger_dict['definitions']:
         raise ValidationError("Swagger spec has no definition for model %s" % model_name)
     model_def = self.swagger_dict['definitions'][model_name]
     log.debug("Validating %s" % model_name)
     return validate_schema_object(self.spec, model_def, object)
Пример #29
0
def validate_response_body(op, response_spec, response):
    """Validate an outgoing response's body against the response's Swagger
    specification.

    :type op: :class:`bravado_core.operation.Operation`
    :type response_spec: dict
    :type response: :class:`bravado_core.response.OutgoingResponse`

    :raises: SwaggerMappingError
    """
    deref = op.swagger_spec.deref

    # response that returns nothing in the body
    response_body_spec = deref(response_spec.get('schema'))
    if response_body_spec is None:
        if response.text in EMPTY_BODIES:
            return
        raise SwaggerMappingError(
            "Response body should be empty: {0}".format(response.text), )

    if response.content_type not in op.produces:
        raise SwaggerMappingError(
            "Response content-type '{0}' is not supported by the Swagger "
            "specification's content-types '{1}".format(
                response.content_type,
                op.produces,
            ), )

    if response.content_type == APP_JSON or response.content_type == APP_MSGPACK:
        if response.content_type == APP_JSON:
            response_value = response.json()
        else:
            response_value = msgpack.loads(response.raw_bytes, raw=False)
        validate_schema_object(
            op.swagger_spec,
            response_body_spec,
            response_value,
        )
    elif response.content_type.startswith("text/"):
        # TODO: support some kind of validation for text/* responses
        # TODO: but in the meantime don't raise errors for them
        pass
    else:
        # TODO: Expand content-type support for non-json types
        raise SwaggerMappingError(
            "Unsupported content-type in response: {0}".format(
                response.content_type), )
Пример #30
0
def marshal_param(param, value, request):
    """
    Given an operation parameter and its value, marshal the value and place it
    in the proper request destination.

    Destination is one of:
        - path - can accept primitive and array of primitive types
        - query - can accept primitive and array of primitive types
        - header - can accept primitive and array of primitive types
        - body - can accept any type
        - formData - can accept primitive and array of primitive types

    :type param: :class:`bravado_core.param.Param`
    :param value: The value to assign to the parameter
    :type request: dict
    """
    spec = get_param_type_spec(param)
    location = param.location
    value = marshal_schema_object(param.swagger_spec, spec, value)

    if param.swagger_spec.config['validate_requests']:
        validate_schema_object(spec, value)

    if spec['type'] == 'array' and location != 'body':
        value = marshal_collection_format(spec, value)

    if location == 'path':
        token = u'{%s}' % param.name
        request['url'] = \
            request['url'].replace(token, urllib.quote(unicode(value)))
    elif location == 'query':
        request['params'][param.name] = value
    elif location == 'header':
        request['headers'][param.name] = value
    elif location == 'formData':
        if spec['type'] == 'file':
            add_file(param, value, request)
        else:
            request.setdefault('data', {})[param.name] = value
    elif location == 'body':
        request['headers']['Content-Type'] = APP_JSON
        request['data'] = json.dumps(value)
    else:
        raise SwaggerMappingError(
            "Don't know how to marshal_param with location {0}".
            format(location))
Пример #31
0
def validate_response_headers(op, response_spec, response):
    """Validate an outgoing response's headers against the response's Swagger
    specification.

    :type op: :class:`bravado_core.operation.Operation`
    :type response_spec: dict
    :type response: :class:`bravado_core.response.OutgoingResponse`
    """
    deref = op.swagger_spec.deref

    headers_spec = deref(response_spec.get("headers"))
    if not headers_spec:
        return

    for header_name, header_spec in iteritems(headers_spec):
        header_spec = deref(header_spec)
        validate_schema_object(op.swagger_spec, header_spec, response.headers.get(header_name))
Пример #32
0
def validate_response_dict(rule, response_dict, http_method='GET', status_code=200, headers=None):
    path = rule_to_path(rule)

    if not headers:
        headers = {}

    # TODO: Validate the entire response, including headers
    # response = Response(response_dict, headers)

    op = spec.get_op_for_request(http_method, path)
    response_spec = get_response_spec(status_code, op)

    # No schema defined? Nothing to validate.
    if 'schema' not in response_spec:
        return

    validate_schema_object(spec, response_spec['schema'], response_dict)
Пример #33
0
def unmarshal_param(param, request):
    """Unmarshal the given parameter from the passed in request like object.

    :type param: :class:`bravado_core.param.Param`
    :type request: :class:`bravado_core.request.IncomingRequest`
    :return: value of parameter
    """
    swagger_spec = param.swagger_spec
    deref = swagger_spec.deref
    param_spec = deref(get_param_type_spec(param))
    location = param.location
    param_type = deref(param_spec.get('type'))
    cast_param = partial(cast_request_param, param_type, param.name)

    default_value = schema.get_default(swagger_spec, param_spec)

    if location == 'path':
        raw_value = cast_param(request.path.get(param.name, None))
    elif location == 'query':
        raw_value = cast_param(request.query.get(param.name, default_value))
    elif location == 'header':
        raw_value = cast_param(request.headers.get(param.name, default_value))
    elif location == 'formData':
        if param_type == 'file':
            raw_value = request.files.get(param.name, None)
        else:
            raw_value = cast_param(request.form.get(param.name, default_value))
    elif location == 'body':
        # TODO: verify content-type header
        raw_value = request.json()
    else:
        raise SwaggerMappingError(
            "Don't know how to unmarshal_param with location {0}".format(
                location))

    if param_type == 'array' and location != 'body':
        raw_value = unmarshal_collection_format(swagger_spec, param_spec,
                                                raw_value)

    if swagger_spec.config['validate_requests']:
        validate_schema_object(swagger_spec, param_spec, raw_value)

    value = unmarshal_schema_object(swagger_spec, param_spec, raw_value)
    return value
Пример #34
0
def validate_response_body(op, response_spec, response):
    """Validate an outgoing response's body against the response's Swagger
    specification.

    :type op: :class:`bravado_core.operation.Operation`
    :type response_spec: dict
    :type response: :class:`bravado_core.response.OutgoingResponse`

    :raises: SwaggerMappingError
    """
    deref = op.swagger_spec.deref

    # response that returns nothing in the body
    response_body_spec = deref(response_spec.get('schema'))
    if response_body_spec is None:
        if response.text in EMPTY_BODIES:
            return
        raise SwaggerMappingError(
            "Response body should be empty: {0}".format(response.text))

    if response.content_type not in op.produces:
        raise SwaggerMappingError(
            "Response content-type '{0}' is not supported by the Swagger "
            "specification's content-types '{1}"
            .format(response.content_type, op.produces))

    if response.content_type == APP_JSON or response.content_type == APP_MSGPACK:
        if response.content_type == APP_JSON:
            response_value = response.json()
        else:
            response_value = msgpack.loads(response.raw_bytes, encoding='utf-8')
        validate_schema_object(
            op.swagger_spec, response_body_spec, response_value)
    elif response.content_type.startswith("text/"):
        # TODO: support some kind of validation for text/* responses
        # TODO: but in the meantime don't raise errors for them
        pass
    else:
        # TODO: Expand content-type support for non-json types
        raise SwaggerMappingError(
            "Unsupported content-type in response: {0}"
            .format(response.content_type))
Пример #35
0
def unmarshal_response_inner(
        response,  # type: IncomingResponse
        op,  # type: Operation
):
    # type: (...) -> typing.Optional[T]
    """
    Unmarshal incoming http response into a value based on the
    response specification.
    :type response: :class:`bravado_core.response.IncomingResponse`
    :type op: :class:`bravado_core.operation.Operation`
    :returns: value where type(value) matches response_spec['schema']['type']
        if it exists, None otherwise.
    """
    deref = op.swagger_spec.deref
    response_spec = get_response_spec(status_code=response.status_code, op=op)

    if 'schema' not in response_spec:
        return None

    content_type = response.headers.get('content-type', '').lower()

    if content_type.startswith(APP_JSON) or content_type.startswith(
            APP_MSGPACK):
        content_spec = deref(response_spec['schema'])
        if content_type.startswith(APP_JSON):
            content_value = response.json()
        else:
            content_value = unpackb(response.raw_bytes, encoding='utf-8')

        if op.swagger_spec.config.get('validate_responses', False):
            validate_schema_object(op.swagger_spec, content_spec,
                                   content_value)

        return unmarshal_schema_object(
            swagger_spec=op.swagger_spec,
            schema_object_spec=content_spec,
            value=content_value,
        )

    # TODO: Non-json response contents
    return response.text
Пример #36
0
def unmarshal_param(param, request):
    """Unmarshal the given parameter from the passed in request like object.

    :type param: :class:`bravado_core.param.Param`
    :type request: :class:`bravado_core.request.IncomingRequest`
    """
    param_spec = get_param_type_spec(param)
    location = param.location
    cast_param = partial(cast_request_param, param_spec['type'], param.name)

    default_value = schema.get_default(param_spec)

    if location == 'path':
        raw_value = cast_param(request.path.get(param.name, None))
    elif location == 'query':
        raw_value = cast_param(request.query.get(param.name, default_value))
    elif location == 'header':
        raw_value = cast_param(request.headers.get(param.name, default_value))
    elif location == 'formData':
        if param_spec['type'] == 'file':
            raw_value = request.files.get(param.name, None)
        else:
            raw_value = cast_param(request.form.get(param.name, default_value))
    elif location == 'body':
        # TODO: verify content-type header
        raw_value = request.json()
    else:
        raise SwaggerMappingError(
            "Don't know how to unmarshal_param with location {0}".
            format(location))

    if param_spec['type'] == 'array' and location != 'body':
        raw_value = unmarshal_collection_format(param_spec, raw_value)

    if param.swagger_spec.config['validate_requests']:
        validate_schema_object(param.swagger_spec, param_spec, raw_value)

    value = unmarshal_schema_object(param.swagger_spec, param_spec, raw_value)
    return value
Пример #37
0
def test_no_validation_when_no_type(minimal_swagger_spec):
    validate_schema_object(minimal_swagger_spec, {}, None)
Пример #38
0
from bravado_core.validate import validate_schema_object
from jsonschema import ValidationError
from six.moves.urllib.parse import urljoin
from six.moves.urllib.request import pathname2url

old_client = SwaggerClient.from_url(spec_url=urljoin(
    'file:', pathname2url(abspath('old.yaml'))), )
new_client = SwaggerClient.from_url(spec_url=urljoin(
    'file:', pathname2url(abspath('new.yaml'))), )

object_to_validate = {'property': 'True'}

print('Validating the get endpoint response with old client: Succeeded')
validate_schema_object(
    swagger_spec=old_client.swagger_spec,
    schema_object_spec=old_client.swagger_spec.
    definitions['get_endpoint_response']._model_spec,
    value=object_to_validate,
)

print('Validating the get endpoint response with the new client: Failed')
try:
    validate_schema_object(
        swagger_spec=new_client.swagger_spec,
        schema_object_spec=new_client.swagger_spec.
        definitions['get_endpoint_response']._model_spec,
        value=object_to_validate,
    )
    raise RuntimeError('An error was expected')
except ValidationError:
    pass
def test_no_validation_when_no_type(minimal_swagger_spec):
    validate_schema_object(minimal_swagger_spec, {}, None)
Пример #40
0
def test_unknown_type(minimal_swagger_spec):
    with pytest.raises(SwaggerMappingError) as excinfo:
        validate_schema_object(minimal_swagger_spec, {'type': 'unknown'}, 'foo')
    assert 'Unknown type' in str(excinfo.value)