Skip to content

Commit

Permalink
Support to deprecate and hide an endpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
greyli committed Mar 12, 2021
1 parent e12e5a8 commit 82d181a
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 2 deletions.
21 changes: 19 additions & 2 deletions apiflask/decorators.py
Expand Up @@ -93,7 +93,14 @@ def _response(*args, **kwargs):
return decorator


def doc(summary=None, description=None, tag=None, responses=None):
def doc(
summary=None,
description=None,
tag=None,
responses=None,
deprecated=None,
hide=False
):
"""
Set up OpenAPI documentation for view function.
Expand All @@ -108,10 +115,20 @@ def doc(summary=None, description=None, tag=None, responses=None):
attribute. If app.tags not set, the blueprint name will be used as tag name.
:param responses: The other responses for this view function, accept a dict in a format
of ``{400: 'Bad Request'}``.
:param deprecated: Flag this endpoint as deprecated in API docs. Defaults to ``None``.
:param hide: Hide this endpoint in API docs. Defaults to ``False``.
.. versionadded:: 0.2.0
"""
def decorator(f):
_annotate(f, summary=summary, description=description, tag=tag, responses=responses)
_annotate(
f,
summary=summary,
description=description,
tag=tag,
responses=responses,
deprecated=deprecated,
hide=hide
)
return f
return decorator
17 changes: 17 additions & 0 deletions apiflask/openapi.py
Expand Up @@ -320,6 +320,7 @@ def resolver(schema):
view_func._spec = \
dict(_response=True, status_code=200, response_description=None)

# tag
tag = None
if view_func._spec.get('tag'):
tag = view_func._spec.get('tag')
Expand All @@ -329,6 +330,8 @@ def resolver(schema):
tag = rule.endpoint.split('.', 1)[0].title()

for method in ['GET', 'POST', 'PUT', 'PATCH', 'DELETE']:
if view_func._spec.get('hide') == True:
continue
if method not in rule.methods:
continue
operation = {
Expand All @@ -342,19 +345,29 @@ def resolver(schema):
if tag:
operation['tags'] = [tag]

# summary and description
if view_func._spec.get('summary'):
operation['summary'] = view_func._spec.get('summary')
operation['description'] = view_func._spec.get('description')
else:
# auto-generate summary and description from dotstring
docs = (view_func.__doc__ or '').strip().split('\n')
if docs[0]:
# Use the first line of docstring as summary
operation['summary'] = docs[0]
else:
# Use the function name as summary
operation['summary'] = ' '.join(
view_func.__name__.split('_')).title()
if len(docs) > 1:
# Use the remain lines of docstring as description
operation['description'] = '\n'.join(docs[1:]).strip()

# deprecated
if view_func._spec.get('deprecated'):
operation['deprecated'] = view_func._spec.get('deprecated')

# responses
if view_func._spec.get('responses'):
for status_code, description in view_func._spec.get('responses').items():
operation['responses'][status_code] = {'description': description}
Expand All @@ -378,6 +391,7 @@ def resolver(schema):
operation['responses']['204']['description'] = \
self.config['204_DESCRIPTION']

# requestBody
if view_func._spec.get('body'):
operation['requestBody'] = {
'content': {
Expand All @@ -387,12 +401,14 @@ def resolver(schema):
}
}

# security
if view_func._spec.get('auth'):
operation['security'] = [{
security[view_func._spec['auth']]: view_func._spec[
'roles']
}]

# Add validation error response
if view_func._spec.get('body') or view_func._spec.get('args'):
code = self.config['VALIDATION_ERROR_CODE']
operation['responses'][code] = {
Expand All @@ -407,6 +423,7 @@ def resolver(schema):

operations[method.lower()] = operation

# parameters
path_arguments = re.findall(r'<(([^:]+:)?([^>]+))>', rule.rule)
if path_arguments:
arguments = []
Expand Down

0 comments on commit 82d181a

Please sign in to comment.