diff --git a/.openapi-generator/VERSION b/.openapi-generator/VERSION index 1a487e1..28cbf7c 100755 --- a/.openapi-generator/VERSION +++ b/.openapi-generator/VERSION @@ -1 +1 @@ -5.0.0-beta2 \ No newline at end of file +5.0.0 \ No newline at end of file diff --git a/generator-templates/api_client.mustache b/generator-templates/api_client.mustache index 6768b8a..3ad1f5e 100755 --- a/generator-templates/api_client.mustache +++ b/generator-templates/api_client.mustache @@ -131,7 +131,7 @@ class ApiClient(object): {{#asyncio}}async {{/asyncio}}def __call_api( self, resource_path, method, path_params=None, query_params=None, header_params=None, body=None, post_params=None, - files=None, response_type=None, auth_settings=None, + files=None, response_types_map=None, auth_settings=None, _return_http_data_only=None, collection_formats=None, _preload_content=True, _request_timeout=None, _host=None, _request_auth=None): @@ -159,11 +159,13 @@ class ApiClient(object): '{%s}' % k, quote(str(v), safe=config.safe_chars_for_path_param) ) + # query parameters if query_params: query_params = self.sanitize_for_serialization(query_params) query_params = self.parameters_to_tuples(query_params, collection_formats) + # post parameters if post_params or files: post_params = post_params if post_params else [] @@ -171,19 +173,23 @@ class ApiClient(object): post_params = self.parameters_to_tuples(post_params, collection_formats) post_params.extend(self.files_parameters(files)) + # auth setting self.update_params_for_auth( header_params, query_params, auth_settings, request_auth=_request_auth) + # body if body: body = self.sanitize_for_serialization(body) + # request url if _host is None: url = self.configuration.host + resource_path else: # use server/host defined in path or operation instead url = _host + resource_path + try: # perform request and return response response_data = {{#asyncio}}await {{/asyncio}}{{#tornado}}yield {{/tornado}}self.request( @@ -194,9 +200,11 @@ class ApiClient(object): except ApiException as e: e.body = e.body.decode('utf-8') if six.PY3 else e.body raise e - content_type = response_data.getheader('content-type') + self.last_response = response_data + return_data = response_data + if not _preload_content: {{^tornado}} return return_data @@ -204,17 +212,24 @@ class ApiClient(object): {{#tornado}} raise tornado.gen.Return(return_data) {{/tornado}} + + response_type = response_types_map.get(response_data.status, None) + if six.PY3 and response_type not in ["file", "bytes"]: match = None + content_type = response_data.getheader('content-type') if content_type is not None: match = re.search(r"charset=([a-zA-Z\-\d]+)[\s\;]?", content_type) encoding = match.group(1) if match else "utf-8" response_data.data = response_data.data.decode(encoding) + # deserialize response data + if response_type: return_data = self.deserialize(response_data, response_type) else: return_data = None + {{^tornado}} if _return_http_data_only: return (return_data) @@ -229,8 +244,10 @@ class ApiClient(object): raise tornado.gen.Return((return_data, response_data.status, response_data.getheaders())) {{/tornado}} + def sanitize_for_serialization(self, obj): """Builds a JSON POST object. + If obj is None, return None. If obj is str, int, long, float, bool, return directly. If obj is datetime.datetime, datetime.date @@ -238,6 +255,7 @@ class ApiClient(object): If obj is list, sanitize each element in the list. If obj is dict, return the dict. If obj is OpenAPI model, return the properties dict. + :param obj: The data to serialize. :return: The serialized form of data. """ @@ -253,6 +271,7 @@ class ApiClient(object): for sub_obj in obj) elif isinstance(obj, (datetime.datetime, datetime.date)): return obj.isoformat() + if isinstance(obj, dict): obj_dict = obj else: @@ -264,42 +283,54 @@ class ApiClient(object): obj_dict = {obj.attribute_map[attr]: getattr(obj, attr) for attr, _ in six.iteritems(obj.openapi_types) if getattr(obj, attr) is not None} + return {key: self.sanitize_for_serialization(val) for key, val in six.iteritems(obj_dict)} + def deserialize(self, response, response_type): """Deserializes response into an object. + :param response: RESTResponse object to be deserialized. :param response_type: class literal for deserialized object, or string of class name. + :return: deserialized object. """ # handle file downloading # save response body into a tmp file and return the instance if response_type == "file": return self.__deserialize_file(response) + # fetch data from response object try: data = json.loads(response.data) except ValueError: data = response.data + return self.__deserialize(data, response_type) + def __deserialize(self, data, klass): """Deserializes dict, list, str into an object. + :param data: dict, list or str. :param klass: class literal, or string of class name. + :return: object. """ if data is None: return None + if type(klass) == str: if klass.startswith('list['): sub_kls = re.match(r'list\[(.*)\]', klass).group(1) return [self.__deserialize(sub_data, sub_kls) for sub_data in data] + if klass.startswith('dict('): sub_kls = re.match(r'dict\(([^,]*), (.*)\)', klass).group(2) return {k: self.__deserialize(v, sub_kls) for k, v in six.iteritems(data)} + # convert str to class if klass in self.NATIVE_TYPES_MAPPING: klass = self.NATIVE_TYPES_MAPPING[klass] @@ -307,6 +338,7 @@ class ApiClient(object): klass = getattr({{extPackageName}}.models, klass) else: klass = getattr({{modelPackage}}, klass) + if klass in self.PRIMITIVE_TYPES: return self.__deserialize_primitive(data, klass) elif klass == object: @@ -317,15 +349,18 @@ class ApiClient(object): return self.__deserialize_datetime(data) else: return self.__deserialize_model(data, klass) + def call_api(self, resource_path, method, path_params=None, query_params=None, header_params=None, body=None, post_params=None, files=None, - response_type=None, auth_settings=None, async_req=None, - _return_http_data_only=None, collection_formats=None, - _preload_content=True, _request_timeout=None, _host=None, - _request_auth=None): + response_types_map=None, auth_settings=None, + async_req=None, _return_http_data_only=None, + collection_formats=None,_preload_content=True, + _request_timeout=None, _host=None, _request_auth=None): """Makes the HTTP request (synchronous) and returns deserialized data. + To make an async_req request, set the async_req parameter. + :param resource_path: Path to method endpoint. :param method: Method to call. :param path_params: Path parameters in the url. @@ -366,22 +401,24 @@ class ApiClient(object): return self.__call_api(resource_path, method, path_params, query_params, header_params, body, post_params, files, - response_type, auth_settings, + response_types_map, auth_settings, _return_http_data_only, collection_formats, _preload_content, _request_timeout, _host, _request_auth) + return self.pool.apply_async(self.__call_api, (resource_path, method, path_params, query_params, header_params, body, post_params, files, - response_type, + response_types_map, auth_settings, _return_http_data_only, collection_formats, _preload_content, _request_timeout, _host, _request_auth)) + def request(self, method, url, query_params=None, headers=None, post_params=None, body=None, _preload_content=True, _request_timeout=None): @@ -440,8 +477,10 @@ class ApiClient(object): "http method must be `GET`, `HEAD`, `OPTIONS`," " `POST`, `PATCH`, `PUT` or `DELETE`." ) + def parameters_to_tuples(self, params, collection_formats): """Get parameters as list of tuples, formatting collections. + :param params: Parameters as dict or list of two-tuples :param dict collection_formats: Parameter collection formats :return: Parameters as list of tuples, collections formatted @@ -468,12 +507,15 @@ class ApiClient(object): else: new_params.append((k, v)) return new_params + def files_parameters(self, files=None): """Builds form parameters. + :param files: File parameters. :return: Form parameters with files. """ params = [] + if files: for k, v in six.iteritems(files): if not v: @@ -487,34 +529,45 @@ class ApiClient(object): 'application/octet-stream') params.append( tuple([k, tuple([filename, filedata, mimetype])])) + return params + def select_header_accept(self, accepts): """Returns `Accept` based on an array of accepts provided. + :param accepts: List of headers. :return: Accept (e.g. application/json). """ if not accepts: return + accepts = [x.lower() for x in accepts] + if 'application/json' in accepts: return 'application/json' else: return ', '.join(accepts) + def select_header_content_type(self, content_types): """Returns `Content-Type` based on an array of content_types provided. + :param content_types: List of content-types. :return: Content-Type (e.g. application/json). """ if not content_types: return 'application/json' + content_types = [x.lower() for x in content_types] + if 'application/json' in content_types or '*/*' in content_types: return 'application/json' else: return content_types[0] + def update_params_for_auth(self, headers, querys, auth_settings, request_auth=None): """Updates header and query params based on authentication setting. + :param headers: Header parameters dict to be updated. :param querys: Query parameters tuple list to be updated. :param auth_settings: Authentication setting identifiers list. @@ -523,15 +576,19 @@ class ApiClient(object): """ if not auth_settings: return + if request_auth: self._apply_auth_params(headers, querys, request_auth) return + for auth in auth_settings: auth_setting = self.configuration.auth_settings().get(auth) if auth_setting: self._apply_auth_params(headers, querys, auth_setting) + def _apply_auth_params(self, headers, querys, auth_setting): """Updates the request parameters based on a single auth_setting + :param headers: Header parameters dict to be updated. :param querys: Query parameters tuple list to be updated. :param auth_setting: auth settings for the endpoint @@ -546,28 +603,37 @@ class ApiClient(object): raise ApiValueError( 'Authentication token must be in `query` or `header`' ) + def __deserialize_file(self, response): """Deserializes body to file + Saves response body into a file in a temporary folder, using the filename from the `Content-Disposition` header if provided. + :param response: RESTResponse. :return: file path. """ fd, path = tempfile.mkstemp(dir=self.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) path = os.path.join(os.path.dirname(path), filename) + with open(path, "wb") as f: f.write(response.data) + return path + def __deserialize_primitive(self, data, klass): """Deserializes string to primitive type. + :param data: str. :param klass: class literal. + :return: int, long, float, str, bool. """ try: @@ -576,13 +642,17 @@ class ApiClient(object): return six.text_type(data) except TypeError: return data + def __deserialize_object(self, value): """Return an original value. + :return: object. """ return value + def __deserialize_date(self, string): """Deserializes string to date. + :param string: str. :return: date. """ @@ -595,9 +665,12 @@ class ApiClient(object): status=0, reason="Failed to parse `{0}` as date object".format(string) ) + def __deserialize_datetime(self, string): """Deserializes string to datetime. + The string should be in iso8601 datetime format. + :param string: str. :return: datetime. """ @@ -613,8 +686,10 @@ class ApiClient(object): .format(string) ) ) + def __deserialize_model(self, data, klass): """Deserializes list or dict to model. + :param data: dict, list. :param klass: class literal. :return: model object. @@ -623,8 +698,10 @@ class ApiClient(object): if (hasattr(klass, 'get_real_child_model') and klass.discriminator_value_class_map): has_discriminator = True + if not klass.openapi_types and has_discriminator is False: return data + kwargs = {} if (data is not None and klass.openapi_types is not None and @@ -639,8 +716,9 @@ class ApiClient(object): kwargs[attr] = self.__deserialize(value, attr_type) instance = klass(**kwargs) + if has_discriminator: klass_name = instance.get_real_child_model(data) if klass_name: instance = self.__deserialize(data, klass_name) - return instance \ No newline at end of file + return instance diff --git a/generator-templates/model.mustache b/generator-templates/model.mustache index 596f476..0a8634e 100755 --- a/generator-templates/model.mustache +++ b/generator-templates/model.mustache @@ -37,13 +37,13 @@ class {{classname}}(object): """ openapi_types = { {{#allVars}} - '{{name}}': '{{{dataType}}}'{{#hasMore}},{{/hasMore}} + '{{name}}': '{{{dataType}}}'{{^-last}},{{/-last}} {{/allVars}} } attribute_map = { {{#allVars}} - '{{name}}': '{{baseName}}'{{#hasMore}},{{/hasMore}} + '{{name}}': '{{baseName}}'{{^-last}},{{/-last}} {{/allVars}} } {{#discriminator}} diff --git a/regula/documentreader/webclient/gen/api/default_api.py b/regula/documentreader/webclient/gen/api/default_api.py index c704e94..589511a 100755 --- a/regula/documentreader/webclient/gen/api/default_api.py +++ b/regula/documentreader/webclient/gen/api/default_api.py @@ -145,6 +145,12 @@ def api_process_with_http_info(self, process_request, **kwargs): # noqa: E501 # Authentication setting auth_settings = [] # noqa: E501 + + response_types_map = { + 200: "ProcessResponse", + 400: None, + 403: None, + } return self.api_client.call_api( '/api/process', 'POST', @@ -154,7 +160,7 @@ def api_process_with_http_info(self, process_request, **kwargs): # noqa: E501 body=body_params, post_params=form_params, files=local_var_files, - response_type='ProcessResponse', # noqa: E501 + response_types_map=response_types_map, auth_settings=auth_settings, async_req=local_var_params.get('async_req'), _return_http_data_only=local_var_params.get('_return_http_data_only'), # noqa: E501 @@ -263,6 +269,10 @@ def ping_with_http_info(self, **kwargs): # noqa: E501 # Authentication setting auth_settings = [] # noqa: E501 + + response_types_map = { + 200: "DeviceInfo", + } return self.api_client.call_api( '/api/ping', 'GET', @@ -272,7 +282,7 @@ def ping_with_http_info(self, **kwargs): # noqa: E501 body=body_params, post_params=form_params, files=local_var_files, - response_type='DeviceInfo', # noqa: E501 + response_types_map=response_types_map, auth_settings=auth_settings, async_req=local_var_params.get('async_req'), _return_http_data_only=local_var_params.get('_return_http_data_only'), # noqa: E501 diff --git a/regula/documentreader/webclient/gen/api_client.py b/regula/documentreader/webclient/gen/api_client.py index cf6c69e..a85af4c 100755 --- a/regula/documentreader/webclient/gen/api_client.py +++ b/regula/documentreader/webclient/gen/api_client.py @@ -115,7 +115,7 @@ def set_default_header(self, header_name, header_value): def __call_api( self, resource_path, method, path_params=None, query_params=None, header_params=None, body=None, post_params=None, - files=None, response_type=None, auth_settings=None, + files=None, response_types_map=None, auth_settings=None, _return_http_data_only=None, collection_formats=None, _preload_content=True, _request_timeout=None, _host=None, _request_auth=None): @@ -143,11 +143,13 @@ def __call_api( '{%s}' % k, quote(str(v), safe=config.safe_chars_for_path_param) ) + # query parameters if query_params: query_params = self.sanitize_for_serialization(query_params) query_params = self.parameters_to_tuples(query_params, collection_formats) + # post parameters if post_params or files: post_params = post_params if post_params else [] @@ -155,19 +157,23 @@ def __call_api( post_params = self.parameters_to_tuples(post_params, collection_formats) post_params.extend(self.files_parameters(files)) + # auth setting self.update_params_for_auth( header_params, query_params, auth_settings, request_auth=_request_auth) + # body if body: body = self.sanitize_for_serialization(body) + # request url if _host is None: url = self.configuration.host + resource_path else: # use server/host defined in path or operation instead url = _host + resource_path + try: # perform request and return response response_data = self.request( @@ -178,29 +184,40 @@ def __call_api( except ApiException as e: e.body = e.body.decode('utf-8') if six.PY3 else e.body raise e - content_type = response_data.getheader('content-type') + self.last_response = response_data + return_data = response_data + if not _preload_content: return return_data + + response_type = response_types_map.get(response_data.status, None) + if six.PY3 and response_type not in ["file", "bytes"]: match = None + content_type = response_data.getheader('content-type') if content_type is not None: match = re.search(r"charset=([a-zA-Z\-\d]+)[\s\;]?", content_type) encoding = match.group(1) if match else "utf-8" response_data.data = response_data.data.decode(encoding) + # deserialize response data + if response_type: return_data = self.deserialize(response_data, response_type) else: return_data = None + if _return_http_data_only: return (return_data) else: return (return_data, response_data.status, response_data.getheaders()) + def sanitize_for_serialization(self, obj): """Builds a JSON POST object. + If obj is None, return None. If obj is str, int, long, float, bool, return directly. If obj is datetime.datetime, datetime.date @@ -208,6 +225,7 @@ def sanitize_for_serialization(self, obj): If obj is list, sanitize each element in the list. If obj is dict, return the dict. If obj is OpenAPI model, return the properties dict. + :param obj: The data to serialize. :return: The serialized form of data. """ @@ -223,6 +241,7 @@ def sanitize_for_serialization(self, obj): for sub_obj in obj) elif isinstance(obj, (datetime.datetime, datetime.date)): return obj.isoformat() + if isinstance(obj, dict): obj_dict = obj else: @@ -234,42 +253,54 @@ def sanitize_for_serialization(self, obj): obj_dict = {obj.attribute_map[attr]: getattr(obj, attr) for attr, _ in six.iteritems(obj.openapi_types) if getattr(obj, attr) is not None} + return {key: self.sanitize_for_serialization(val) for key, val in six.iteritems(obj_dict)} + def deserialize(self, response, response_type): """Deserializes response into an object. + :param response: RESTResponse object to be deserialized. :param response_type: class literal for deserialized object, or string of class name. + :return: deserialized object. """ # handle file downloading # save response body into a tmp file and return the instance if response_type == "file": return self.__deserialize_file(response) + # fetch data from response object try: data = json.loads(response.data) except ValueError: data = response.data + return self.__deserialize(data, response_type) + def __deserialize(self, data, klass): """Deserializes dict, list, str into an object. + :param data: dict, list or str. :param klass: class literal, or string of class name. + :return: object. """ if data is None: return None + if type(klass) == str: if klass.startswith('list['): sub_kls = re.match(r'list\[(.*)\]', klass).group(1) return [self.__deserialize(sub_data, sub_kls) for sub_data in data] + if klass.startswith('dict('): sub_kls = re.match(r'dict\(([^,]*), (.*)\)', klass).group(2) return {k: self.__deserialize(v, sub_kls) for k, v in six.iteritems(data)} + # convert str to class if klass in self.NATIVE_TYPES_MAPPING: klass = self.NATIVE_TYPES_MAPPING[klass] @@ -277,6 +308,7 @@ def __deserialize(self, data, klass): klass = getattr(regula.documentreader.webclient.ext.models, klass) else: klass = getattr(regula.documentreader.webclient.gen.models, klass) + if klass in self.PRIMITIVE_TYPES: return self.__deserialize_primitive(data, klass) elif klass == object: @@ -287,15 +319,18 @@ def __deserialize(self, data, klass): return self.__deserialize_datetime(data) else: return self.__deserialize_model(data, klass) + def call_api(self, resource_path, method, path_params=None, query_params=None, header_params=None, body=None, post_params=None, files=None, - response_type=None, auth_settings=None, async_req=None, - _return_http_data_only=None, collection_formats=None, - _preload_content=True, _request_timeout=None, _host=None, - _request_auth=None): + response_types_map=None, auth_settings=None, + async_req=None, _return_http_data_only=None, + collection_formats=None,_preload_content=True, + _request_timeout=None, _host=None, _request_auth=None): """Makes the HTTP request (synchronous) and returns deserialized data. + To make an async_req request, set the async_req parameter. + :param resource_path: Path to method endpoint. :param method: Method to call. :param path_params: Path parameters in the url. @@ -336,22 +371,24 @@ def call_api(self, resource_path, method, return self.__call_api(resource_path, method, path_params, query_params, header_params, body, post_params, files, - response_type, auth_settings, + response_types_map, auth_settings, _return_http_data_only, collection_formats, _preload_content, _request_timeout, _host, _request_auth) + return self.pool.apply_async(self.__call_api, (resource_path, method, path_params, query_params, header_params, body, post_params, files, - response_type, + response_types_map, auth_settings, _return_http_data_only, collection_formats, _preload_content, _request_timeout, _host, _request_auth)) + def request(self, method, url, query_params=None, headers=None, post_params=None, body=None, _preload_content=True, _request_timeout=None): @@ -410,8 +447,10 @@ def request(self, method, url, query_params=None, headers=None, "http method must be `GET`, `HEAD`, `OPTIONS`," " `POST`, `PATCH`, `PUT` or `DELETE`." ) + def parameters_to_tuples(self, params, collection_formats): """Get parameters as list of tuples, formatting collections. + :param params: Parameters as dict or list of two-tuples :param dict collection_formats: Parameter collection formats :return: Parameters as list of tuples, collections formatted @@ -438,12 +477,15 @@ def parameters_to_tuples(self, params, collection_formats): else: new_params.append((k, v)) return new_params + def files_parameters(self, files=None): """Builds form parameters. + :param files: File parameters. :return: Form parameters with files. """ params = [] + if files: for k, v in six.iteritems(files): if not v: @@ -457,34 +499,45 @@ def files_parameters(self, files=None): 'application/octet-stream') params.append( tuple([k, tuple([filename, filedata, mimetype])])) + return params + def select_header_accept(self, accepts): """Returns `Accept` based on an array of accepts provided. + :param accepts: List of headers. :return: Accept (e.g. application/json). """ if not accepts: return + accepts = [x.lower() for x in accepts] + if 'application/json' in accepts: return 'application/json' else: return ', '.join(accepts) + def select_header_content_type(self, content_types): """Returns `Content-Type` based on an array of content_types provided. + :param content_types: List of content-types. :return: Content-Type (e.g. application/json). """ if not content_types: return 'application/json' + content_types = [x.lower() for x in content_types] + if 'application/json' in content_types or '*/*' in content_types: return 'application/json' else: return content_types[0] + def update_params_for_auth(self, headers, querys, auth_settings, request_auth=None): """Updates header and query params based on authentication setting. + :param headers: Header parameters dict to be updated. :param querys: Query parameters tuple list to be updated. :param auth_settings: Authentication setting identifiers list. @@ -493,15 +546,19 @@ def update_params_for_auth(self, headers, querys, auth_settings, """ if not auth_settings: return + if request_auth: self._apply_auth_params(headers, querys, request_auth) return + for auth in auth_settings: auth_setting = self.configuration.auth_settings().get(auth) if auth_setting: self._apply_auth_params(headers, querys, auth_setting) + def _apply_auth_params(self, headers, querys, auth_setting): """Updates the request parameters based on a single auth_setting + :param headers: Header parameters dict to be updated. :param querys: Query parameters tuple list to be updated. :param auth_setting: auth settings for the endpoint @@ -516,28 +573,37 @@ def _apply_auth_params(self, headers, querys, auth_setting): raise ApiValueError( 'Authentication token must be in `query` or `header`' ) + def __deserialize_file(self, response): """Deserializes body to file + Saves response body into a file in a temporary folder, using the filename from the `Content-Disposition` header if provided. + :param response: RESTResponse. :return: file path. """ fd, path = tempfile.mkstemp(dir=self.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) path = os.path.join(os.path.dirname(path), filename) + with open(path, "wb") as f: f.write(response.data) + return path + def __deserialize_primitive(self, data, klass): """Deserializes string to primitive type. + :param data: str. :param klass: class literal. + :return: int, long, float, str, bool. """ try: @@ -546,13 +612,17 @@ def __deserialize_primitive(self, data, klass): return six.text_type(data) except TypeError: return data + def __deserialize_object(self, value): """Return an original value. + :return: object. """ return value + def __deserialize_date(self, string): """Deserializes string to date. + :param string: str. :return: date. """ @@ -565,9 +635,12 @@ def __deserialize_date(self, string): status=0, reason="Failed to parse `{0}` as date object".format(string) ) + def __deserialize_datetime(self, string): """Deserializes string to datetime. + The string should be in iso8601 datetime format. + :param string: str. :return: datetime. """ @@ -583,8 +656,10 @@ def __deserialize_datetime(self, string): .format(string) ) ) + def __deserialize_model(self, data, klass): """Deserializes list or dict to model. + :param data: dict, list. :param klass: class literal. :return: model object. @@ -593,8 +668,10 @@ def __deserialize_model(self, data, klass): if (hasattr(klass, 'get_real_child_model') and klass.discriminator_value_class_map): has_discriminator = True + if not klass.openapi_types and has_discriminator is False: return data + kwargs = {} if (data is not None and klass.openapi_types is not None and @@ -609,8 +686,9 @@ def __deserialize_model(self, data, klass): kwargs[attr] = self.__deserialize(value, attr_type) instance = klass(**kwargs) + if has_discriminator: klass_name = instance.get_real_child_model(data) if klass_name: instance = self.__deserialize(data, klass_name) - return instance \ No newline at end of file + return instance diff --git a/regula/documentreader/webclient/gen/configuration.py b/regula/documentreader/webclient/gen/configuration.py index bc3b0fd..4e23b36 100755 --- a/regula/documentreader/webclient/gen/configuration.py +++ b/regula/documentreader/webclient/gen/configuration.py @@ -72,6 +72,8 @@ class Configuration(object): :param server_operation_variables: Mapping from operation ID to a mapping with string values to replace variables in templated server configuration. The validation of enums is performed for variables with defined enum values before. + :param ssl_ca_cert: str - the path to a file of concatenated CA certificates + in PEM format """ @@ -84,6 +86,7 @@ def __init__(self, host=None, disabled_client_side_validations="", server_index=None, server_variables=None, server_operation_index=None, server_operation_variables=None, + ssl_ca_cert=None, ): """Constructor """ @@ -149,7 +152,7 @@ def __init__(self, host=None, Set this to false to skip verifying SSL certificate when calling API from https server. """ - self.ssl_ca_cert = None + self.ssl_ca_cert = ssl_ca_cert """Set this to customize the certificate file to verify the peer. """ self.cert_file = None @@ -185,6 +188,10 @@ def __init__(self, host=None, # Enable client side validation self.client_side_validation = True + self.socket_options = None + """Options to pass down to the underlying urllib3 socket + """ + def __deepcopy__(self, memo): cls = self.__class__ result = cls.__new__(cls) diff --git a/regula/documentreader/webclient/gen/exceptions.py b/regula/documentreader/webclient/gen/exceptions.py index d50d09e..01c903e 100755 --- a/regula/documentreader/webclient/gen/exceptions.py +++ b/regula/documentreader/webclient/gen/exceptions.py @@ -122,6 +122,30 @@ def __str__(self): return error_message +class NotFoundException(ApiException): + + def __init__(self, status=None, reason=None, http_resp=None): + super(NotFoundException, self).__init__(status, reason, http_resp) + + +class UnauthorizedException(ApiException): + + def __init__(self, status=None, reason=None, http_resp=None): + super(UnauthorizedException, self).__init__(status, reason, http_resp) + + +class ForbiddenException(ApiException): + + def __init__(self, status=None, reason=None, http_resp=None): + super(ForbiddenException, self).__init__(status, reason, http_resp) + + +class ServiceException(ApiException): + + def __init__(self, status=None, reason=None, http_resp=None): + super(ServiceException, self).__init__(status, reason, http_resp) + + def render_path(path_to_item): """Returns a string representation of a path""" result = "" diff --git a/regula/documentreader/webclient/gen/models/result_item.py b/regula/documentreader/webclient/gen/models/result_item.py index 38c2f0c..62c8c6a 100755 --- a/regula/documentreader/webclient/gen/models/result_item.py +++ b/regula/documentreader/webclient/gen/models/result_item.py @@ -45,19 +45,19 @@ class ResultItem(object): } discriminator_value_class_map = { 1 : 'DocumentImageResult', - 3 : 'TextDataResult', - 6 : 'GraphicsResult', - 8 : 'DocumentTypesCandidatesResult', - 9 : 'ChosenDocumentTypeResult', + 102 : 'TextDataResult', + 103 : 'GraphicsResult', 15 : 'LexicalAnalysisResult', 17 : 'TextDataResult', 18 : 'TextDataResult', 19 : 'GraphicsResult', + 3 : 'TextDataResult', 33 : 'StatusResult', 36 : 'TextResult', 37 : 'ImagesResult', - 102 : 'TextDataResult', - 103 : 'GraphicsResult', + 6 : 'GraphicsResult', + 8 : 'DocumentTypesCandidatesResult', + 9 : 'ChosenDocumentTypeResult', } def __init__(self, buf_length=None, light=None, list_idx=None, page_idx=None, result_type=None, local_vars_configuration=None): # noqa: E501 diff --git a/regula/documentreader/webclient/gen/rest.py b/regula/documentreader/webclient/gen/rest.py index 238d14d..bbb1342 100755 --- a/regula/documentreader/webclient/gen/rest.py +++ b/regula/documentreader/webclient/gen/rest.py @@ -12,13 +12,12 @@ import re import ssl -import certifi # python 2 and python 3 compatibility library import six from six.moves.urllib.parse import urlencode import urllib3 -from regula.documentreader.webclient.gen.exceptions import ApiException, ApiValueError +from regula.documentreader.webclient.gen.exceptions import ApiException, UnauthorizedException, ForbiddenException, NotFoundException, ServiceException, ApiValueError logger = logging.getLogger(__name__) @@ -56,13 +55,6 @@ def __init__(self, configuration, pools_size=4, maxsize=None): else: cert_reqs = ssl.CERT_NONE - # ca_certs - if configuration.ssl_ca_cert: - ca_certs = configuration.ssl_ca_cert - else: - # if not set certificate file, use Mozilla's root certificates. - ca_certs = certifi.where() - addition_pool_args = {} if configuration.assert_hostname is not None: addition_pool_args['assert_hostname'] = configuration.assert_hostname # noqa: E501 @@ -70,6 +62,9 @@ def __init__(self, configuration, pools_size=4, maxsize=None): if configuration.retries is not None: addition_pool_args['retries'] = configuration.retries + if configuration.socket_options is not None: + addition_pool_args['socket_options'] = configuration.socket_options + if maxsize is None: if configuration.connection_pool_maxsize is not None: maxsize = configuration.connection_pool_maxsize @@ -82,7 +77,7 @@ def __init__(self, configuration, pools_size=4, maxsize=None): num_pools=pools_size, maxsize=maxsize, cert_reqs=cert_reqs, - ca_certs=ca_certs, + ca_certs=configuration.ssl_ca_cert, cert_file=configuration.cert_file, key_file=configuration.key_file, proxy_url=configuration.proxy, @@ -94,7 +89,7 @@ def __init__(self, configuration, pools_size=4, maxsize=None): num_pools=pools_size, maxsize=maxsize, cert_reqs=cert_reqs, - ca_certs=ca_certs, + ca_certs=configuration.ssl_ca_cert, cert_file=configuration.cert_file, key_file=configuration.key_file, **addition_pool_args @@ -215,6 +210,18 @@ def request(self, method, url, query_params=None, headers=None, 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/update-models.sh b/update-models.sh index 62a4bd4..2a29bfe 100755 --- a/update-models.sh +++ b/update-models.sh @@ -3,6 +3,6 @@ DOCS_DEFINITION_FOLDER="${PWD}/../DocumentReader-web-openapi" \ \ && docker run --user "$(id -u):$(id -g)" --rm -v "${PWD}:/client" -v "$DOCS_DEFINITION_FOLDER:/definitions" \ -openapitools/openapi-generator-cli:v5.0.0-beta2 generate -g python \ +openapitools/openapi-generator-cli:v5.0.0 generate -g python-legacy \ -i /definitions/index.yml -o /client -c /client/generator-config.json \ -t /client/generator-templates