From 8b9645cf2dcef289101d55121d9f5236324b33f6 Mon Sep 17 00:00:00 2001 From: icleary Date: Wed, 20 Feb 2019 22:04:58 -0700 Subject: [PATCH 1/5] implemented rest of OpenAPI Info Object --- responder/api.py | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/responder/api.py b/responder/api.py index 59bce2d..49f23c6 100644 --- a/responder/api.py +++ b/responder/api.py @@ -46,6 +46,18 @@ class API: :param templates_dir: The directory to use for templates. Will be created for you if it doesn't already exist. :param auto_escape: If ``True``, HTML and XML templates will automatically be escaped. :param enable_hsts: If ``True``, send all responses to HTTPS URLs. + :param title->str: The title of the application (OpenAPI Info Object) + :param version->str: The version of the OpenAPI document (OpenAPI Info Object) + :param contact->dict: The contact dictionary of the application (OpenAPI Contact Object) + e.g. { + "name": "API Support", + "url": "http://www.example.com/support", + "email": "support@example.com" + } + :param license->dict: The license information of the exposed API (OpenAPI License Object) + e.g. {"name": "Apache 2.0", + "url": "https://www.apache.org/licenses/LICENSE-2.0.html"} + :param termsOfService->str: A URL to the Terms of Service for the API (OpenAPI Info Object) """ status_codes = status_codes @@ -56,6 +68,10 @@ class API: debug=False, title=None, version=None, + contact=None, + license=None, + description=None, + termsOfService=None, openapi=None, openapi_route="/schema.yml", static_dir="static", @@ -74,6 +90,10 @@ class API: self.secret_key = secret_key self.title = title self.version = version + self.contact = contact + self.license = license + self.description = description + self.termsOfService = termsOfService self.openapi_version = openapi self.static_dir = Path(os.path.abspath(static_dir)) self.static_route = f"/{static_route.strip('/')}" @@ -175,11 +195,23 @@ class API: @property def _apispec(self): + + info = {} + if self.contact: + info["contact"] = self.contact + if self.license: + info["license"] = self.license + if self.description: + info["description"] = self.description + if self.termsOfService: + info["termsOfService"] = self.termsOfService + spec = APISpec( title=self.title, version=self.version, openapi_version=self.openapi_version, plugins=[MarshmallowPlugin()], + info=info ) for route in self.routes: From d2ec3238880a7f7d83afd5e102f5e89f91c41f4b Mon Sep 17 00:00:00 2001 From: icleary Date: Wed, 20 Feb 2019 22:29:49 -0700 Subject: [PATCH 2/5] edited docstring to remove ->type --- responder/api.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/responder/api.py b/responder/api.py index 49f23c6..62926eb 100644 --- a/responder/api.py +++ b/responder/api.py @@ -46,18 +46,18 @@ class API: :param templates_dir: The directory to use for templates. Will be created for you if it doesn't already exist. :param auto_escape: If ``True``, HTML and XML templates will automatically be escaped. :param enable_hsts: If ``True``, send all responses to HTTPS URLs. - :param title->str: The title of the application (OpenAPI Info Object) - :param version->str: The version of the OpenAPI document (OpenAPI Info Object) - :param contact->dict: The contact dictionary of the application (OpenAPI Contact Object) + :param title: The title of the application (OpenAPI Info Object) + :param version: The version of the OpenAPI document (OpenAPI Info Object) + :param contact: The contact dictionary of the application (OpenAPI Contact Object) e.g. { "name": "API Support", "url": "http://www.example.com/support", "email": "support@example.com" } - :param license->dict: The license information of the exposed API (OpenAPI License Object) + :param license: The license information of the exposed API (OpenAPI License Object) e.g. {"name": "Apache 2.0", "url": "https://www.apache.org/licenses/LICENSE-2.0.html"} - :param termsOfService->str: A URL to the Terms of Service for the API (OpenAPI Info Object) + :param termsOfService: A URL to the Terms of Service for the API (OpenAPI Info Object) """ status_codes = status_codes From 6e5b3a4bf9567dadbaf05e2753e65f9c650415f7 Mon Sep 17 00:00:00 2001 From: icleary Date: Wed, 20 Feb 2019 22:38:57 -0700 Subject: [PATCH 3/5] ran black on changed file --- responder/api.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/responder/api.py b/responder/api.py index 62926eb..54465af 100644 --- a/responder/api.py +++ b/responder/api.py @@ -211,7 +211,7 @@ class API: version=self.version, openapi_version=self.openapi_version, plugins=[MarshmallowPlugin()], - info=info + info=info, ) for route in self.routes: From 9f2182949d271e7fac1f684dd4522ea0902fce34 Mon Sep 17 00:00:00 2001 From: icleary Date: Thu, 21 Feb 2019 08:35:53 -0700 Subject: [PATCH 4/5] snake case for terms_of_service, is not None for if statements --- responder/api.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/responder/api.py b/responder/api.py index 54465af..9388105 100644 --- a/responder/api.py +++ b/responder/api.py @@ -57,7 +57,7 @@ class API: :param license: The license information of the exposed API (OpenAPI License Object) e.g. {"name": "Apache 2.0", "url": "https://www.apache.org/licenses/LICENSE-2.0.html"} - :param termsOfService: A URL to the Terms of Service for the API (OpenAPI Info Object) + :param terms_of_service: A URL to the Terms of Service for the API (OpenAPI Info Object) """ status_codes = status_codes @@ -71,7 +71,7 @@ class API: contact=None, license=None, description=None, - termsOfService=None, + terms_of_service=None, openapi=None, openapi_route="/schema.yml", static_dir="static", @@ -93,7 +93,7 @@ class API: self.contact = contact self.license = license self.description = description - self.termsOfService = termsOfService + self.terms_of_service = terms_of_service self.openapi_version = openapi self.static_dir = Path(os.path.abspath(static_dir)) self.static_route = f"/{static_route.strip('/')}" @@ -197,14 +197,14 @@ class API: def _apispec(self): info = {} - if self.contact: + if self.contact is not None: info["contact"] = self.contact - if self.license: + if self.license is not None: info["license"] = self.license - if self.description: + if self.description is not None: info["description"] = self.description - if self.termsOfService: - info["termsOfService"] = self.termsOfService + if self.terms_of_service is not None: + info["termsOfService"] = self.terms_of_service spec = APISpec( title=self.title, From 00309936319e62b3b6be02deda2b36fdfd6b40a3 Mon Sep 17 00:00:00 2001 From: icleary Date: Thu, 21 Feb 2019 18:35:19 -0700 Subject: [PATCH 5/5] api OpenAPI params match /docs display order, updated tour docs and docs test --- docs/source/tour.rst | 23 ++++++++++++++++++++++- responder/api.py | 28 +++++++++++----------------- tests/test_responder.py | 23 ++++++++++++++++++++--- 3 files changed, 53 insertions(+), 21 deletions(-) diff --git a/docs/source/tour.rst b/docs/source/tour.rst index 051a007..475c1c5 100644 --- a/docs/source/tour.rst +++ b/docs/source/tour.rst @@ -63,7 +63,28 @@ Responder comes with built-in support for OpenAPI / marshmallow:: import responder from marshmallow import Schema, fields - api = responder.API(title="Web Service", version="1.0", openapi="3.0.0") + description = "This is a sample server for a pet store." + terms_of_service = "http://example.com/terms/" + contact = { + "name": "API Support", + "url": "http://www.example.com/support", + "email": "support@example.com", + } + license = { + "name": "Apache 2.0", + "url": "https://www.apache.org/licenses/LICENSE-2.0.html", + } + + api = responder.API( + title="Web Service", + version="1.0", + openapi="3.0.2", + docs_route='/docs', + description=description, + terms_of_service=terms_of_service, + contact=contact, + license=license, + ) @api.schema("Pet") diff --git a/responder/api.py b/responder/api.py index 9388105..926379b 100644 --- a/responder/api.py +++ b/responder/api.py @@ -48,16 +48,10 @@ class API: :param enable_hsts: If ``True``, send all responses to HTTPS URLs. :param title: The title of the application (OpenAPI Info Object) :param version: The version of the OpenAPI document (OpenAPI Info Object) - :param contact: The contact dictionary of the application (OpenAPI Contact Object) - e.g. { - "name": "API Support", - "url": "http://www.example.com/support", - "email": "support@example.com" - } - :param license: The license information of the exposed API (OpenAPI License Object) - e.g. {"name": "Apache 2.0", - "url": "https://www.apache.org/licenses/LICENSE-2.0.html"} + :param description: The description of the OpenAPI document (OpenAPI Info Object) :param terms_of_service: A URL to the Terms of Service for the API (OpenAPI Info Object) + :param contact: The contact dictionary of the application (OpenAPI Contact Object) + :param license: The license information of the exposed API (OpenAPI License Object) """ status_codes = status_codes @@ -68,10 +62,10 @@ class API: debug=False, title=None, version=None, - contact=None, - license=None, description=None, terms_of_service=None, + contact=None, + license=None, openapi=None, openapi_route="/schema.yml", static_dir="static", @@ -90,10 +84,10 @@ class API: self.secret_key = secret_key self.title = title self.version = version - self.contact = contact - self.license = license self.description = description self.terms_of_service = terms_of_service + self.contact = contact + self.license = license self.openapi_version = openapi self.static_dir = Path(os.path.abspath(static_dir)) self.static_route = f"/{static_route.strip('/')}" @@ -197,14 +191,14 @@ class API: def _apispec(self): info = {} - if self.contact is not None: - info["contact"] = self.contact - if self.license is not None: - info["license"] = self.license if self.description is not None: info["description"] = self.description if self.terms_of_service is not None: info["termsOfService"] = self.terms_of_service + if self.contact is not None: + info["contact"] = self.contact + if self.license is not None: + info["license"] = self.license spec = APISpec( title=self.title, diff --git a/tests/test_responder.py b/tests/test_responder.py index 7048d1b..1cb29c0 100644 --- a/tests/test_responder.py +++ b/tests/test_responder.py @@ -336,7 +336,7 @@ def test_schema_generation(): from marshmallow import Schema, fields api = responder.API( - title="Web Service", openapi="3.0", allowed_hosts=["testserver", ";"] + title="Web Service", openapi="3.0.2", allowed_hosts=["testserver", ";"] ) @api.schema("Pet") @@ -361,17 +361,34 @@ def test_schema_generation(): dump = yaml.safe_load(r.content) assert dump - assert dump["openapi"] == "3.0" + assert dump["openapi"] == "3.0.2" def test_documentation(): import responder from marshmallow import Schema, fields + description = "This is a sample server for a pet store." + terms_of_service = "http://example.com/terms/" + contact = { + "name": "API Support", + "url": "http://www.example.com/support", + "email": "support@example.com", + } + license = { + "name": "Apache 2.0", + "url": "https://www.apache.org/licenses/LICENSE-2.0.html", + } + api = responder.API( title="Web Service", - openapi="3.0", + version="1.0", + openapi="3.0.2", docs_route="/docs", + description=description, + terms_of_service=terms_of_service, + contact=contact, + license=license, allowed_hosts=["testserver", ";"], )