From 33d3954f4fff31a153ad8da3c1f6959b86cb46bf Mon Sep 17 00:00:00 2001
From: Ryan Rishi <ryan@ryanrishi.com>
Date: Mon, 31 Aug 2020 12:40:26 -0600
Subject: [PATCH 1/4] Subclass Python exceptions: - UnauthorizedException (401)
 - ForbiddenException (403) - NotFoundException (404) - ServiceException [500
 - 599]

Fixes #2151
---
 .../main/resources/python/exceptions.mustache | 24 +++++++++++++++++++
 .../src/main/resources/python/rest.mustache   | 14 ++++++++++-
 2 files changed, 37 insertions(+), 1 deletion(-)

diff --git a/modules/openapi-generator/src/main/resources/python/exceptions.mustache b/modules/openapi-generator/src/main/resources/python/exceptions.mustache
index b187ee9d47e..0faaeca87b9 100644
--- a/modules/openapi-generator/src/main/resources/python/exceptions.mustache
+++ b/modules/openapi-generator/src/main/resources/python/exceptions.mustache
@@ -120,6 +120,30 @@ class ApiException(OpenApiException):
         return error_message
 
 
+class NotFoundException(ApiException):
+
+    def __init__(self, status=None, reason=None, http_resp=None):
+        super().__init__(status, reason, http_resp)
+
+
+class UnauthorizedException(ApiException):
+
+    def __init__(self, status=None, reason=None, http_resp=None):
+        super().__init__(status, reason, http_resp)
+
+
+class ForbiddenException(ApiException):
+
+    def __init__(self, status=None, reason=None, http_resp=None):
+        super().__init__(status, reason, http_resp)
+
+
+class ServiceException(ApiException):
+
+    def __init__(self, status=None, reason=None, http_resp=None):
+        super().__init__(status, reason, http_resp)
+
+
 def render_path(path_to_item):
     """Returns a string representation of a path"""
     result = ""
diff --git a/modules/openapi-generator/src/main/resources/python/rest.mustache b/modules/openapi-generator/src/main/resources/python/rest.mustache
index 51f72f6e1ff..05b46dadc16 100644
--- a/modules/openapi-generator/src/main/resources/python/rest.mustache
+++ b/modules/openapi-generator/src/main/resources/python/rest.mustache
@@ -16,7 +16,7 @@ import six
 from six.moves.urllib.parse import urlencode
 import urllib3
 
-from {{packageName}}.exceptions import ApiException, ApiValueError
+from {{packageName}}.exceptions import ApiException, UnauthorizedException, ForbiddenException, NotFoundException, ServiceException, ApiValueError
 
 
 logger = logging.getLogger(__name__)
@@ -213,6 +213,18 @@ class RESTClientObject(object):
             logger.debug("response body: %s", r.data)
 
         if not 200 <= r.status <= 299:
+            if r.status == 401:
+                raise UnauthorizedException(http_resp=r)
+
+            if r.status == 403:
+                raise ForbiddenException(http_resp=r)
+
+            if r.status == 404:
+                raise NotFoundException(http_resp=r)
+
+            if 500 <= r.status <= 599:
+                raise ServiceException(http_resp=r)
+
             raise ApiException(http_resp=r)
 
         return r
-- 
GitLab


From 52e07e1b81219a6e74d870e05676b0de1a0ad45e Mon Sep 17 00:00:00 2001
From: Ryan Rishi <ryan@ryanrishi.com>
Date: Mon, 31 Aug 2020 13:17:28 -0600
Subject: [PATCH 2/4] add generated sample code

---
 .../python-asyncio/petstore_api/exceptions.py | 24 +++++++++++++++++++
 .../python-tornado/petstore_api/exceptions.py | 24 +++++++++++++++++++
 .../python/petstore_api/exceptions.py         | 24 +++++++++++++++++++
 .../petstore/python/petstore_api/rest.py      | 14 ++++++++++-
 .../python/petstore_api/exceptions.py         | 24 +++++++++++++++++++
 .../petstore/python/petstore_api/rest.py      | 14 ++++++++++-
 6 files changed, 122 insertions(+), 2 deletions(-)

