예제 #1
0
def empty_swagger_spec():
    return Spec(spec_dict={})
예제 #2
0
def test_ref(minimal_swagger_dict, int_array_spec):
    minimal_swagger_dict['definitions']['IntArray'] = int_array_spec
    ref_spec = {'$ref': '#/definitions/IntArray'}
    swagger_spec = Spec(minimal_swagger_dict)
    result = marshal_array(swagger_spec, ref_spec, [1, 2, 3])
    assert [1, 2, 3] == result
예제 #3
0
def test_ref(minimal_swagger_dict, address_spec, address):
    minimal_swagger_dict['definitions']['Address'] = address_spec
    ref_spec = {'$ref': '#/definitions/Address'}
    swagger_spec = Spec(minimal_swagger_dict)
    result = marshal_object(swagger_spec, ref_spec, address)
    assert address == result
예제 #4
0
def test_returns_operation_id_from_operation_spec():
    spec = Spec(spec_dict={})
    operation_spec = {'operationId': 'getPetById'}
    operation = Operation(spec, '/pet/{petId}', 'get', operation_spec)
    assert 'getPetById' == operation.operation_id
def test_ref(minimal_swagger_dict):
    ref_spec = {'$ref': '#/refs/Foo'}
    foo_spec = {'type': 'string'}
    minimal_swagger_dict['refs'] = {'Foo': foo_spec}
    swagger_spec = Spec(minimal_swagger_dict)
    assert 'foo' == marshal_schema_object(swagger_spec, ref_spec, 'foo')
예제 #6
0
def test_returns_generated_operation_id_with_path_parameters():
    spec = Spec(spec_dict={})
    operation_spec = {}
    operation = Operation(spec, '/pet/{petId}', 'get', operation_spec)
    assert 'get_pet_petId' == operation.operation_id
예제 #7
0
def test_returns_sanitized_operation_id_when_using_illegal_chars(
        input, expected):
    spec = Spec(spec_dict={})
    operation_spec = {'operationId': input}
    operation = Operation(spec, '/pet/{petId}', 'get', operation_spec)
    assert expected == operation.operation_id
예제 #8
0
def test_empty():
    swagger_spec = Spec({})
    callback = Mock()
    post_process_spec(swagger_spec, [callback])
    assert callback.call_count == 0
예제 #9
0
def test_returns_generated_operation_id_when_missing_from_operation_spec():
    spec = Spec(spec_dict={})
    operation_spec = {}
    operation = Operation(spec, '/pet', 'get', operation_spec)
    assert 'get_pet' == operation.operation_id
예제 #10
0
def assert_validate_call_count(expected_call_count, config, petstore_dict):
    spec = Spec(petstore_dict, config=config)
    with patch('bravado_core.spec.validator20.validate_spec') as m_validate:
        spec.build()
    assert expected_call_count == m_validate.call_count
예제 #11
0
def build_swagger_spec(swagger_dict):
    spec = Spec(swagger_dict)
    spec.api_url = 'http://localhost/'
    return spec
예제 #12
0
def test_empty():
    spec_dict = {'paths': {}}
    spec = Spec(spec_dict)
    assert {} == build_resources(spec)
예제 #13
0
def test_resource_with_a_single_operation_associated_by_tag(paths_spec):
    spec_dict = {'paths': paths_spec}
    resources = build_resources(Spec(spec_dict))
    assert 1 == len(resources)
    assert resources['pet'].findPetsByStatus
예제 #14
0
def test_ref(minimal_swagger_dict, body_param_spec):
    minimal_swagger_dict['parameters'] = {'PetIdParam': body_param_spec}
    param_ref_spec = {'$ref': '#/parameters/PetIdParam'}
    swagger_spec = Spec(minimal_swagger_dict)
    param = Param(swagger_spec, Mock(spec=Operation), param_ref_spec)
    assert {'type': 'string'} == get_param_type_spec(param)
예제 #15
0
def test_op_with_security_in_root_without_security_defs(
    specs_with_security_obj_in_root_and_no_security_specs, ):
    with pytest.raises(SwaggerSchemaError):
        build_resources(
            Spec(specs_with_security_obj_in_root_and_no_security_specs, ))
