From b355cc73816364df381b871a19d74c7216ccd21f Mon Sep 17 00:00:00 2001 From: Roman Truba Date: Sat, 5 Nov 2016 22:10:52 +0300 Subject: [PATCH 01/11] Fixed afnetworking API usage: pinnedCertificates now declared as NSSet, not as NSArray --- .../src/main/resources/objc/ApiClient-body.mustache | 2 +- .../swagger-codegen/src/main/resources/objc/podspec.mustache | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/swagger-codegen/src/main/resources/objc/ApiClient-body.mustache b/modules/swagger-codegen/src/main/resources/objc/ApiClient-body.mustache index 10cb6528d86d..d2acc529b5d6 100644 --- a/modules/swagger-codegen/src/main/resources/objc/ApiClient-body.mustache +++ b/modules/swagger-codegen/src/main/resources/objc/ApiClient-body.mustache @@ -483,7 +483,7 @@ static NSString * {{classPrefix}}__fileNameForResponse(NSURLResponse *response) if (config.sslCaCert) { NSData *certData = [NSData dataWithContentsOfFile:config.sslCaCert]; - [securityPolicy setPinnedCertificates:@[certData]]; + [securityPolicy setPinnedCertificates:[NSSet setWithObject:certData]]; } if (config.verifySSL) { diff --git a/modules/swagger-codegen/src/main/resources/objc/podspec.mustache b/modules/swagger-codegen/src/main/resources/objc/podspec.mustache index bd0bd9f328ee..93b3303ec31f 100644 --- a/modules/swagger-codegen/src/main/resources/objc/podspec.mustache +++ b/modules/swagger-codegen/src/main/resources/objc/podspec.mustache @@ -30,7 +30,7 @@ Pod::Spec.new do |s| s.public_header_files = '{{podName}}/**/*.h' {{#useCoreData}} s.resources = '{{podName}}/**/*.{xcdatamodeld,xcdatamodel}'{{/useCoreData}} - s.dependency 'AFNetworking', '~> 3' + s.dependency 'AFNetworking', '~> 3.1' s.dependency 'JSONModel', '~> 1.2' s.dependency 'ISO8601', '~> 0.5' end From 0c7ab639129a67ab1527a019a373e570d8f7ffa4 Mon Sep 17 00:00:00 2001 From: Roman Truba Date: Sat, 5 Nov 2016 22:11:09 +0300 Subject: [PATCH 02/11] Petstore updated --- samples/client/petstore/objc/default/SwaggerClient.podspec | 2 +- .../petstore/objc/default/SwaggerClient/Core/SWGApiClient.m | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/samples/client/petstore/objc/default/SwaggerClient.podspec b/samples/client/petstore/objc/default/SwaggerClient.podspec index 934e35a2a6b7..bebefdfc4a60 100644 --- a/samples/client/petstore/objc/default/SwaggerClient.podspec +++ b/samples/client/petstore/objc/default/SwaggerClient.podspec @@ -30,7 +30,7 @@ Pod::Spec.new do |s| s.public_header_files = 'SwaggerClient/**/*.h' - s.dependency 'AFNetworking', '~> 3' + s.dependency 'AFNetworking', '~> 3.1' s.dependency 'JSONModel', '~> 1.2' s.dependency 'ISO8601', '~> 0.5' end diff --git a/samples/client/petstore/objc/default/SwaggerClient/Core/SWGApiClient.m b/samples/client/petstore/objc/default/SwaggerClient/Core/SWGApiClient.m index f004200b2eb8..c3c1bc453c4c 100644 --- a/samples/client/petstore/objc/default/SwaggerClient/Core/SWGApiClient.m +++ b/samples/client/petstore/objc/default/SwaggerClient/Core/SWGApiClient.m @@ -483,7 +483,7 @@ static NSString * SWG__fileNameForResponse(NSURLResponse *response) { if (config.sslCaCert) { NSData *certData = [NSData dataWithContentsOfFile:config.sslCaCert]; - [securityPolicy setPinnedCertificates:@[certData]]; + [securityPolicy setPinnedCertificates:[NSSet setWithObject:certData]]; } if (config.verifySSL) { From cfd8add825a80ac5ea264e2ac902fec064763215 Mon Sep 17 00:00:00 2001 From: mbohlool Date: Thu, 10 Nov 2016 14:24:06 -0800 Subject: [PATCH 03/11] Add test for _preload_content flag --- .../petstore/python/tests/test_pet_api.py | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/samples/client/petstore/python/tests/test_pet_api.py b/samples/client/petstore/python/tests/test_pet_api.py index 33c6d86c14a1..a539d2c598f9 100644 --- a/samples/client/petstore/python/tests/test_pet_api.py +++ b/samples/client/petstore/python/tests/test_pet_api.py @@ -45,6 +45,26 @@ class PetApiTests(unittest.TestCase): self.test_file_dir = os.path.realpath(self.test_file_dir) self.foo = os.path.join(self.test_file_dir, "foo.png") + def test_preload_content_flag(self): + self.pet_api.add_pet(body=self.pet) + + resp = self.pet_api.find_pets_by_status(status=[self.pet.status], _preload_content=False) + + # return response should at least have read and close methods. + self.assertTrue(hasattr(resp, 'read')) + self.assertTrue(hasattr(resp, 'close')) + + # Also we need to make sure we can release the connection to a pool (if exists) when we are done with it. + self.assertTrue(hasattr(resp, 'release_conn')) + + # Right now, the client returns urllib3.HTTPResponse. If that changed in future, it is probably a breaking + # change, however supporting above methods should be enough for most usecases. Remove this test case if + # we followed the breaking change procedure for python client (e.g. increasing major version). + self.assertTrue(resp.__class__, 'urllib3.response.HTTPResponse') + + resp.close() + resp.release_conn() + def test_create_api_instance(self): pet_api = petstore_api.PetApi() pet_api2 = petstore_api.PetApi() From f6a02f43393ad239db75de097c592c33a9b636f3 Mon Sep 17 00:00:00 2001 From: Chakrit Wichian Date: Fri, 11 Nov 2016 16:39:45 +0700 Subject: [PATCH 04/11] [ruby] Make sure super is always called for ApiError class. (#4168) * [ruby] Make sure super is always called for ApiError class. * Add test for Petstore::ApiError --- .../src/main/resources/ruby/api_error.mustache | 12 +++++++----- .../petstore/ruby/lib/petstore/api_error.rb | 12 +++++++----- .../client/petstore/ruby/spec/api_error_spec.rb | 15 +++++++++++++++ 3 files changed, 29 insertions(+), 10 deletions(-) create mode 100644 samples/client/petstore/ruby/spec/api_error_spec.rb diff --git a/modules/swagger-codegen/src/main/resources/ruby/api_error.mustache b/modules/swagger-codegen/src/main/resources/ruby/api_error.mustache index ddd8cda32f53..b3320779b36e 100644 --- a/modules/swagger-codegen/src/main/resources/ruby/api_error.mustache +++ b/modules/swagger-codegen/src/main/resources/ruby/api_error.mustache @@ -13,12 +13,14 @@ module {{moduleName}} # ApiError.new(:code => 404, :message => "Not Found") def initialize(arg = nil) if arg.is_a? Hash + if arg.key?(:message) || arg.key?('message') + super(arg[:message] || arg['message']) + else + super arg + end + arg.each do |k, v| - if k.to_s == 'message' - super v - else - instance_variable_set "@#{k}", v - end + instance_variable_set "@#{k}", v end else super arg diff --git a/samples/client/petstore/ruby/lib/petstore/api_error.rb b/samples/client/petstore/ruby/lib/petstore/api_error.rb index aaf331230d36..30b03841f570 100644 --- a/samples/client/petstore/ruby/lib/petstore/api_error.rb +++ b/samples/client/petstore/ruby/lib/petstore/api_error.rb @@ -32,12 +32,14 @@ module Petstore # ApiError.new(:code => 404, :message => "Not Found") def initialize(arg = nil) if arg.is_a? Hash + if arg.key?(:message) || arg.key?('message') + super(arg[:message] || arg['message']) + else + super arg + end + arg.each do |k, v| - if k.to_s == 'message' - super v - else - instance_variable_set "@#{k}", v - end + instance_variable_set "@#{k}", v end else super arg diff --git a/samples/client/petstore/ruby/spec/api_error_spec.rb b/samples/client/petstore/ruby/spec/api_error_spec.rb new file mode 100644 index 000000000000..1ea0ecd68171 --- /dev/null +++ b/samples/client/petstore/ruby/spec/api_error_spec.rb @@ -0,0 +1,15 @@ +require File.dirname(__FILE__) + '/spec_helper' + +describe Petstore::ApiClient do + describe '#initialize' do + it "should save the message if one is given" do + err = Petstore::ApiError.new(message: "Hello") + expect(err.message).to eq("Hello") + end + + it "should save the hash as message if no message is given" do + err = Petstore::ApiError.new(code: 500, response_body: "server error") + expect(err.message).to eq("{:code=>500, :response_body=>\"server error\"}") + end + end +end From 876669cd316c91f9629f08622341ed5c91f945b2 Mon Sep 17 00:00:00 2001 From: mbohlool Date: Fri, 11 Nov 2016 07:48:53 -0800 Subject: [PATCH 05/11] [Python] Add support for request timeout (#4173) * [Python] Add support for request timeout * Update python petstore api * [Python] Add test for request timeout --- .../src/main/resources/python/api.mustache | 2 + .../main/resources/python/api_client.mustache | 29 ++++++++--- .../src/main/resources/python/rest.mustache | 41 ++++++++++++--- .../python/petstore_api/api_client.py | 29 ++++++++--- .../python/petstore_api/apis/fake_api.py | 6 +++ .../python/petstore_api/apis/pet_api.py | 16 ++++++ .../python/petstore_api/apis/store_api.py | 8 +++ .../python/petstore_api/apis/user_api.py | 16 ++++++ .../petstore/python/petstore_api/rest.py | 41 ++++++++++++--- .../petstore/python/tests/test_pet_api.py | 52 +++++++++++++++++++ 10 files changed, 208 insertions(+), 32 deletions(-) diff --git a/modules/swagger-codegen/src/main/resources/python/api.mustache b/modules/swagger-codegen/src/main/resources/python/api.mustache index c6a07b2f7a27..e3c687f7bad0 100644 --- a/modules/swagger-codegen/src/main/resources/python/api.mustache +++ b/modules/swagger-codegen/src/main/resources/python/api.mustache @@ -99,6 +99,7 @@ class {{classname}}(object): all_params.append('callback') all_params.append('_return_http_data_only') all_params.append('_preload_content') + all_params.append('_request_timeout') params = locals() for key, val in iteritems(params['kwargs']): @@ -213,6 +214,7 @@ class {{classname}}(object): callback=params.get('callback'), _return_http_data_only=params.get('_return_http_data_only'), _preload_content=params.get('_preload_content', True), + _request_timeout=params.get('_request_timeout'), collection_formats=collection_formats) {{/operation}} {{/operations}} 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 116467054956..94046a878f53 100644 --- a/modules/swagger-codegen/src/main/resources/python/api_client.mustache +++ b/modules/swagger-codegen/src/main/resources/python/api_client.mustache @@ -96,7 +96,8 @@ class ApiClient(object): path_params=None, query_params=None, header_params=None, body=None, post_params=None, files=None, response_type=None, auth_settings=None, callback=None, - _return_http_data_only=None, collection_formats=None, _preload_content=True): + _return_http_data_only=None, collection_formats=None, _preload_content=True, + _request_timeout=None): # header parameters header_params = header_params or {} @@ -144,7 +145,9 @@ class ApiClient(object): response_data = self.request(method, url, query_params=query_params, headers=header_params, - post_params=post_params, body=body, _preload_content=_preload_content) + post_params=post_params, body=body, + _preload_content=_preload_content, + _request_timeout=_request_timeout) self.last_response = response_data @@ -279,7 +282,8 @@ class ApiClient(object): path_params=None, query_params=None, header_params=None, body=None, post_params=None, files=None, response_type=None, auth_settings=None, callback=None, - _return_http_data_only=None, collection_formats=None, _preload_content=True): + _return_http_data_only=None, collection_formats=None, _preload_content=True, + _request_timeout=None): """ Makes the HTTP request (synchronous) and return the deserialized data. To make an async request, define a function for callback. @@ -303,21 +307,23 @@ class ApiClient(object): :param _return_http_data_only: response data without head status code and headers :param collection_formats: dict of collection formats for path, query, header, and post parameters. + :param _preload_content: if False, the urllib3.HTTPResponse object will be returned without + reading/decoding response data. Default is True. + :param _request_timeout: timeout setting for this request. If one number provided, it will be total request + timeout. It can also be a pair (tuple) of (connection, read) timeouts. :return: If provide parameter callback, the request will be called asynchronously. The method will return the request thread. If parameter callback is None, then the method will return the response directly. - :param _preload_content: if False, the urllib3.HTTPResponse object will be returned without - reading/decoding response data. Default is True. """ if callback is None: return self.__call_api(resource_path, method, path_params, query_params, header_params, body, post_params, files, response_type, auth_settings, callback, - _return_http_data_only, collection_formats, _preload_content) + _return_http_data_only, collection_formats, _preload_content, _request_timeout) else: thread = threading.Thread(target=self.__call_api, args=(resource_path, method, @@ -326,12 +332,12 @@ class ApiClient(object): post_params, files, response_type, auth_settings, callback, _return_http_data_only, - collection_formats, _preload_content)) + collection_formats, _preload_content, _request_timeout)) thread.start() return thread def request(self, method, url, query_params=None, headers=None, - post_params=None, body=None, _preload_content=True): + post_params=None, body=None, _preload_content=True, _request_timeout=None): """ Makes the HTTP request using RESTClient. """ @@ -339,11 +345,13 @@ class ApiClient(object): return self.rest_client.GET(url, query_params=query_params, _preload_content=_preload_content, + _request_timeout=_request_timeout, headers=headers) elif method == "HEAD": return self.rest_client.HEAD(url, query_params=query_params, _preload_content=_preload_content, + _request_timeout=_request_timeout, headers=headers) elif method == "OPTIONS": return self.rest_client.OPTIONS(url, @@ -351,6 +359,7 @@ class ApiClient(object): headers=headers, post_params=post_params, _preload_content=_preload_content, + _request_timeout=_request_timeout, body=body) elif method == "POST": return self.rest_client.POST(url, @@ -358,6 +367,7 @@ class ApiClient(object): headers=headers, post_params=post_params, _preload_content=_preload_content, + _request_timeout=_request_timeout, body=body) elif method == "PUT": return self.rest_client.PUT(url, @@ -365,6 +375,7 @@ class ApiClient(object): headers=headers, post_params=post_params, _preload_content=_preload_content, + _request_timeout=_request_timeout, body=body) elif method == "PATCH": return self.rest_client.PATCH(url, @@ -372,12 +383,14 @@ class ApiClient(object): headers=headers, post_params=post_params, _preload_content=_preload_content, + _request_timeout=_request_timeout, body=body) elif method == "DELETE": return self.rest_client.DELETE(url, query_params=query_params, headers=headers, _preload_content=_preload_content, + _request_timeout=_request_timeout, body=body) else: raise ValueError( diff --git a/modules/swagger-codegen/src/main/resources/python/rest.mustache b/modules/swagger-codegen/src/main/resources/python/rest.mustache index 3f0e3dca2928..8ddd17c473c9 100644 --- a/modules/swagger-codegen/src/main/resources/python/rest.mustache +++ b/modules/swagger-codegen/src/main/resources/python/rest.mustache @@ -85,7 +85,7 @@ class RESTClientObject(object): ) def request(self, method, url, query_params=None, headers=None, - body=None, post_params=None, _preload_content=True): + body=None, post_params=None, _preload_content=True, _request_timeout=None): """ :param method: http request method :param url: http request url @@ -97,6 +97,8 @@ class RESTClientObject(object): and `multipart/form-data` :param _preload_content: if False, the urllib3.HTTPResponse object will be returned without reading/decoding response data. Default is True. + :param _request_timeout: timeout setting for this request. If one number provided, it will be total request + timeout. It can also be a pair (tuple) of (connection, read) timeouts. """ method = method.upper() assert method in ['GET', 'HEAD', 'DELETE', 'POST', 'PUT', 'PATCH', 'OPTIONS'] @@ -109,6 +111,13 @@ class RESTClientObject(object): post_params = post_params or {} headers = headers or {} + timeout = None + if _request_timeout: + if isinstance(_request_timeout, (int, ) if PY3 else (int, long)): + timeout = urllib3.Timeout(total=_request_timeout) + elif isinstance(_request_timeout, tuple) and len(_request_timeout) == 2: + timeout = urllib3.Timeout(connect=_request_timeout[0], read=_request_timeout[1]) + if 'Content-Type' not in headers: headers['Content-Type'] = 'application/json' @@ -124,12 +133,14 @@ class RESTClientObject(object): r = self.pool_manager.request(method, url, body=request_body, preload_content=_preload_content, + timeout=timeout, headers=headers) elif headers['Content-Type'] == 'application/x-www-form-urlencoded': r = self.pool_manager.request(method, url, fields=post_params, encode_multipart=False, preload_content=_preload_content, + timeout=timeout, headers=headers) elif headers['Content-Type'] == 'multipart/form-data': # must del headers['Content-Type'], or the correct Content-Type @@ -139,6 +150,7 @@ class RESTClientObject(object): fields=post_params, encode_multipart=True, preload_content=_preload_content, + timeout=timeout, headers=headers) # Pass a `string` parameter directly in the body to support # other content types than Json when `body` argument is provided @@ -148,6 +160,7 @@ class RESTClientObject(object): r = self.pool_manager.request(method, url, body=request_body, preload_content=_preload_content, + timeout=timeout, headers=headers) else: # Cannot generate the request from given parameters @@ -159,6 +172,7 @@ class RESTClientObject(object): r = self.pool_manager.request(method, url, fields=query_params, preload_content=_preload_content, + timeout=timeout, headers=headers) except urllib3.exceptions.SSLError as e: msg = "{0}\n{1}".format(type(e).__name__, str(e)) @@ -180,55 +194,66 @@ class RESTClientObject(object): return r - def GET(self, url, headers=None, query_params=None, _preload_content=True): + def GET(self, url, headers=None, query_params=None, _preload_content=True, _request_timeout=None): return self.request("GET", url, headers=headers, _preload_content=_preload_content, + _request_timeout=_request_timeout, query_params=query_params) - def HEAD(self, url, headers=None, query_params=None, _preload_content=True): + def HEAD(self, url, headers=None, query_params=None, _preload_content=True, _request_timeout=None): return self.request("HEAD", url, headers=headers, _preload_content=_preload_content, + _request_timeout=_request_timeout, query_params=query_params) - def OPTIONS(self, url, headers=None, query_params=None, post_params=None, body=None, _preload_content=True): + def OPTIONS(self, url, headers=None, query_params=None, post_params=None, body=None, _preload_content=True, + _request_timeout=None): return self.request("OPTIONS", url, headers=headers, query_params=query_params, post_params=post_params, _preload_content=_preload_content, + _request_timeout=_request_timeout, body=body) - def DELETE(self, url, headers=None, query_params=None, body=None, _preload_content=True): + def DELETE(self, url, headers=None, query_params=None, body=None, _preload_content=True, _request_timeout=None): return self.request("DELETE", url, headers=headers, query_params=query_params, _preload_content=_preload_content, + _request_timeout=_request_timeout, body=body) - def POST(self, url, headers=None, query_params=None, post_params=None, body=None, _preload_content=True): + def POST(self, url, headers=None, query_params=None, post_params=None, body=None, _preload_content=True, + _request_timeout=None): return self.request("POST", url, headers=headers, query_params=query_params, post_params=post_params, _preload_content=_preload_content, + _request_timeout=_request_timeout, body=body) - def PUT(self, url, headers=None, query_params=None, post_params=None, body=None, _preload_content=True): + def PUT(self, url, headers=None, query_params=None, post_params=None, body=None, _preload_content=True, + _request_timeout=None): return self.request("PUT", url, headers=headers, query_params=query_params, post_params=post_params, _preload_content=_preload_content, + _request_timeout=_request_timeout, body=body) - def PATCH(self, url, headers=None, query_params=None, post_params=None, body=None, _preload_content=True): + def PATCH(self, url, headers=None, query_params=None, post_params=None, body=None, _preload_content=True, + _request_timeout=None): return self.request("PATCH", url, headers=headers, query_params=query_params, post_params=post_params, _preload_content=_preload_content, + _request_timeout=_request_timeout, body=body) diff --git a/samples/client/petstore/python/petstore_api/api_client.py b/samples/client/petstore/python/petstore_api/api_client.py index f13cb3772ad5..16841117b1b6 100644 --- a/samples/client/petstore/python/petstore_api/api_client.py +++ b/samples/client/petstore/python/petstore_api/api_client.py @@ -96,7 +96,8 @@ class ApiClient(object): path_params=None, query_params=None, header_params=None, body=None, post_params=None, files=None, response_type=None, auth_settings=None, callback=None, - _return_http_data_only=None, collection_formats=None, _preload_content=True): + _return_http_data_only=None, collection_formats=None, _preload_content=True, + _request_timeout=None): # header parameters header_params = header_params or {} @@ -144,7 +145,9 @@ class ApiClient(object): response_data = self.request(method, url, query_params=query_params, headers=header_params, - post_params=post_params, body=body, _preload_content=_preload_content) + post_params=post_params, body=body, + _preload_content=_preload_content, + _request_timeout=_request_timeout) self.last_response = response_data @@ -279,7 +282,8 @@ class ApiClient(object): path_params=None, query_params=None, header_params=None, body=None, post_params=None, files=None, response_type=None, auth_settings=None, callback=None, - _return_http_data_only=None, collection_formats=None, _preload_content=True): + _return_http_data_only=None, collection_formats=None, _preload_content=True, + _request_timeout=None): """ Makes the HTTP request (synchronous) and return the deserialized data. To make an async request, define a function for callback. @@ -303,21 +307,23 @@ class ApiClient(object): :param _return_http_data_only: response data without head status code and headers :param collection_formats: dict of collection formats for path, query, header, and post parameters. + :param _preload_content: if False, the urllib3.HTTPResponse object will be returned without + reading/decoding response data. Default is True. + :param _request_timeout: timeout setting for this request. If one number provided, it will be total request + timeout. It can also be a pair (tuple) of (connection, read) timeouts. :return: If provide parameter callback, the request will be called asynchronously. The method will return the request thread. If parameter callback is None, then the method will return the response directly. - :param _preload_content: if False, the urllib3.HTTPResponse object will be returned without - reading/decoding response data. Default is True. """ if callback is None: return self.__call_api(resource_path, method, path_params, query_params, header_params, body, post_params, files, response_type, auth_settings, callback, - _return_http_data_only, collection_formats, _preload_content) + _return_http_data_only, collection_formats, _preload_content, _request_timeout) else: thread = threading.Thread(target=self.__call_api, args=(resource_path, method, @@ -326,12 +332,12 @@ class ApiClient(object): post_params, files, response_type, auth_settings, callback, _return_http_data_only, - collection_formats, _preload_content)) + collection_formats, _preload_content, _request_timeout)) thread.start() return thread def request(self, method, url, query_params=None, headers=None, - post_params=None, body=None, _preload_content=True): + post_params=None, body=None, _preload_content=True, _request_timeout=None): """ Makes the HTTP request using RESTClient. """ @@ -339,11 +345,13 @@ class ApiClient(object): return self.rest_client.GET(url, query_params=query_params, _preload_content=_preload_content, + _request_timeout=_request_timeout, headers=headers) elif method == "HEAD": return self.rest_client.HEAD(url, query_params=query_params, _preload_content=_preload_content, + _request_timeout=_request_timeout, headers=headers) elif method == "OPTIONS": return self.rest_client.OPTIONS(url, @@ -351,6 +359,7 @@ class ApiClient(object): headers=headers, post_params=post_params, _preload_content=_preload_content, + _request_timeout=_request_timeout, body=body) elif method == "POST": return self.rest_client.POST(url, @@ -358,6 +367,7 @@ class ApiClient(object): headers=headers, post_params=post_params, _preload_content=_preload_content, + _request_timeout=_request_timeout, body=body) elif method == "PUT": return self.rest_client.PUT(url, @@ -365,6 +375,7 @@ class ApiClient(object): headers=headers, post_params=post_params, _preload_content=_preload_content, + _request_timeout=_request_timeout, body=body) elif method == "PATCH": return self.rest_client.PATCH(url, @@ -372,12 +383,14 @@ class ApiClient(object): headers=headers, post_params=post_params, _preload_content=_preload_content, + _request_timeout=_request_timeout, body=body) elif method == "DELETE": return self.rest_client.DELETE(url, query_params=query_params, headers=headers, _preload_content=_preload_content, + _request_timeout=_request_timeout, body=body) else: raise ValueError( diff --git a/samples/client/petstore/python/petstore_api/apis/fake_api.py b/samples/client/petstore/python/petstore_api/apis/fake_api.py index cdf79483bc9a..44eb2a07e436 100644 --- a/samples/client/petstore/python/petstore_api/apis/fake_api.py +++ b/samples/client/petstore/python/petstore_api/apis/fake_api.py @@ -103,6 +103,7 @@ class FakeApi(object): all_params.append('callback') all_params.append('_return_http_data_only') all_params.append('_preload_content') + all_params.append('_request_timeout') params = locals() for key, val in iteritems(params['kwargs']): @@ -159,6 +160,7 @@ class FakeApi(object): callback=params.get('callback'), _return_http_data_only=params.get('_return_http_data_only'), _preload_content=params.get('_preload_content', True), + _request_timeout=params.get('_request_timeout'), collection_formats=collection_formats) def test_endpoint_parameters(self, number, double, pattern_without_delimiter, byte, **kwargs): @@ -239,6 +241,7 @@ class FakeApi(object): all_params.append('callback') all_params.append('_return_http_data_only') all_params.append('_preload_content') + all_params.append('_request_timeout') params = locals() for key, val in iteritems(params['kwargs']): @@ -356,6 +359,7 @@ class FakeApi(object): callback=params.get('callback'), _return_http_data_only=params.get('_return_http_data_only'), _preload_content=params.get('_preload_content', True), + _request_timeout=params.get('_request_timeout'), collection_formats=collection_formats) def test_enum_parameters(self, **kwargs): @@ -424,6 +428,7 @@ class FakeApi(object): all_params.append('callback') all_params.append('_return_http_data_only') all_params.append('_preload_content') + all_params.append('_request_timeout') params = locals() for key, val in iteritems(params['kwargs']): @@ -494,4 +499,5 @@ class FakeApi(object): callback=params.get('callback'), _return_http_data_only=params.get('_return_http_data_only'), _preload_content=params.get('_preload_content', True), + _request_timeout=params.get('_request_timeout'), collection_formats=collection_formats) diff --git a/samples/client/petstore/python/petstore_api/apis/pet_api.py b/samples/client/petstore/python/petstore_api/apis/pet_api.py index d8c5eefc946c..431b4deb39a2 100644 --- a/samples/client/petstore/python/petstore_api/apis/pet_api.py +++ b/samples/client/petstore/python/petstore_api/apis/pet_api.py @@ -103,6 +103,7 @@ class PetApi(object): all_params.append('callback') all_params.append('_return_http_data_only') all_params.append('_preload_content') + all_params.append('_request_timeout') params = locals() for key, val in iteritems(params['kwargs']): @@ -159,6 +160,7 @@ class PetApi(object): callback=params.get('callback'), _return_http_data_only=params.get('_return_http_data_only'), _preload_content=params.get('_preload_content', True), + _request_timeout=params.get('_request_timeout'), collection_formats=collection_formats) def delete_pet(self, pet_id, **kwargs): @@ -215,6 +217,7 @@ class PetApi(object): all_params.append('callback') all_params.append('_return_http_data_only') all_params.append('_preload_content') + all_params.append('_request_timeout') params = locals() for key, val in iteritems(params['kwargs']): @@ -273,6 +276,7 @@ class PetApi(object): callback=params.get('callback'), _return_http_data_only=params.get('_return_http_data_only'), _preload_content=params.get('_preload_content', True), + _request_timeout=params.get('_request_timeout'), collection_formats=collection_formats) def find_pets_by_status(self, status, **kwargs): @@ -327,6 +331,7 @@ class PetApi(object): all_params.append('callback') all_params.append('_return_http_data_only') all_params.append('_preload_content') + all_params.append('_request_timeout') params = locals() for key, val in iteritems(params['kwargs']): @@ -384,6 +389,7 @@ class PetApi(object): callback=params.get('callback'), _return_http_data_only=params.get('_return_http_data_only'), _preload_content=params.get('_preload_content', True), + _request_timeout=params.get('_request_timeout'), collection_formats=collection_formats) def find_pets_by_tags(self, tags, **kwargs): @@ -438,6 +444,7 @@ class PetApi(object): all_params.append('callback') all_params.append('_return_http_data_only') all_params.append('_preload_content') + all_params.append('_request_timeout') params = locals() for key, val in iteritems(params['kwargs']): @@ -495,6 +502,7 @@ class PetApi(object): callback=params.get('callback'), _return_http_data_only=params.get('_return_http_data_only'), _preload_content=params.get('_preload_content', True), + _request_timeout=params.get('_request_timeout'), collection_formats=collection_formats) def get_pet_by_id(self, pet_id, **kwargs): @@ -549,6 +557,7 @@ class PetApi(object): all_params.append('callback') all_params.append('_return_http_data_only') all_params.append('_preload_content') + all_params.append('_request_timeout') params = locals() for key, val in iteritems(params['kwargs']): @@ -605,6 +614,7 @@ class PetApi(object): callback=params.get('callback'), _return_http_data_only=params.get('_return_http_data_only'), _preload_content=params.get('_preload_content', True), + _request_timeout=params.get('_request_timeout'), collection_formats=collection_formats) def update_pet(self, body, **kwargs): @@ -659,6 +669,7 @@ class PetApi(object): all_params.append('callback') all_params.append('_return_http_data_only') all_params.append('_preload_content') + all_params.append('_request_timeout') params = locals() for key, val in iteritems(params['kwargs']): @@ -715,6 +726,7 @@ class PetApi(object): callback=params.get('callback'), _return_http_data_only=params.get('_return_http_data_only'), _preload_content=params.get('_preload_content', True), + _request_timeout=params.get('_request_timeout'), collection_formats=collection_formats) def update_pet_with_form(self, pet_id, **kwargs): @@ -773,6 +785,7 @@ class PetApi(object): all_params.append('callback') all_params.append('_return_http_data_only') all_params.append('_preload_content') + all_params.append('_request_timeout') params = locals() for key, val in iteritems(params['kwargs']): @@ -833,6 +846,7 @@ class PetApi(object): callback=params.get('callback'), _return_http_data_only=params.get('_return_http_data_only'), _preload_content=params.get('_preload_content', True), + _request_timeout=params.get('_request_timeout'), collection_formats=collection_formats) def upload_file(self, pet_id, **kwargs): @@ -891,6 +905,7 @@ class PetApi(object): all_params.append('callback') all_params.append('_return_http_data_only') all_params.append('_preload_content') + all_params.append('_request_timeout') params = locals() for key, val in iteritems(params['kwargs']): @@ -951,4 +966,5 @@ class PetApi(object): callback=params.get('callback'), _return_http_data_only=params.get('_return_http_data_only'), _preload_content=params.get('_preload_content', True), + _request_timeout=params.get('_request_timeout'), collection_formats=collection_formats) diff --git a/samples/client/petstore/python/petstore_api/apis/store_api.py b/samples/client/petstore/python/petstore_api/apis/store_api.py index adcf8d2b4edb..55a916ef18a3 100644 --- a/samples/client/petstore/python/petstore_api/apis/store_api.py +++ b/samples/client/petstore/python/petstore_api/apis/store_api.py @@ -103,6 +103,7 @@ class StoreApi(object): all_params.append('callback') all_params.append('_return_http_data_only') all_params.append('_preload_content') + all_params.append('_request_timeout') params = locals() for key, val in iteritems(params['kwargs']): @@ -161,6 +162,7 @@ class StoreApi(object): callback=params.get('callback'), _return_http_data_only=params.get('_return_http_data_only'), _preload_content=params.get('_preload_content', True), + _request_timeout=params.get('_request_timeout'), collection_formats=collection_formats) def get_inventory(self, **kwargs): @@ -213,6 +215,7 @@ class StoreApi(object): all_params.append('callback') all_params.append('_return_http_data_only') all_params.append('_preload_content') + all_params.append('_request_timeout') params = locals() for key, val in iteritems(params['kwargs']): @@ -264,6 +267,7 @@ class StoreApi(object): callback=params.get('callback'), _return_http_data_only=params.get('_return_http_data_only'), _preload_content=params.get('_preload_content', True), + _request_timeout=params.get('_request_timeout'), collection_formats=collection_formats) def get_order_by_id(self, order_id, **kwargs): @@ -318,6 +322,7 @@ class StoreApi(object): all_params.append('callback') all_params.append('_return_http_data_only') all_params.append('_preload_content') + all_params.append('_request_timeout') params = locals() for key, val in iteritems(params['kwargs']): @@ -378,6 +383,7 @@ class StoreApi(object): callback=params.get('callback'), _return_http_data_only=params.get('_return_http_data_only'), _preload_content=params.get('_preload_content', True), + _request_timeout=params.get('_request_timeout'), collection_formats=collection_formats) def place_order(self, body, **kwargs): @@ -432,6 +438,7 @@ class StoreApi(object): all_params.append('callback') all_params.append('_return_http_data_only') all_params.append('_preload_content') + all_params.append('_request_timeout') params = locals() for key, val in iteritems(params['kwargs']): @@ -488,4 +495,5 @@ class StoreApi(object): callback=params.get('callback'), _return_http_data_only=params.get('_return_http_data_only'), _preload_content=params.get('_preload_content', True), + _request_timeout=params.get('_request_timeout'), collection_formats=collection_formats) diff --git a/samples/client/petstore/python/petstore_api/apis/user_api.py b/samples/client/petstore/python/petstore_api/apis/user_api.py index 255b68a8c7fd..6d23713217d1 100644 --- a/samples/client/petstore/python/petstore_api/apis/user_api.py +++ b/samples/client/petstore/python/petstore_api/apis/user_api.py @@ -103,6 +103,7 @@ class UserApi(object): all_params.append('callback') all_params.append('_return_http_data_only') all_params.append('_preload_content') + all_params.append('_request_timeout') params = locals() for key, val in iteritems(params['kwargs']): @@ -159,6 +160,7 @@ class UserApi(object): callback=params.get('callback'), _return_http_data_only=params.get('_return_http_data_only'), _preload_content=params.get('_preload_content', True), + _request_timeout=params.get('_request_timeout'), collection_formats=collection_formats) def create_users_with_array_input(self, body, **kwargs): @@ -213,6 +215,7 @@ class UserApi(object): all_params.append('callback') all_params.append('_return_http_data_only') all_params.append('_preload_content') + all_params.append('_request_timeout') params = locals() for key, val in iteritems(params['kwargs']): @@ -269,6 +272,7 @@ class UserApi(object): callback=params.get('callback'), _return_http_data_only=params.get('_return_http_data_only'), _preload_content=params.get('_preload_content', True), + _request_timeout=params.get('_request_timeout'), collection_formats=collection_formats) def create_users_with_list_input(self, body, **kwargs): @@ -323,6 +327,7 @@ class UserApi(object): all_params.append('callback') all_params.append('_return_http_data_only') all_params.append('_preload_content') + all_params.append('_request_timeout') params = locals() for key, val in iteritems(params['kwargs']): @@ -379,6 +384,7 @@ class UserApi(object): callback=params.get('callback'), _return_http_data_only=params.get('_return_http_data_only'), _preload_content=params.get('_preload_content', True), + _request_timeout=params.get('_request_timeout'), collection_formats=collection_formats) def delete_user(self, username, **kwargs): @@ -433,6 +439,7 @@ class UserApi(object): all_params.append('callback') all_params.append('_return_http_data_only') all_params.append('_preload_content') + all_params.append('_request_timeout') params = locals() for key, val in iteritems(params['kwargs']): @@ -489,6 +496,7 @@ class UserApi(object): callback=params.get('callback'), _return_http_data_only=params.get('_return_http_data_only'), _preload_content=params.get('_preload_content', True), + _request_timeout=params.get('_request_timeout'), collection_formats=collection_formats) def get_user_by_name(self, username, **kwargs): @@ -543,6 +551,7 @@ class UserApi(object): all_params.append('callback') all_params.append('_return_http_data_only') all_params.append('_preload_content') + all_params.append('_request_timeout') params = locals() for key, val in iteritems(params['kwargs']): @@ -599,6 +608,7 @@ class UserApi(object): callback=params.get('callback'), _return_http_data_only=params.get('_return_http_data_only'), _preload_content=params.get('_preload_content', True), + _request_timeout=params.get('_request_timeout'), collection_formats=collection_formats) def login_user(self, username, password, **kwargs): @@ -655,6 +665,7 @@ class UserApi(object): all_params.append('callback') all_params.append('_return_http_data_only') all_params.append('_preload_content') + all_params.append('_request_timeout') params = locals() for key, val in iteritems(params['kwargs']): @@ -716,6 +727,7 @@ class UserApi(object): callback=params.get('callback'), _return_http_data_only=params.get('_return_http_data_only'), _preload_content=params.get('_preload_content', True), + _request_timeout=params.get('_request_timeout'), collection_formats=collection_formats) def logout_user(self, **kwargs): @@ -768,6 +780,7 @@ class UserApi(object): all_params.append('callback') all_params.append('_return_http_data_only') all_params.append('_preload_content') + all_params.append('_request_timeout') params = locals() for key, val in iteritems(params['kwargs']): @@ -819,6 +832,7 @@ class UserApi(object): callback=params.get('callback'), _return_http_data_only=params.get('_return_http_data_only'), _preload_content=params.get('_preload_content', True), + _request_timeout=params.get('_request_timeout'), collection_formats=collection_formats) def update_user(self, username, body, **kwargs): @@ -875,6 +889,7 @@ class UserApi(object): all_params.append('callback') all_params.append('_return_http_data_only') all_params.append('_preload_content') + all_params.append('_request_timeout') params = locals() for key, val in iteritems(params['kwargs']): @@ -936,4 +951,5 @@ class UserApi(object): callback=params.get('callback'), _return_http_data_only=params.get('_return_http_data_only'), _preload_content=params.get('_preload_content', True), + _request_timeout=params.get('_request_timeout'), collection_formats=collection_formats) diff --git a/samples/client/petstore/python/petstore_api/rest.py b/samples/client/petstore/python/petstore_api/rest.py index c61b29c81209..3a98beec9b16 100644 --- a/samples/client/petstore/python/petstore_api/rest.py +++ b/samples/client/petstore/python/petstore_api/rest.py @@ -105,7 +105,7 @@ class RESTClientObject(object): ) def request(self, method, url, query_params=None, headers=None, - body=None, post_params=None, _preload_content=True): + body=None, post_params=None, _preload_content=True, _request_timeout=None): """ :param method: http request method :param url: http request url @@ -117,6 +117,8 @@ class RESTClientObject(object): and `multipart/form-data` :param _preload_content: if False, the urllib3.HTTPResponse object will be returned without reading/decoding response data. Default is True. + :param _request_timeout: timeout setting for this request. If one number provided, it will be total request + timeout. It can also be a pair (tuple) of (connection, read) timeouts. """ method = method.upper() assert method in ['GET', 'HEAD', 'DELETE', 'POST', 'PUT', 'PATCH', 'OPTIONS'] @@ -129,6 +131,13 @@ class RESTClientObject(object): post_params = post_params or {} headers = headers or {} + timeout = None + if _request_timeout: + if isinstance(_request_timeout, (int, ) if PY3 else (int, long)): + timeout = urllib3.Timeout(total=_request_timeout) + elif isinstance(_request_timeout, tuple) and len(_request_timeout) == 2: + timeout = urllib3.Timeout(connect=_request_timeout[0], read=_request_timeout[1]) + if 'Content-Type' not in headers: headers['Content-Type'] = 'application/json' @@ -144,12 +153,14 @@ class RESTClientObject(object): r = self.pool_manager.request(method, url, body=request_body, preload_content=_preload_content, + timeout=timeout, headers=headers) elif headers['Content-Type'] == 'application/x-www-form-urlencoded': r = self.pool_manager.request(method, url, fields=post_params, encode_multipart=False, preload_content=_preload_content, + timeout=timeout, headers=headers) elif headers['Content-Type'] == 'multipart/form-data': # must del headers['Content-Type'], or the correct Content-Type @@ -159,6 +170,7 @@ class RESTClientObject(object): fields=post_params, encode_multipart=True, preload_content=_preload_content, + timeout=timeout, headers=headers) # Pass a `string` parameter directly in the body to support # other content types than Json when `body` argument is provided @@ -168,6 +180,7 @@ class RESTClientObject(object): r = self.pool_manager.request(method, url, body=request_body, preload_content=_preload_content, + timeout=timeout, headers=headers) else: # Cannot generate the request from given parameters @@ -179,6 +192,7 @@ class RESTClientObject(object): r = self.pool_manager.request(method, url, fields=query_params, preload_content=_preload_content, + timeout=timeout, headers=headers) except urllib3.exceptions.SSLError as e: msg = "{0}\n{1}".format(type(e).__name__, str(e)) @@ -200,55 +214,66 @@ class RESTClientObject(object): return r - def GET(self, url, headers=None, query_params=None, _preload_content=True): + def GET(self, url, headers=None, query_params=None, _preload_content=True, _request_timeout=None): return self.request("GET", url, headers=headers, _preload_content=_preload_content, + _request_timeout=_request_timeout, query_params=query_params) - def HEAD(self, url, headers=None, query_params=None, _preload_content=True): + def HEAD(self, url, headers=None, query_params=None, _preload_content=True, _request_timeout=None): return self.request("HEAD", url, headers=headers, _preload_content=_preload_content, + _request_timeout=_request_timeout, query_params=query_params) - def OPTIONS(self, url, headers=None, query_params=None, post_params=None, body=None, _preload_content=True): + def OPTIONS(self, url, headers=None, query_params=None, post_params=None, body=None, _preload_content=True, + _request_timeout=None): return self.request("OPTIONS", url, headers=headers, query_params=query_params, post_params=post_params, _preload_content=_preload_content, + _request_timeout=_request_timeout, body=body) - def DELETE(self, url, headers=None, query_params=None, body=None, _preload_content=True): + def DELETE(self, url, headers=None, query_params=None, body=None, _preload_content=True, _request_timeout=None): return self.request("DELETE", url, headers=headers, query_params=query_params, _preload_content=_preload_content, + _request_timeout=_request_timeout, body=body) - def POST(self, url, headers=None, query_params=None, post_params=None, body=None, _preload_content=True): + def POST(self, url, headers=None, query_params=None, post_params=None, body=None, _preload_content=True, + _request_timeout=None): return self.request("POST", url, headers=headers, query_params=query_params, post_params=post_params, _preload_content=_preload_content, + _request_timeout=_request_timeout, body=body) - def PUT(self, url, headers=None, query_params=None, post_params=None, body=None, _preload_content=True): + def PUT(self, url, headers=None, query_params=None, post_params=None, body=None, _preload_content=True, + _request_timeout=None): return self.request("PUT", url, headers=headers, query_params=query_params, post_params=post_params, _preload_content=_preload_content, + _request_timeout=_request_timeout, body=body) - def PATCH(self, url, headers=None, query_params=None, post_params=None, body=None, _preload_content=True): + def PATCH(self, url, headers=None, query_params=None, post_params=None, body=None, _preload_content=True, + _request_timeout=None): return self.request("PATCH", url, headers=headers, query_params=query_params, post_params=post_params, _preload_content=_preload_content, + _request_timeout=_request_timeout, body=body) diff --git a/samples/client/petstore/python/tests/test_pet_api.py b/samples/client/petstore/python/tests/test_pet_api.py index a539d2c598f9..613b665cf5f8 100644 --- a/samples/client/petstore/python/tests/test_pet_api.py +++ b/samples/client/petstore/python/tests/test_pet_api.py @@ -15,8 +15,38 @@ from petstore_api.rest import ApiException from .util import id_gen +import json + +import urllib3 + HOST = 'http://petstore.swagger.io/v2' + +class TimeoutWithEqual(urllib3.Timeout): + def __init__(self, *arg, **kwargs): + super(TimeoutWithEqual, self).__init__(*arg, **kwargs) + + def __eq__(self, other): + return self._read == other._read and self._connect == other._connect and self.total == other.total + + +class MockPoolManager(object): + def __init__(self, tc): + self._tc = tc + self._reqs = [] + + def expect_request(self, *args, **kwargs): + self._reqs.append((args, kwargs)) + + def request(self, *args, **kwargs): + self._tc.assertTrue(len(self._reqs)>0) + r = self._reqs.pop(0) + self._tc.maxDiff = None + self._tc.assertEqual(r[0], args) + self._tc.assertEqual(r[1], kwargs) + return urllib3.HTTPResponse(status=200, body=b'test') + + class PetApiTests(unittest.TestCase): def setUp(self): @@ -65,6 +95,28 @@ class PetApiTests(unittest.TestCase): resp.close() resp.release_conn() + def test_timeout(self): + mock_pool = MockPoolManager(self) + self.api_client.rest_client.pool_manager = mock_pool + + mock_pool.expect_request('POST', 'http://petstore.swagger.io/v2/pet', + body=json.dumps(self.api_client.sanitize_for_serialization(self.pet)), + headers={'Content-Type': 'application/json', + 'Authorization': 'Bearer ', + 'Accept': 'application/json', + 'User-Agent': 'Swagger-Codegen/1.0.0/python'}, + preload_content=True, timeout=TimeoutWithEqual(total=5)) + mock_pool.expect_request('POST', 'http://petstore.swagger.io/v2/pet', + body=json.dumps(self.api_client.sanitize_for_serialization(self.pet)), + headers={'Content-Type': 'application/json', + 'Authorization': 'Bearer ', + 'Accept': 'application/json', + 'User-Agent': 'Swagger-Codegen/1.0.0/python'}, + preload_content=True, timeout=TimeoutWithEqual(connect=1, read=2)) + + self.pet_api.add_pet(body=self.pet, _request_timeout=5) + self.pet_api.add_pet(body=self.pet, _request_timeout=(1, 2)) + def test_create_api_instance(self): pet_api = petstore_api.PetApi() pet_api2 = petstore_api.PetApi() From 265d635eee1805745d22d71a6726aaea272e8113 Mon Sep 17 00:00:00 2001 From: Brian Shamblen Date: Fri, 11 Nov 2016 11:41:08 -0800 Subject: [PATCH 06/11] Add markdown support to descriptions --- .../main/resources/htmlDocs2/index.mustache | 148 ++++++++++-------- .../htmlDocs2/js_jsonschemaview.mustache | 4 +- .../main/resources/htmlDocs2/marked.mustache | 8 + 3 files changed, 91 insertions(+), 69 deletions(-) create mode 100644 modules/swagger-codegen/src/main/resources/htmlDocs2/marked.mustache diff --git a/modules/swagger-codegen/src/main/resources/htmlDocs2/index.mustache b/modules/swagger-codegen/src/main/resources/htmlDocs2/index.mustache index c65ca3502689..d8de13e9e764 100644 --- a/modules/swagger-codegen/src/main/resources/htmlDocs2/index.mustache +++ b/modules/swagger-codegen/src/main/resources/htmlDocs2/index.mustache @@ -12,70 +12,84 @@ {{>js_prettify}} {{>js_bootstrap}} +{{>marked}}