diff --git a/samples/client/petstore/python-asyncio/petstore_api/exceptions.py b/samples/client/petstore/python-asyncio/petstore_api/exceptions.py
index b55977ee5e7..7325acbec07 100644
--- a/samples/client/petstore/python-asyncio/petstore_api/exceptions.py
+++ b/samples/client/petstore/python-asyncio/petstore_api/exceptions.py
@@ -128,6 +128,30 @@ class ApiException(OpenApiException):
         return error_message
 
 
+class NotFoundException(ApiException):
+
+    def __init__(self, status=None, reason=None, http_resp=None):
+        super().__init__(status, reason, http_resp)
+
+
+class UnauthorizedException(ApiException):
+
+    def __init__(self, status=None, reason=None, http_resp=None):
+        super().__init__(status, reason, http_resp)
+
+
+class ForbiddenException(ApiException):
+
+    def __init__(self, status=None, reason=None, http_resp=None):
+        super().__init__(status, reason, http_resp)
+
+
+class ServiceException(ApiException):
+
+    def __init__(self, status=None, reason=None, http_resp=None):
+        super().__init__(status, reason, http_resp)
+
+
 def render_path(path_to_item):
     """Returns a string representation of a path"""
     result = ""
diff --git a/samples/client/petstore/python-tornado/petstore_api/exceptions.py b/samples/client/petstore/python-tornado/petstore_api/exceptions.py
index b55977ee5e7..7325acbec07 100644
--- a/samples/client/petstore/python-tornado/petstore_api/exceptions.py
+++ b/samples/client/petstore/python-tornado/petstore_api/exceptions.py
@@ -128,6 +128,30 @@ class ApiException(OpenApiException):
         return error_message
 
 
+class NotFoundException(ApiException):
+
+    def __init__(self, status=None, reason=None, http_resp=None):
+        super().__init__(status, reason, http_resp)
+
+
+class UnauthorizedException(ApiException):
+
+    def __init__(self, status=None, reason=None, http_resp=None):
+        super().__init__(status, reason, http_resp)
+
+
+class ForbiddenException(ApiException):
+
+    def __init__(self, status=None, reason=None, http_resp=None):
+        super().__init__(status, reason, http_resp)
+
+
+class ServiceException(ApiException):
+
+    def __init__(self, status=None, reason=None, http_resp=None):
+        super().__init__(status, reason, http_resp)
+
+
 def render_path(path_to_item):
     """Returns a string representation of a path"""
     result = ""
diff --git a/samples/client/petstore/python/petstore_api/exceptions.py b/samples/client/petstore/python/petstore_api/exceptions.py
index b55977ee5e7..7325acbec07 100644
--- a/samples/client/petstore/python/petstore_api/exceptions.py
+++ b/samples/client/petstore/python/petstore_api/exceptions.py
@@ -128,6 +128,30 @@ class ApiException(OpenApiException):
         return error_message
 
 
+class NotFoundException(ApiException):
+
+    def __init__(self, status=None, reason=None, http_resp=None):
+        super().__init__(status, reason, http_resp)
+
+
+class UnauthorizedException(ApiException):
+
+    def __init__(self, status=None, reason=None, http_resp=None):
+        super().__init__(status, reason, http_resp)
+
+
+class ForbiddenException(ApiException):
+
+    def __init__(self, status=None, reason=None, http_resp=None):
+        super().__init__(status, reason, http_resp)
+
+
+class ServiceException(ApiException):
+
+    def __init__(self, status=None, reason=None, http_resp=None):
+        super().__init__(status, reason, http_resp)
+
+
 def render_path(path_to_item):
     """Returns a string representation of a path"""
     result = ""
