def init_http_client(self): exception_handler = None \ if self.exception_handler_model is None else getattr(self.exception_handler_model, "handle_exception") self._http_client = HttpClient(self._config, self._http_handler, exception_handler, self._logger)
class Client: def __init__(self): self.preset_headers = {} self._agent = {"User-Agent": "huaweicloud-usdk-python/3.0"} self._logger = self._init_logger() self._credentials = None self._config = None self._endpoint = None self._http_client = None self._http_handler = None self.model_package = None try: exception_handler_model_name = "%s.exception_handler" % self.__module__[:self . __module__ . rindex( '.' )] self.exception_handler_model = importlib.import_module( exception_handler_model_name) except ImportError: self.exception_handler_model = None @classmethod def _init_logger(cls): logger_name = 'HuaweiCloud-SDK-%s' % cls.__name__ logger = logging.getLogger(logger_name) logger.propagate = False return logger def with_config(self, config): self._config = config return self def with_credentials(self, credentials): self._credentials = credentials return self def with_endpoint(self, endpoint): self._endpoint = endpoint return self def with_http_handler(self, http_handler): self._http_handler = http_handler if http_handler is not None else HttpHandler( ) return self def init_http_client(self): exception_handler = None \ if self.exception_handler_model is None else getattr(self.exception_handler_model, "handle_exception") self._http_client = HttpClient(self._config, self._http_handler, exception_handler, self._logger) def add_stream_logger(self, stream, log_level, format_string): self._logger.setLevel(log_level) stream_handler = logging.StreamHandler(stream) stream_handler.setLevel(log_level) formatter = logging.Formatter(format_string if format_string is not None else core_utils.LOG_FORMAT) stream_handler.setFormatter(formatter) if stream_handler not in self._logger.handlers: self._logger.addHandler(stream_handler) def add_file_logger(self, path, log_level, max_bytes, backup_count, format_string): self._logger.setLevel(log_level) file_handler = RotatingFileHandler(path, maxBytes=max_bytes, backupCount=backup_count) file_handler.setLevel(log_level) formatter = logging.Formatter(format_string if format_string is not None else core_utils.LOG_FORMAT) file_handler.setFormatter(formatter) if file_handler not in self._logger.handlers: self._logger.addHandler(file_handler) def get_agent(self): return self._agent def get_credentials(self): return self._credentials def get_http_client(self): return self._http_client def _parse_header_params(self, collection_formats, header_params): header_params = self.post_process_params(header_params) or {} header_params.update(self.preset_headers) if header_params: header_params = http_utils.sanitize_for_serialization( header_params) header_params = dict( http_utils.parameters_to_tuples(header_params, collection_formats)) header_params.update(self._agent) return header_params def _parse_path_params(self, collection_formats, path_params, resource_path, update_path_params): path_params = self.post_process_params(path_params) or {} if path_params: path_params = http_utils.sanitize_for_serialization(path_params) path_params = http_utils.parameters_to_tuples( path_params, collection_formats) for k, v in path_params: resource_path = resource_path.replace('{%s}' % k, quote(str(v), safe='')) if update_path_params: update_path_params = http_utils.sanitize_for_serialization( update_path_params) update_path_params = http_utils.parameters_to_tuples( update_path_params, collection_formats) for k, v in update_path_params: resource_path = resource_path.replace('{%s}' % k, quote(str(v), safe='')) return resource_path def _parse_query_params(self, collection_formats, query_params): query_params = self.post_process_params(query_params) or [] if query_params: query_params = http_utils.sanitize_for_serialization(query_params) query_params = http_utils.parameters_to_tuples( query_params, collection_formats) return query_params def _parse_post_params(self, collection_formats, post_params): post_params = self.post_process_params( post_params) if post_params else {} if post_params: post_params = http_utils.sanitize_for_serialization(post_params) post_params = http_utils.parameters_to_tuples( post_params, collection_formats) return post_params @classmethod def _parse_body(cls, body, post_params): if body: if all([ hasattr(body, '__iter__'), not isinstance(body, (str, bytes, list, tuple, Mapping)) ]): return body body = http_utils.sanitize_for_serialization(body) body = json.dumps(body) elif len(post_params) != 0: body = post_params else: body = "" return body def _is_stream(self, response_type): if type(response_type) == str and hasattr(self.model_package, response_type): klass = getattr(self.model_package, response_type) if issubclass(klass, SdkStreamResponse): return True return False @classmethod def post_process_params(cls, params): if type(params) == dict: for key in list(params.keys()): if params[key] is None: del [params[key]] return params elif type(params) == list: list_filter = filter( lambda x: type(x) == tuple and len(x) == 2 and x[1] is not None, params) return [i for i in list_filter] def skip_authorization(self, request): return request def do_http_request(self, method, resource_path, path_params=None, query_params=None, header_params=None, body=None, post_params=None, response_type=None, response_headers=None, collection_formats=None, request_type=None, async_request=False): url_parse_result = urlparse(self._endpoint) schema = url_parse_result.scheme host = url_parse_result.netloc header_params = self._parse_header_params(collection_formats, header_params) resource_path = self._parse_path_params( collection_formats, path_params, resource_path, self._credentials.get_update_path_params()) query_params = self._parse_query_params(collection_formats, query_params) post_params = self._parse_post_params(collection_formats, post_params) body = self._parse_body(body, post_params) stream = self._is_stream(response_type) sdk_request = SdkRequest(method=method, schema=schema, host=host, resource_path=resource_path, query_params=query_params, header_params=header_params, body=body, stream=stream) if "Authorization" not in header_params: future_request = self._credentials.process_auth_request( sdk_request, self._http_client) else: executor = ThreadPoolExecutor(max_workers=8) future_request = executor.submit(self.skip_authorization, sdk_request) if async_request: executor = ThreadPoolExecutor(max_workers=8) future_response = executor.submit(self._do_http_request_async, future_request, response_type, response_headers) return FutureSdkResponse(future_response, self._logger) else: request = future_request.result() response = self._do_http_request_sync(request) return self.sync_response_handler(response, response_type, response_headers) def _do_http_request_sync(self, request): response = self._http_client.do_request_sync(request) return response def _do_http_request_async(self, future_request, response_type, response_headers): request = future_request.result() future_response = self._http_client.do_request_async( request=request, hooks=[ self.async_response_hook_factory(response_type, response_headers) ]) return future_response def sync_response_handler(self, response, response_type, response_headers): return_data = self.deserialize(response, response_type) self.set_response_status_code(return_data, response) if response_headers is not None and len(response_headers) > 0: self.set_response_headers(return_data, response, response_headers) if not issubclass(return_data.__class__, SdkStreamResponse): return_data.raw_content = response.content return return_data def async_response_hook_factory(self, response_type, response_headers): def response_hook(resp, *args, **kwargs): resp.data = self.sync_response_handler(resp, response_type, response_headers) return response_hook @classmethod def set_response_status_code(cls, return_data, response): setattr(return_data, "status_code", response.status_code) @classmethod def set_response_headers(cls, return_data, response, response_headers): if not hasattr(return_data, "attribute_map"): return for attr in return_data.attribute_map: if getattr(return_data, attr) is not None: continue key_in_response_headers = return_data.attribute_map[attr] if key_in_response_headers in response_headers and key_in_response_headers in response.headers: setattr(return_data, attr, response.headers[key_in_response_headers]) def deserialize(self, response, response_type): if type(response_type) == str and hasattr(self.model_package, response_type): klass = getattr(self.model_package, response_type) if issubclass(klass, SdkStreamResponse): return klass(response) try: data = json.loads(response.text) except ValueError: data = response.text return self._deserialize(data, response_type) def _deserialize(self, data, klass): 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) } if klass in native_types_mapping: klass = native_types_mapping[klass] else: klass = getattr(self.model_package, klass) if klass in primitive_types: return self._deserialize_primitive(data, klass) elif klass == object: return self._deserialize_object(data) elif klass == datetime.date: return self._deserialize_date(data) elif klass == datetime.datetime: return self._deserialize_data_time(data) else: return self._deserialize_model(data, klass) @classmethod def _deserialize_primitive(cls, data, klass): try: return klass(data) except UnicodeEncodeError: return six.text_type(data) except TypeError: return data @classmethod def _deserialize_object(cls, value): return value @classmethod def _deserialize_date(cls, string): try: from dateutil.parser import parse return parse(string if string.endswith("Z") else string + "Z").date() except ImportError: return string except ValueError: return string @classmethod def _deserialize_data_time(cls, string): try: from dateutil.parser import parse return parse(string if string.endswith("Z") else string + "Z") except ImportError: return string except ValueError: return string def _deserialize_model(self, data, klass): if not klass.openapi_types and not hasattr(klass, 'get_real_child_model'): if type(data) == int and hasattr(klass, "_%s" % data): return getattr(klass, "_%s" % data) if type(data) == str and hasattr(klass, re.sub(r'\W+', '_', data).upper()): return getattr(klass, re.sub(r'\W+', '_', data).upper()) if type(data) == bool and hasattr(klass, str(data).upper()): return getattr(klass, str(data).upper()) if type(data) == float and hasattr(klass, ("_%s" % data).replace( '.', '_')): return getattr(klass, ("_%s" % data).replace('.', '_')) return klass() kwargs = {} if klass.openapi_types is not None: for attr, attr_type in six.iteritems(klass.openapi_types): if data is not None and isinstance(data, (list, dict)): if klass.attribute_map[attr] == "body": kwargs[attr] = self._deserialize(data, attr_type) if klass.attribute_map[attr] in data: value = data[klass.attribute_map[attr]] kwargs[attr] = self._deserialize(value, attr_type) instance = klass(**kwargs) if hasattr(instance, 'get_real_child_model'): klass_name = instance.get_real_child_model(data) if klass_name: instance = self._deserialize(data, klass_name) return instance