Example #1
0
def _add_tag(tag: OpenAPITag, tag_group: Optional[str] = None) -> None:
    name = tag["name"]
    if name in [t["name"] for t in SPEC._tags]:
        return

    SPEC.tag(tag)
    if tag_group is not None:
        _assign_to_tag_group(tag_group, name)
Example #2
0
def _add_tag(tag: dict, tag_group: Optional[str] = None) -> None:
    name = tag['name']
    if name in [t['name'] for t in SPEC._tags]:
        return

    SPEC.tag(tag)
    if tag_group is not None:
        _assign_to_tag_group(tag_group, name)
Example #3
0
def _add_tag(tag, tag_group=None):
    # type: (dict, Optional[str]) -> None
    name = tag['name']
    if name in [t['name'] for t in SPEC._tags]:
        return

    SPEC.tag(tag)
    if tag_group is not None:
        _assign_to_tag_group(tag_group, name)
Example #4
0
    def _add_api_spec(func):
        module_obj = import_string(func.__module__)
        module_name = module_obj.__name__
        operation_id = func.__module__ + "." + func.__name__

        ENDPOINT_REGISTRY.add_endpoint(
            module_name,
            name,
            method,
            path,
            find_all_parameters(primitive_parameters),
        )

        if not output_empty and response_schema is None:
            raise ValueError(f"{operation_id}: 'response_schema' required when "
                             f"output will be sent!")

        if output_empty and response_schema:
            raise ValueError(f"{operation_id}: On empty output 'output_schema' may not be used.")

        headers: Dict[str, PrimitiveParameter] = {}
        if etag in ('output', 'both'):
            headers.update(ETAG_HEADER_PARAM.header_dict())

        responses: ResponseType = {}

        # We don't(!) support any endpoint without an output schema.
        # Just define one!
        if response_schema is not None:
            responses['200'] = {
                'content': {
                    content_type: {
                        'schema': response_schema
                    },
                },
                'description': apispec.utils.dedent(response_schema.__doc__ or ''),
                'headers': headers,
            }

        if will_do_redirects:
            responses['302'] = {
                'description':
                    ('Either the resource has moved or has not yet completed. Please see this '
                     'resource for further information.')
            }

        # Actually, iff you don't want to give out anything, then we don't need a schema.
        if output_empty:
            responses['204'] = {
                'description': 'Operation done successfully. No further output.',
                'headers': headers,
            }

        tag_obj: OpenAPITag = {
            'name': module_name,
        }
        docstring_name = _docstring_name(module_obj.__doc__)
        if docstring_name:
            tag_obj['x-displayName'] = docstring_name
        docstring_desc = _docstring_description(module_obj.__doc__)
        if docstring_desc:
            tag_obj['description'] = docstring_desc
        _add_tag(tag_obj, tag_group='Endpoints')

        operation_spec: OperationSpecType = {
            'operationId': operation_id,
            'tags': [module_name],
            'description': '',
            'responses': {
                'default': {
                    'description': 'Any unsuccessful or unexpected result.',
                    'content': {
                        'application/problem+json': {
                            'schema': error_schema,
                        }
                    }
                }
            },
            'parameters': primitive_parameters,
        }

        if etag in ('input', 'both'):
            operation_spec['parameters'].append(ETAG_IF_MATCH_HEADER.to_dict())

        operation_spec['responses'].update(responses)

        if request_schema is not None:
            tag = _tag_from_schema(request_schema)
            _add_tag(tag, tag_group='Request Schemas')

            operation_spec['requestBody'] = {
                'required': request_body_required,
                'content': {
                    'application/json': {
                        'schema': request_schema,
                    }
                }
            }

        operation_spec['x-codeSamples'] = code_samples(path, method, request_schema, operation_spec)

        # If we don't have any parameters we remove the empty list, so the spec will not have it.
        if not operation_spec['parameters']:
            del operation_spec['parameters']

        docstring_name = _docstring_name(func.__doc__)
        if docstring_name:
            operation_spec['summary'] = docstring_name
        docstring_desc = _docstring_description(func.__doc__)
        if docstring_desc:
            operation_spec['description'] = docstring_desc

        apispec.utils.deepupdate(operation_spec, options)

        if func not in _SEEN_ENDPOINTS:
            # NOTE:
            # Only add the endpoint to the spec if not already done. We don't want
            # to add it multiple times. While this shouldn't be happening, doctest
            # sometimes complains that it would be happening. Not sure why. Anyways,
            # it's not a big deal as long as the SPEC is written correctly.
            SPEC.path(path=path, operations={method.lower(): operation_spec})
            _SEEN_ENDPOINTS.add(func)

        return wrap_with_validation(func, request_schema, response_schema)