diff --git a/samples/client/petstore/python/petstore_api/rest.py b/samples/client/petstore/python/petstore_api/rest.py
index 9dfb1ffefd5..9cbcd62db56 100644
--- a/samples/client/petstore/python/petstore_api/rest.py
+++ b/samples/client/petstore/python/petstore_api/rest.py
@@ -24,7 +24,7 @@ import six
 from six.moves.urllib.parse import urlencode
 import urllib3
 
-from petstore_api.exceptions import ApiException, ApiValueError
+from petstore_api.exceptions import ApiException, UnauthorizedException, ForbiddenException, NotFoundException, ServiceException, ApiValueError
 
 
 logger = logging.getLogger(__name__)
@@ -221,6 +221,18 @@ class RESTClientObject(object):
             logger.debug("response body: %s", r.data)
 
         if not 200 <= r.status <= 299:
+            if r.status == 401:
+                raise UnauthorizedException(http_resp=r)
+
+            if r.status == 403:
+                raise ForbiddenException(http_resp=r)
+
+            if r.status == 404:
+                raise NotFoundException(http_resp=r)
+
+            if 500 <= r.status <= 599:
+                raise ServiceException(http_resp=r)
+
             raise ApiException(http_resp=r)
 
         return r
diff --git a/samples/openapi3/client/petstore/python/petstore_api/exceptions.py b/samples/openapi3/client/petstore/python/petstore_api/exceptions.py
index b55977ee5e7..7325acbec07 100644
--- a/samples/openapi3/client/petstore/python/petstore_api/exceptions.py
+++ b/samples/openapi3/client/petstore/python/petstore_api/exceptions.py
@@ -128,6 +128,30 @@ class ApiException(OpenApiException):
         return error_message
 
 
+class NotFoundException(ApiException):
+
+    def __init__(self, status=None, reason=None, http_resp=None):
+        super().__init__(status, reason, http_resp)
+
+
+class UnauthorizedException(ApiException):
+
+    def __init__(self, status=None, reason=None, http_resp=None):
+        super().__init__(status, reason, http_resp)
+
+
+class ForbiddenException(ApiException):
+
+    def __init__(self, status=None, reason=None, http_resp=None):
+        super().__init__(status, reason, http_resp)
+
+
+class ServiceException(ApiException):
+
+    def __init__(self, status=None, reason=None, http_resp=None):
+        super().__init__(status, reason, http_resp)
+
+
 def render_path(path_to_item):
     """Returns a string representation of a path"""
     result = ""
diff --git a/samples/openapi3/client/petstore/python/petstore_api/rest.py b/samples/openapi3/client/petstore/python/petstore_api/rest.py
index 9dfb1ffefd5..9cbcd62db56 100644
--- a/samples/openapi3/client/petstore/python/petstore_api/rest.py
+++ b/samples/openapi3/client/petstore/python/petstore_api/rest.py
@@ -24,7 +24,7 @@ import six
 from six.moves.urllib.parse import urlencode
 import urllib3
 
-from petstore_api.exceptions import ApiException, ApiValueError
+from petstore_api.exceptions import ApiException, UnauthorizedException, ForbiddenException, NotFoundException, ServiceException, ApiValueError
 
 
 logger = logging.getLogger(__name__)
@@ -221,6 +221,18 @@ class RESTClientObject(object):
             logger.debug("response body: %s", r.data)
 
         if not 200 <= r.status <= 299:
+            if r.status == 401:
+                raise UnauthorizedException(http_resp=r)
+
+            if r.status == 403:
+                raise ForbiddenException(http_resp=r)
+
+            if r.status == 404:
+                raise NotFoundException(http_resp=r)
+
+            if 500 <= r.status <= 599:
+                raise ServiceException(http_resp=r)
+
             raise ApiException(http_resp=r)
 
         return r
-- 
GitLab


From c5b824c3f693755fbaa541c285a44bcf89d900d4 Mon Sep 17 00:00:00 2001
From: Ryan Rishi <ryan@ryanrishi.com>
Date: Mon, 31 Aug 2020 14:59:40 -0600
Subject: [PATCH 3/4] use Python 2 flavor inheritance

