mirror of
https://github.com/ansible/awx.git
synced 2026-03-19 18:07:33 -02:30
add support for marking Swagger paths deprecated
This commit is contained in:
@@ -1,3 +1,4 @@
|
|||||||
|
import json
|
||||||
import warnings
|
import warnings
|
||||||
|
|
||||||
from coreapi.document import Object, Link
|
from coreapi.document import Object, Link
|
||||||
@@ -25,6 +26,8 @@ class AutoSchema(DRFAuthSchema):
|
|||||||
'generated for {} {}.'
|
'generated for {} {}.'
|
||||||
.format(self.view.__class__.__name__, method, path))
|
.format(self.view.__class__.__name__, method, path))
|
||||||
|
|
||||||
|
link.__dict__['deprecated'] = getattr(self.view, 'deprecated', False)
|
||||||
|
|
||||||
# auto-generate a topic/tag for the serializer based on its model
|
# auto-generate a topic/tag for the serializer based on its model
|
||||||
if hasattr(self.view, 'swagger_topic'):
|
if hasattr(self.view, 'swagger_topic'):
|
||||||
link.__dict__['topic'] = str(self.view.swagger_topic).title()
|
link.__dict__['topic'] = str(self.view.swagger_topic).title()
|
||||||
@@ -62,6 +65,9 @@ class SwaggerSchemaView(APIView):
|
|||||||
urlconf=None
|
urlconf=None
|
||||||
)
|
)
|
||||||
schema = generator.get_schema(request=request)
|
schema = generator.get_schema(request=request)
|
||||||
|
# python core-api doesn't support the deprecation yet, so track it
|
||||||
|
# ourselves and return it in a response header
|
||||||
|
_deprecated = []
|
||||||
|
|
||||||
# By default, DRF OpenAPI serialization places all endpoints in
|
# By default, DRF OpenAPI serialization places all endpoints in
|
||||||
# a single node based on their root path (/api). Instead, we want to
|
# a single node based on their root path (/api). Instead, we want to
|
||||||
@@ -75,6 +81,11 @@ class SwaggerSchemaView(APIView):
|
|||||||
if topic:
|
if topic:
|
||||||
schema._data.setdefault(topic, Object())
|
schema._data.setdefault(topic, Object())
|
||||||
schema._data[topic]._data[path] = node
|
schema._data[topic]._data[path] = node
|
||||||
|
|
||||||
|
if isinstance(action, Object):
|
||||||
|
for link in action.links.values():
|
||||||
|
if link.deprecated:
|
||||||
|
_deprecated.append(link.url)
|
||||||
elif isinstance(node, Link):
|
elif isinstance(node, Link):
|
||||||
topic = getattr(node, 'topic', None)
|
topic = getattr(node, 'topic', None)
|
||||||
if topic:
|
if topic:
|
||||||
@@ -86,4 +97,7 @@ class SwaggerSchemaView(APIView):
|
|||||||
'The schema generator did not return a schema Document'
|
'The schema generator did not return a schema Document'
|
||||||
)
|
)
|
||||||
|
|
||||||
return Response(schema)
|
return Response(
|
||||||
|
schema,
|
||||||
|
headers={'X-Deprecated-Paths': json.dumps(_deprecated)}
|
||||||
|
)
|
||||||
|
|||||||
@@ -42,27 +42,27 @@ class TestSwaggerGeneration():
|
|||||||
url = drf_reverse('api:swagger_view') + '?format=openapi'
|
url = drf_reverse('api:swagger_view') + '?format=openapi'
|
||||||
response = get(url, user=admin)
|
response = get(url, user=admin)
|
||||||
data = generate_swagger_object(response.data)
|
data = generate_swagger_object(response.data)
|
||||||
|
if response.has_header('X-Deprecated-Paths'):
|
||||||
|
data['deprecated_paths'] = json.loads(response['X-Deprecated-Paths'])
|
||||||
data.update(response.accepted_renderer.get_customizations() or {})
|
data.update(response.accepted_renderer.get_customizations() or {})
|
||||||
self.__class__.JSON = data
|
self.__class__.JSON = data
|
||||||
|
|
||||||
def _lookup_display_name(self, method, path):
|
|
||||||
return path
|
|
||||||
|
|
||||||
def test_transform_metadata(self, release):
|
def test_transform_metadata(self, release):
|
||||||
"""
|
"""
|
||||||
This test takes the JSON output from the swagger endpoint and applies
|
This test takes the JSON output from the swagger endpoint and applies
|
||||||
various transformations to it.
|
various transformations to it.
|
||||||
"""
|
"""
|
||||||
self.__class__.JSON['info']['version'] = release
|
JSON = self.__class__.JSON
|
||||||
self.__class__.JSON['host'] = None
|
JSON['info']['version'] = release
|
||||||
self.__class__.JSON['schemes'] = ['https']
|
JSON['host'] = None
|
||||||
self.__class__.JSON['produces'] = ['application/json']
|
JSON['schemes'] = ['https']
|
||||||
self.__class__.JSON['consumes'] = ['application/json']
|
JSON['produces'] = ['application/json']
|
||||||
|
JSON['consumes'] = ['application/json']
|
||||||
|
|
||||||
# Inject a top-level description into the OpenAPI document
|
# Inject a top-level description into the OpenAPI document
|
||||||
if os.path.exists(description_file):
|
if os.path.exists(description_file):
|
||||||
with open(description_file, 'r') as f:
|
with open(description_file, 'r') as f:
|
||||||
self.__class__.JSON['info']['description'] = f.read()
|
JSON['info']['description'] = f.read()
|
||||||
|
|
||||||
# Write tags in the order we want them sorted
|
# Write tags in the order we want them sorted
|
||||||
if os.path.exists(config_file):
|
if os.path.exists(config_file):
|
||||||
@@ -72,9 +72,10 @@ class TestSwaggerGeneration():
|
|||||||
tag = {'name': category['name']}
|
tag = {'name': category['name']}
|
||||||
if 'description' in category:
|
if 'description' in category:
|
||||||
tag['description'] = category['description']
|
tag['description'] = category['description']
|
||||||
self.__class__.JSON.setdefault('tags', []).append(tag)
|
JSON.setdefault('tags', []).append(tag)
|
||||||
|
|
||||||
revised_paths = {}
|
revised_paths = {}
|
||||||
|
deprecated_paths = JSON.pop('deprecated_paths', [])
|
||||||
for path, node in self.__class__.JSON['paths'].items():
|
for path, node in self.__class__.JSON['paths'].items():
|
||||||
# change {version} in paths to the actual default API version (e.g., v2)
|
# change {version} in paths to the actual default API version (e.g., v2)
|
||||||
revised_paths[path.replace(
|
revised_paths[path.replace(
|
||||||
@@ -82,6 +83,8 @@ class TestSwaggerGeneration():
|
|||||||
settings.REST_FRAMEWORK['DEFAULT_VERSION']
|
settings.REST_FRAMEWORK['DEFAULT_VERSION']
|
||||||
)] = node
|
)] = node
|
||||||
for method in node:
|
for method in node:
|
||||||
|
if path in deprecated_paths:
|
||||||
|
node[method]['deprecated'] = True
|
||||||
if 'description' in node[method]:
|
if 'description' in node[method]:
|
||||||
# Pop off the first line and use that as the summary
|
# Pop off the first line and use that as the summary
|
||||||
lines = node[method]['description'].splitlines()
|
lines = node[method]['description'].splitlines()
|
||||||
|
|||||||
Reference in New Issue
Block a user