From 981e4f89460826388b680569aa01c1664aec725b Mon Sep 17 00:00:00 2001 From: Suyash Vardhan Mathur <56172924+MSurfer20@users.noreply.github.com> Date: Tue, 13 Jul 2021 21:03:43 +0530 Subject: [PATCH] openapi: Render all responses of an operation. Previously, one needed to specifying all the HTTP status codes that we want to render along with the operation, but the primary use case just needs the responses of all the status codes, and not just one. This commit modifies the Markdown extension to render all the responses of all status codes of a specified operation in a loop. --- docs/documentation/api.md | 7 ++- templates/zerver/api/api-doc-template.md | 4 +- templates/zerver/api/mark-all-as-read.md | 12 ++--- templates/zerver/api/outgoing-webhooks.md | 2 +- templates/zerver/api/rest-error-handling.md | 8 +-- templates/zerver/api/send-message.md | 4 +- zerver/openapi/markdown_extension.py | 8 ++- zerver/openapi/openapi.py | 58 +++++++++++---------- 8 files changed, 44 insertions(+), 59 deletions(-) diff --git a/docs/documentation/api.md b/docs/documentation/api.md index f156bf66dc..cde321b8a2 100644 --- a/docs/documentation/api.md +++ b/docs/documentation/api.md @@ -182,12 +182,11 @@ must have a `post` HTTP method defined. If you've already followed the steps in the [Usage examples](#usage-examples) section, this part should be fairly trivial. -You can use the following Markdown directive to render the fixtures -defined in the OpenAPI `zulip.yaml` for a given endpoint and status -code: +You can use the following Markdown directive to render all the fixtures +defined in the OpenAPI `zulip.yaml` for a given endpoint ``` -{generate_code_example|/messages/render:post|fixture(200)} +{generate_code_example|/messages/render:post|fixture} ``` ## Step by step guide diff --git a/templates/zerver/api/api-doc-template.md b/templates/zerver/api/api-doc-template.md index 38daf38b61..272b905f3b 100644 --- a/templates/zerver/api/api-doc-template.md +++ b/templates/zerver/api/api-doc-template.md @@ -30,6 +30,4 @@ #### Example response -{generate_code_example|API_ENDPOINT_NAME|fixture(200)} - -{generate_code_example|API_ENDPOINT_NAME|fixture(400)} +{generate_code_example|API_ENDPOINT_NAME|fixture} diff --git a/templates/zerver/api/mark-all-as-read.md b/templates/zerver/api/mark-all-as-read.md index 13ecff3a54..5646331fde 100644 --- a/templates/zerver/api/mark-all-as-read.md +++ b/templates/zerver/api/mark-all-as-read.md @@ -28,9 +28,7 @@ #### Example response -{generate_code_example|/mark_all_as_read:post|fixture(200)} - -{generate_code_example|/mark_all_as_read:post|fixture(400)} +{generate_code_example|/mark_all_as_read:post|fixture} {generate_api_title(/mark_stream_as_read:post)} @@ -64,9 +62,7 @@ #### Example response -{generate_code_example|/mark_stream_as_read:post|fixture(200)} - -{generate_code_example|/mark_stream_as_read:post|fixture(400)} +{generate_code_example|/mark_stream_as_read:post|fixture} # Mark messages in a topic as read {generate_api_title(/mark_topic_as_read:post)} @@ -101,6 +97,4 @@ #### Example response -{generate_code_example|/mark_topic_as_read:post|fixture(200)} - -{generate_code_example|/mark_topic_as_read:post|fixture(400)} +{generate_code_example|/mark_topic_as_read:post|fixture} diff --git a/templates/zerver/api/outgoing-webhooks.md b/templates/zerver/api/outgoing-webhooks.md index a09884f7d9..87e0e0d8ed 100644 --- a/templates/zerver/api/outgoing-webhooks.md +++ b/templates/zerver/api/outgoing-webhooks.md @@ -46,7 +46,7 @@ settings][settings]. ## Outgoing webhook format -{generate_code_example|/zulip-outgoing-webhook:post|fixture(200)} +{generate_code_example|/zulip-outgoing-webhook:post|fixture} ### Fields documentation diff --git a/templates/zerver/api/rest-error-handling.md b/templates/zerver/api/rest-error-handling.md index 622d62a70c..f92a006bb6 100644 --- a/templates/zerver/api/rest-error-handling.md +++ b/templates/zerver/api/rest-error-handling.md @@ -17,13 +17,7 @@ translated into French if the user has a French locale). Each endpoint documents its own unique errors; below, we document errors common to many endpoints: -{generate_code_example|/rest-error-handling:post|fixture(400)} - -{generate_code_example|/rest-error-handling:post|fixture(401)} - -{generate_code_example|/rest-error-handling:post|fixture(403)} - -{generate_code_example|/rest-error-handling:post|fixture(429)} +{generate_code_example|/rest-error-handling:post|fixture} The `retry-after` paremeter in the response indicates how many seconds the client must wait before making additional requests. diff --git a/templates/zerver/api/send-message.md b/templates/zerver/api/send-message.md index eb0bf407b4..d67511d6ae 100644 --- a/templates/zerver/api/send-message.md +++ b/templates/zerver/api/send-message.md @@ -76,6 +76,4 @@ file. #### Example response -{generate_code_example|/messages:post|fixture(200)} - -{generate_code_example|/messages:post|fixture(400)} +{generate_code_example|/messages:post|fixture} diff --git a/zerver/openapi/markdown_extension.py b/zerver/openapi/markdown_extension.py index 5f2959fdd8..0434ca7e31 100644 --- a/zerver/openapi/markdown_extension.py +++ b/zerver/openapi/markdown_extension.py @@ -451,14 +451,12 @@ class APICodeExamplesPreprocessor(Preprocessor): language, options = parse_language_and_options(match.group(2)) function = match.group(3) key = match.group(4) - argument = match.group(6) if self.api_url is None: raise AssertionError("Cannot render curl API examples without API URL set.") options["api_url"] = self.api_url if key == "fixture": - if argument: - text = self.render_fixture(function, name=argument) + text = self.render_fixture(function) elif key == "example": path, method = function.rsplit(":", 1) if language in ADMIN_CONFIG_LANGUAGES and check_requires_administrator( @@ -484,9 +482,9 @@ class APICodeExamplesPreprocessor(Preprocessor): done = True return lines - def render_fixture(self, function: str, name: str) -> List[str]: + def render_fixture(self, function: str) -> List[str]: path, method = function.rsplit(":", 1) - return generate_openapi_fixture(path, method, name) + return generate_openapi_fixture(path, method) class APIDescriptionPreprocessor(Preprocessor): diff --git a/zerver/openapi/openapi.py b/zerver/openapi/openapi.py index d9fab253b3..b39e89c8fd 100644 --- a/zerver/openapi/openapi.py +++ b/zerver/openapi/openapi.py @@ -254,39 +254,43 @@ def get_parameters_description(endpoint: str, method: str) -> str: ) -def generate_openapi_fixture(endpoint: str, method: str, status_code: str = "200") -> List[str]: +def generate_openapi_fixture(endpoint: str, method: str) -> List[str]: """Generate fixture to be rendered""" fixture = [] - if status_code not in openapi_spec.openapi()["paths"][endpoint][method.lower()]["responses"]: - subschema_count = 0 - elif ( - "oneOf" - in openapi_spec.openapi()["paths"][endpoint][method.lower()]["responses"][status_code][ - "content" - ]["application/json"]["schema"] + for status_code in sorted( + openapi_spec.openapi()["paths"][endpoint][method.lower()]["responses"] ): - subschema_count = len( - openapi_spec.openapi()["paths"][endpoint][method.lower()]["responses"][status_code][ + if ( + "oneOf" + in openapi_spec.openapi()["paths"][endpoint][method.lower()]["responses"][status_code][ "content" - ]["application/json"]["schema"]["oneOf"] - ) - else: - subschema_count = 1 - for subschema_index in range(subschema_count): - if subschema_count != 1: - subschema_status_code = status_code + "_" + str(subschema_index) + ]["application/json"]["schema"] + ): + subschema_count = len( + openapi_spec.openapi()["paths"][endpoint][method.lower()]["responses"][status_code][ + "content" + ]["application/json"]["schema"]["oneOf"] + ) else: - subschema_status_code = status_code - fixture_dict = get_openapi_fixture(endpoint, method, subschema_status_code) - fixture_description = ( - get_openapi_fixture_description(endpoint, method, subschema_status_code).strip() + ":" - ) - fixture_json = json.dumps(fixture_dict, indent=4, sort_keys=True, separators=(",", ": ")) + subschema_count = 1 + for subschema_index in range(subschema_count): + if subschema_count != 1: + subschema_status_code = status_code + "_" + str(subschema_index) + else: + subschema_status_code = status_code + fixture_dict = get_openapi_fixture(endpoint, method, subschema_status_code) + fixture_description = ( + get_openapi_fixture_description(endpoint, method, subschema_status_code).strip() + + ":" + ) + fixture_json = json.dumps( + fixture_dict, indent=4, sort_keys=True, separators=(",", ": ") + ) - fixture.extend(fixture_description.splitlines()) - fixture.append("``` json") - fixture.extend(fixture_json.splitlines()) - fixture.append("```") + fixture.extend(fixture_description.splitlines()) + fixture.append("``` json") + fixture.extend(fixture_json.splitlines()) + fixture.append("```") return fixture