---
 .../src/main/resources/python/exceptions.mustache         | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/modules/openapi-generator/src/main/resources/python/exceptions.mustache b/modules/openapi-generator/src/main/resources/python/exceptions.mustache
index 0faaeca87b9..6c772695330 100644
--- a/modules/openapi-generator/src/main/resources/python/exceptions.mustache
+++ b/modules/openapi-generator/src/main/resources/python/exceptions.mustache
@@ -123,25 +123,25 @@ class ApiException(OpenApiException):
 class NotFoundException(ApiException):
 
     def __init__(self, status=None, reason=None, http_resp=None):
-        super().__init__(status, reason, http_resp)
+        super(NotFoundException, self).__init__(status, reason, http_resp)
 
 
 class UnauthorizedException(ApiException):
 
     def __init__(self, status=None, reason=None, http_resp=None):
-        super().__init__(status, reason, http_resp)
+        super(UnauthorizedException, self).__init__(status, reason, http_resp)
 
 
 class ForbiddenException(ApiException):
 
     def __init__(self, status=None, reason=None, http_resp=None):
-        super().__init__(status, reason, http_resp)
+        super(ForbiddenException, self).__init__(status, reason, http_resp)
 
 
 class ServiceException(ApiException):
 
     def __init__(self, status=None, reason=None, http_resp=None):
-        super().__init__(status, reason, http_resp)
+        super(ServiceException, self).__init__(status, reason, http_resp)
 
 
 def render_path(path_to_item):
-- 
GitLab


From 44fa98d5f0a7ee866bfcf13de3110c77ce88dda6 Mon Sep 17 00:00:00 2001
From: Ryan Rishi <ryan@ryanrishi.com>
Date: Mon, 31 Aug 2020 15:00:03 -0600
Subject: [PATCH 4/4] regenerate samples

---
 .../petstore/python-asyncio/petstore_api/exceptions.py    | 8 ++++----
 .../petstore/python-tornado/petstore_api/exceptions.py    | 8 ++++----
 samples/client/petstore/python/petstore_api/exceptions.py | 8 ++++----
 .../client/petstore/python/petstore_api/exceptions.py     | 8 ++++----
 4 files changed, 16 insertions(+), 16 deletions(-)

diff --git a/samples/client/petstore/python-asyncio/petstore_api/exceptions.py b/samples/client/petstore/python-asyncio/petstore_api/exceptions.py
index 7325acbec07..08181d4775d 100644
--- a/samples/client/petstore/python-asyncio/petstore_api/exceptions.py
+++ b/samples/client/petstore/python-asyncio/petstore_api/exceptions.py
@@ -131,25 +131,25 @@ class ApiException(OpenApiException):
 class NotFoundException(ApiException):
 
     def __init__(self, status=None, reason=None, http_resp=None):
-        super().__init__(status, reason, http_resp)
+        super(NotFoundException, self).__init__(status, reason, http_resp)
 
 
 class UnauthorizedException(ApiException):
 
     def __init__(self, status=None, reason=None, http_resp=None):
-        super().__init__(status, reason, http_resp)
+        super(UnauthorizedException, self).__init__(status, reason, http_resp)
 
 
 class ForbiddenException(ApiException):
 
     def __init__(self, status=None, reason=None, http_resp=None):
-        super().__init__(status, reason, http_resp)
+        super(ForbiddenException, self).__init__(status, reason, http_resp)
 
 
 class ServiceException(ApiException):
 
     def __init__(self, status=None, reason=None, http_resp=None):
-        super().__init__(status, reason, http_resp)
+        super(ServiceException, self).__init__(status, reason, http_resp)
 
 
 def render_path(path_to_item):
diff --git a/samples/client/petstore/python-tornado/petstore_api/exceptions.py b/samples/client/petstore/python-tornado/petstore_api/exceptions.py
index 7325acbec07..08181d4775d 100644
--- a/samples/client/petstore/python-tornado/petstore_api/exceptions.py
+++ b/samples/client/petstore/python-tornado/petstore_api/exceptions.py
@@ -131,25 +131,25 @@ class ApiException(OpenApiException):
 class NotFoundException(ApiException):
 
     def __init__(self, status=None, reason=None, http_resp=None):
