From b99f0068613f4a46974437cfbc537d5e4d712d23 Mon Sep 17 00:00:00 2001 From: geekerzp Date: Tue, 30 Jun 2015 18:38:11 +0800 Subject: [PATCH] Update Python client. Throw ApiException if fail to parse string to datetime. --- .../main/resources/python/api_client.mustache | 23 ++++----- .../src/main/resources/python/rest.mustache | 47 +++++++++---------- .../python/swagger_client/api_client.py | 23 ++++----- .../petstore/python/swagger_client/rest.py | 47 +++++++++---------- .../python/tests/test_api_exception.py | 2 +- 5 files changed, 61 insertions(+), 81 deletions(-) diff --git a/modules/swagger-codegen/src/main/resources/python/api_client.mustache b/modules/swagger-codegen/src/main/resources/python/api_client.mustache index e0c1a8ca556f..761a034e1890 100644 --- a/modules/swagger-codegen/src/main/resources/python/api_client.mustache +++ b/modules/swagger-codegen/src/main/resources/python/api_client.mustache @@ -9,6 +9,7 @@ templates.""" from __future__ import absolute_import from . import models from .rest import RESTClient +from .rest import ApiException import os import re @@ -102,7 +103,7 @@ class ApiClient(object): post_params=post_params, body=body) self.last_response = response_data - + # deserialize response data if response_type: return self.deserialize(response_data, response_type) @@ -278,7 +279,7 @@ class ApiClient(object): """ if not auth_settings: return - + for auth in auth_settings: auth_setting = configuration.auth_settings().get(auth) if auth_setting: @@ -294,13 +295,13 @@ class ApiClient(object): Save response body into a file in (the defined) temporary folder, using the filename from the `Content-Disposition` header if provided, otherwise a random filename. - :param response: RESTResponse - :return: file path + :param response: RESTResponse + :return: file path """ fd, path = tempfile.mkstemp(dir=configuration.temp_folder_path) os.close(fd) os.remove(path) - + content_disposition = response.getheader("Content-Disposition") if content_disposition: filename = re.search(r'filename=[\'"]?([^\'"\s]+)[\'"]?', content_disposition).group(1) @@ -314,7 +315,7 @@ class ApiClient(object): def __deserialize_primitive(self, data, klass): """ Deserialize string to primitive type - + :param data: str :param klass: class literal @@ -348,6 +349,8 @@ class ApiClient(object): return parse(string) except ImportError: return string + except ValueError: + raise ApiException(status=0, reason="Failed to parse `{0}` into a datetime object".format(string)) def __deserialize_model(self, data, klass): """ @@ -378,11 +381,3 @@ class ApiClient(object): setattr(instance, attr, self.__deserialize(value, attr_type)) return instance - - - - - - - - diff --git a/modules/swagger-codegen/src/main/resources/python/rest.mustache b/modules/swagger-codegen/src/main/resources/python/rest.mustache index 1d21402606e4..25cf702766e9 100644 --- a/modules/swagger-codegen/src/main/resources/python/rest.mustache +++ b/modules/swagger-codegen/src/main/resources/python/rest.mustache @@ -131,7 +131,7 @@ class RESTClientObject(object): r.data = r.data.decode('utf8') if r.status not in range(200, 206): - raise ApiException(r) + raise ApiException(http_resp=r) return r @@ -155,37 +155,32 @@ class RESTClientObject(object): class ApiException(Exception): - """ - Non-2xx HTTP response - """ - def __init__(self, http_resp): - self.status = http_resp.status - self.reason = http_resp.reason - self.body = http_resp.data - self.headers = http_resp.getheaders() - - # In the python 3, the self.body is bytes. - # we need to decode it to string. - if sys.version_info > (3,): - data = self.body.decode('utf8') + def __init__(self, status=None, reason=None, http_resp=None): + if http_resp: + self.status = http_resp.status + self.reason = http_resp.reason + self.body = http_resp.data + self.headers = http_resp.getheaders() else: - data = self.body - - try: - self.body = json.loads(data) - except ValueError: - self.body = data + self.status = status + self.reason = reason + self.body = None + self.headers = None def __str__(self): """ - Custom error response messages + Custom error messages for exception """ - return "({0})\n"\ - "Reason: {1}\n"\ - "HTTP response headers: {2}\n"\ - "HTTP response body: {3}\n".\ - format(self.status, self.reason, self.headers, self.body) + error_message = "({0})\n"\ + "Reason: {1}\n".format(self.status, self.reason) + if self.headers: + error_message += "HTTP response headers: {0}".format(self.headers) + + if self.body: + error_message += "HTTP response body: {0}".format(self.body) + + return error_message class RESTClient(object): """ diff --git a/samples/client/petstore/python/swagger_client/api_client.py b/samples/client/petstore/python/swagger_client/api_client.py index e0c1a8ca556f..761a034e1890 100644 --- a/samples/client/petstore/python/swagger_client/api_client.py +++ b/samples/client/petstore/python/swagger_client/api_client.py @@ -9,6 +9,7 @@ templates.""" from __future__ import absolute_import from . import models from .rest import RESTClient +from .rest import ApiException import os import re @@ -102,7 +103,7 @@ class ApiClient(object): post_params=post_params, body=body) self.last_response = response_data - + # deserialize response data if response_type: return self.deserialize(response_data, response_type) @@ -278,7 +279,7 @@ class ApiClient(object): """ if not auth_settings: return - + for auth in auth_settings: auth_setting = configuration.auth_settings().get(auth) if auth_setting: @@ -294,13 +295,13 @@ class ApiClient(object): Save response body into a file in (the defined) temporary folder, using the filename from the `Content-Disposition` header if provided, otherwise a random filename. - :param response: RESTResponse - :return: file path + :param response: RESTResponse + :return: file path """ fd, path = tempfile.mkstemp(dir=configuration.temp_folder_path) os.close(fd) os.remove(path) - + content_disposition = response.getheader("Content-Disposition") if content_disposition: filename = re.search(r'filename=[\'"]?([^\'"\s]+)[\'"]?', content_disposition).group(1) @@ -314,7 +315,7 @@ class ApiClient(object): def __deserialize_primitive(self, data, klass): """ Deserialize string to primitive type - + :param data: str :param klass: class literal @@ -348,6 +349,8 @@ class ApiClient(object): return parse(string) except ImportError: return string + except ValueError: + raise ApiException(status=0, reason="Failed to parse `{0}` into a datetime object".format(string)) def __deserialize_model(self, data, klass): """ @@ -378,11 +381,3 @@ class ApiClient(object): setattr(instance, attr, self.__deserialize(value, attr_type)) return instance - - - - - - - - diff --git a/samples/client/petstore/python/swagger_client/rest.py b/samples/client/petstore/python/swagger_client/rest.py index 1d21402606e4..25cf702766e9 100644 --- a/samples/client/petstore/python/swagger_client/rest.py +++ b/samples/client/petstore/python/swagger_client/rest.py @@ -131,7 +131,7 @@ class RESTClientObject(object): r.data = r.data.decode('utf8') if r.status not in range(200, 206): - raise ApiException(r) + raise ApiException(http_resp=r) return r @@ -155,37 +155,32 @@ class RESTClientObject(object): class ApiException(Exception): - """ - Non-2xx HTTP response - """ - def __init__(self, http_resp): - self.status = http_resp.status - self.reason = http_resp.reason - self.body = http_resp.data - self.headers = http_resp.getheaders() - - # In the python 3, the self.body is bytes. - # we need to decode it to string. - if sys.version_info > (3,): - data = self.body.decode('utf8') + def __init__(self, status=None, reason=None, http_resp=None): + if http_resp: + self.status = http_resp.status + self.reason = http_resp.reason + self.body = http_resp.data + self.headers = http_resp.getheaders() else: - data = self.body - - try: - self.body = json.loads(data) - except ValueError: - self.body = data + self.status = status + self.reason = reason + self.body = None + self.headers = None def __str__(self): """ - Custom error response messages + Custom error messages for exception """ - return "({0})\n"\ - "Reason: {1}\n"\ - "HTTP response headers: {2}\n"\ - "HTTP response body: {3}\n".\ - format(self.status, self.reason, self.headers, self.body) + error_message = "({0})\n"\ + "Reason: {1}\n".format(self.status, self.reason) + if self.headers: + error_message += "HTTP response headers: {0}".format(self.headers) + + if self.body: + error_message += "HTTP response body: {0}".format(self.body) + + return error_message class RESTClient(object): """ diff --git a/samples/client/petstore/python/tests/test_api_exception.py b/samples/client/petstore/python/tests/test_api_exception.py index f3d00cb10dc6..a60594b3edd8 100644 --- a/samples/client/petstore/python/tests/test_api_exception.py +++ b/samples/client/petstore/python/tests/test_api_exception.py @@ -52,7 +52,7 @@ class ApiExceptionTests(unittest.TestCase): except ApiException as e: self.assertEqual(e.status, 404) self.assertEqual(e.reason, "Not Found") - self.assertDictEqual(e.body, {'message': 'Pet not found', 'code': 1, 'type': 'error'}) + self.assertRegexpMatches(e.body, "Pet not found") def test_500_error(self): self.pet_api.add_pet(body=self.pet)