From 6ad77b3ef0c8fc69a63cd796e20694e62faea46b Mon Sep 17 00:00:00 2001 From: Carlton Gibson Date: Wed, 8 Jan 2020 20:37:23 +0100 Subject: [PATCH 1/3] Return valid OpenAPI schema even when empty. --- rest_framework/schemas/openapi.py | 10 +--------- tests/schemas/test_openapi.py | 9 +++++++++ 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/rest_framework/schemas/openapi.py b/rest_framework/schemas/openapi.py index 58788bc234..aaeb2914c1 100644 --- a/rest_framework/schemas/openapi.py +++ b/rest_framework/schemas/openapi.py @@ -35,12 +35,7 @@ def get_info(self): def get_paths(self, request=None): result = {} - paths, view_endpoints = self._get_paths_and_endpoints(request) - - # Only generate the path prefix for paths that will be included - if not paths: - return None - + _, view_endpoints = self._get_paths_and_endpoints(request) for path, method, view in view_endpoints: if not self.has_view_permissions(path, method, view): continue @@ -62,9 +57,6 @@ def get_schema(self, request=None, public=False): self._initialise_endpoints() paths = self.get_paths(None if public else request) - if not paths: - return None - schema = { 'openapi': '3.0.2', 'info': self.get_info(), diff --git a/tests/schemas/test_openapi.py b/tests/schemas/test_openapi.py index 03eb9de7a9..83473be4b3 100644 --- a/tests/schemas/test_openapi.py +++ b/tests/schemas/test_openapi.py @@ -707,6 +707,15 @@ def test_schema_construction(self): assert 'openapi' in schema assert 'paths' in schema + def test_schema_with_no_paths(self): + patterns = [] + generator = SchemaGenerator(patterns=patterns) + + request = create_request('/') + schema = generator.get_schema(request=request) + + assert schema['paths'] == {} + def test_schema_information(self): """Construction of the top level dictionary.""" patterns = [ From 1389545981d51b0cb99b4c01e9c41ead8d13f89f Mon Sep 17 00:00:00 2001 From: Carlton Gibson Date: Wed, 8 Jan 2020 20:42:59 +0100 Subject: [PATCH 2/3] Call get_schema(), rather than sub-method in schema tests. --- tests/schemas/test_openapi.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/schemas/test_openapi.py b/tests/schemas/test_openapi.py index 83473be4b3..8a723b85d9 100644 --- a/tests/schemas/test_openapi.py +++ b/tests/schemas/test_openapi.py @@ -659,7 +659,7 @@ def test_paths_construction(self): generator = SchemaGenerator(patterns=patterns) generator._initialise_endpoints() - paths = generator.get_paths() + paths = generator.get_schema()["paths"] assert '/example/' in paths example_operations = paths['/example/'] @@ -676,7 +676,7 @@ def test_prefixed_paths_construction(self): generator = SchemaGenerator(patterns=patterns) generator._initialise_endpoints() - paths = generator.get_paths() + paths = generator.get_schema()["paths"] assert '/v1/example/' in paths assert '/v1/example/{id}/' in paths @@ -689,7 +689,7 @@ def test_mount_url_prefixed_to_paths(self): generator = SchemaGenerator(patterns=patterns, url='/api') generator._initialise_endpoints() - paths = generator.get_paths() + paths = generator.get_schema()["paths"] assert '/api/example/' in paths assert '/api/example/{id}/' in paths From 67549c3e48dd038c9f99ccff5725f9d2b9f70bd1 Mon Sep 17 00:00:00 2001 From: Carlton Gibson Date: Wed, 8 Jan 2020 21:12:26 +0100 Subject: [PATCH 3/3] Inline unnecessary method in OpenAPI schema generator. --- rest_framework/schemas/openapi.py | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/rest_framework/schemas/openapi.py b/rest_framework/schemas/openapi.py index aaeb2914c1..1df132ce32 100644 --- a/rest_framework/schemas/openapi.py +++ b/rest_framework/schemas/openapi.py @@ -32,31 +32,30 @@ def get_info(self): return info - def get_paths(self, request=None): - result = {} + def get_schema(self, request=None, public=False): + """ + Generate a OpenAPI schema. + """ + self._initialise_endpoints() - _, view_endpoints = self._get_paths_and_endpoints(request) + # Iterate endpoints generating per method path operations. + # TODO: …and reference components. + paths = {} + _, view_endpoints = self._get_paths_and_endpoints(None if public else request) for path, method, view in view_endpoints: if not self.has_view_permissions(path, method, view): continue + operation = view.schema.get_operation(path, method) # Normalise path for any provided mount url. if path.startswith('/'): path = path[1:] path = urljoin(self.url or '/', path) - result.setdefault(path, {}) - result[path][method.lower()] = operation - - return result - - def get_schema(self, request=None, public=False): - """ - Generate a OpenAPI schema. - """ - self._initialise_endpoints() + paths.setdefault(path, {}) + paths[path][method.lower()] = operation - paths = self.get_paths(None if public else request) + # Compile final schema. schema = { 'openapi': '3.0.2', 'info': self.get_info(),