-        super().__init__(status, reason, http_resp)
+        super(NotFoundException, self).__init__(status, reason, http_resp)
 
 
 class UnauthorizedException(ApiException):
 
     def __init__(self, status=None, reason=None, http_resp=None):
-        super().__init__(status, reason, http_resp)
+        super(UnauthorizedException, self).__init__(status, reason, http_resp)
 
 
 class ForbiddenException(ApiException):
 
     def __init__(self, status=None, reason=None, http_resp=None):
-        super().__init__(status, reason, http_resp)
+        super(ForbiddenException, self).__init__(status, reason, http_resp)
 
 
 class ServiceException(ApiException):
 
     def __init__(self, status=None, reason=None, http_resp=None):
-        super().__init__(status, reason, http_resp)
+        super(ServiceException, self).__init__(status, reason, http_resp)
 
 
 def render_path(path_to_item):
diff --git a/samples/client/petstore/python/petstore_api/exceptions.py b/samples/client/petstore/python/petstore_api/exceptions.py
index 7325acbec07..08181d4775d 100644
--- a/samples/client/petstore/python/petstore_api/exceptions.py
+++ b/samples/client/petstore/python/petstore_api/exceptions.py
@@ -131,25 +131,25 @@ class ApiException(OpenApiException):
 class NotFoundException(ApiException):
 
     def __init__(self, status=None, reason=None, http_resp=None):
-        super().__init__(status, reason, http_resp)
+        super(NotFoundException, self).__init__(status, reason, http_resp)
 
 
 class UnauthorizedException(ApiException):
 
     def __init__(self, status=None, reason=None, http_resp=None):
-        super().__init__(status, reason, http_resp)
+        super(UnauthorizedException, self).__init__(status, reason, http_resp)
 
 
 class ForbiddenException(ApiException):
 
     def __init__(self, status=None, reason=None, http_resp=None):
-        super().__init__(status, reason, http_resp)
+        super(ForbiddenException, self).__init__(status, reason, http_resp)
 
 
 class ServiceException(ApiException):
 
     def __init__(self, status=None, reason=None, http_resp=None):
-        super().__init__(status, reason, http_resp)
+        super(ServiceException, self).__init__(status, reason, http_resp)
 
 
 def render_path(path_to_item):
diff --git a/samples/openapi3/client/petstore/python/petstore_api/exceptions.py b/samples/openapi3/client/petstore/python/petstore_api/exceptions.py
index 7325acbec07..08181d4775d 100644
--- a/samples/openapi3/client/petstore/python/petstore_api/exceptions.py
+++ b/samples/openapi3/client/petstore/python/petstore_api/exceptions.py
@@ -131,25 +131,25 @@ class ApiException(OpenApiException):
 class NotFoundException(ApiException):
 
     def __init__(self, status=None, reason=None, http_resp=None):
-        super().__init__(status, reason, http_resp)
+        super(NotFoundException, self).__init__(status, reason, http_resp)
 
 
 class UnauthorizedException(ApiException):
 
     def __init__(self, status=None, reason=None, http_resp=None):
-        super().__init__(status, reason, http_resp)
+        super(UnauthorizedException, self).__init__(status, reason, http_resp)
 
 
 class ForbiddenException(ApiException):
 
     def __init__(self, status=None, reason=None, http_resp=None):
-        super().__init__(status, reason, http_resp)
+        super(ForbiddenException, self).__init__(status, reason, http_resp)
 
 
 class ServiceException(ApiException):
 
     def __init__(self, status=None, reason=None, http_resp=None):
-        super().__init__(status, reason, http_resp)
+        super(ServiceException, self).__init__(status, reason, http_resp)
 
 
 def render_path(path_to_item):
-- 
GitLab