예제 #16
0
def flattened_spec(swagger_spec, marshal_uri_function=_marshal_uri):
    """
    Flatten Swagger Specs description into an unique and JSON serializable document.
    The flattening injects in place the referenced [path item objects](https://swagger.io/specification/#pathItemObject)
    while it injects in '#/parameters' the [parameter objects](https://swagger.io/specification/#parameterObject),
    in '#/definitions' the [schema objects](https://swagger.io/specification/#schemaObject) and in
    '#/responses' the [response objects](https://swagger.io/specification/#responseObject).

    Note: the object names in '#/definitions', '#/parameters' and '#/responses' are evaluated by
    ``marshal_uri_function``, the default method takes care of creating unique names for all the used references.
    Since name clashing are still possible take care that a warning could be filed.
    If it happen please report to us the specific warning text and the specs that generated it.
    We can work to improve it and in the mean time you can "plug" a custom marshalling function.

    Note: https://swagger.io/specification/ has been update to track the latest version of the Swagger/OpenAPI specs.
    Please refer to https://github.com/OAI/OpenAPI-Specification/blob/3.0.0/versions/2.0.md#responseObject for the
    most recent Swagger 2.0 specifications.

    WARNING: In the future releases all the parameters except swagger_spec and marshal_uri_function will be removed.
    Please make sure to use only those two parameters.
    Until the deprecation is not effective you can still pass all the parameters but it's strongly discouraged.

    :param swagger_spec: bravado-core Spec object
    :type swagger_spec: bravado_core.spec.Spec
    :param marshal_uri_function: function used to marshal uris in string suitable to be keys in Swagger Specs.
    :type marshal_uri_function: Callable with the same signature of ``_marshal_uri``

    :return: Flattened representation of the Swagger Specs
    :rtype: dict
    """
    spec_url = swagger_spec.origin_url

    if spec_url is None:
        warnings.warn(
            message=
            'It is recommended to set origin_url to your spec before flattering it. '
            'Doing so internal paths will be hidden, reducing the amount of exposed information.',
            category=Warning,
        )

    known_mappings = {
        object_type.get_root_holder(): {}
        for object_type in ObjectType if object_type.get_root_holder()
    }

    # Define marshal_uri method to be used by descend
    marshal_uri = functools.partial(
        marshal_uri_function,
        origin_uri=urlparse(spec_url) if spec_url else None,
    )

    # Avoid object attribute extraction during descend
    spec_resolver = swagger_spec.resolver
    resolve = swagger_spec.resolver.resolve

    default_type_to_object = swagger_spec.config[
        'default_type_to_object'] if swagger_spec else True

    def descend(value):
        if is_ref(value):
            # Update spec_resolver scope to be able to dereference relative specs from a not root file
            with in_scope(spec_resolver, value):
                uri, deref_value = resolve(value['$ref'])
                object_type = determine_object_type(
                    object_dict=deref_value,
                    default_type_to_object=default_type_to_object,
                )

                known_mapping_key = object_type.get_root_holder()
                if known_mapping_key is None:
                    return descend(value=deref_value)
                else:
                    uri = urlparse(uri)
                    if uri not in known_mappings.get(known_mapping_key, {}):
                        # The placeholder is present to interrupt the recursion
                        # during the recursive traverse of the data model (``descend``)
                        known_mappings[known_mapping_key][uri] = None

                        known_mappings[known_mapping_key][uri] = descend(
                            value=deref_value)

                    return {
                        '$ref':
                        '#/{}/{}'.format(known_mapping_key, marshal_uri(uri))
                    }

        elif is_dict_like(value):
            return {
                key: descend(value=subval)
                for key, subval in iteritems(value)
            }

        elif is_list_like(value):
            return [
                descend(value=subval) for index, subval in enumerate(value)
            ]

        else:
            return value

    # Create internal copy of spec_dict to avoid external dict pollution
    resolved_spec = descend(value=copy.deepcopy(swagger_spec.spec_dict))

    # If definitions were identified by the swagger_spec object
    if swagger_spec.definitions is not None:
        # local imports due to circular dependency
        from bravado_core.spec import Spec
        from bravado_core.model import model_discovery

        # Run model-discovery in order to tag the models available in known_mappings['definitions']
        # This is a required step that removes duplications of models due to the presence of models
        # in swagger.json#/definitions and the equivalent models generated by flattening
        model_discovery(
            Spec(spec_dict={
                'definitions': {
                    marshal_uri(uri): value
                    for uri, value in iteritems(known_mappings['definitions'])
                },
            }, ))

        flatten_models = {
            # schema objects might not have a "type" set so they won't be tagged as models
            definition.get(MODEL_MARKER)
            for definition in itervalues(known_mappings['definitions'])
        }

        for model_name, model_type in iteritems(swagger_spec.definitions):
            if model_name in flatten_models:
                continue
            model_url = urlparse(model_type._json_reference)
            known_mappings['definitions'][model_url] = descend(
                value=model_type._model_spec)

    for mapping_key, mappings in iteritems(known_mappings):
        _warn_if_uri_clash_on_same_marshaled_representation(
            uri_schema_mappings=mappings,
            marshal_uri=marshal_uri,
        )
        if len(mappings) > 0:
            resolved_spec.update({
                mapping_key: {
                    marshal_uri(uri): value
                    for uri, value in iteritems(mappings)
                }
            })

    return resolved_spec