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)
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)
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)
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)