We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
[sample] Error running xgboost_training_cm.py
### Environment

*  How did you deploy Kubeflow Pipelines (KFP)?   GCP marketplace
<!-- For more information, see an overview of KFP installation options: https://www.kubeflow.org/docs/pipelines/installation/overview/. -->
*  KFP version:  1.7.1
<!-- Specify the version of Kubeflow Pipelines that you are using. The version number appears in the left side navigation of user interface.
To find the version number, See version number shows on bottom of KFP UI left sidenav. -->
*  KFP SDK version: 
<!-- Specify the output of the following shell command: $pip3 list | grep kfp -->
```
kfp                      1.8.11
kfp-pipeline-spec        0.1.13
kfp-server-api           1.8.1
```

### Steps to reproduce

<!--
Specify how to reproduce the problem. 
This may include information such as: a description of the process, code snippets, log output, or screenshots.
-->
Follow the steps given in the following link to deploy `xgboost_training_cm.py` 
https://github.com/kubeflow/pipelines/tree/master/samples/core/xgboost_training_cm

### Expected result

<!-- What should the correct behavior be? -->
There shows an error with `dataproc-create-cluster` (the second block)
```
Traceback (most recent call last):
  File "/usr/local/lib/python3.7/runpy.py", line 193, in _run_module_as_main
    "__main__", mod_spec)
  File "/usr/local/lib/python3.7/runpy.py", line 85, in _run_code
    exec(code, run_globals)
  File "/ml/kfp_component/launcher/__main__.py", line 45, in <module>
    main()
  File "/ml/kfp_component/launcher/__main__.py", line 42, in main
    launch(args.file_or_module, args.args)
  File "/ml/kfp_component/launcher/launcher.py", line 45, in launch
    return fire.Fire(module, command=args, name=module.__name__)
  File "/usr/local/lib/python3.7/site-packages/fire/core.py", line 127, in Fire
    component_trace = _Fire(component, args, context, name)
  File "/usr/local/lib/python3.7/site-packages/fire/core.py", line 366, in _Fire
    component, remaining_args)
  File "/usr/local/lib/python3.7/site-packages/fire/core.py", line 542, in _CallCallable
    result = fn(*varargs, **kwargs)
  File "/ml/kfp_component/google/dataproc/_create_cluster.py", line 76, in create_cluster
    client = DataprocClient()
  File "/ml/kfp_component/google/common/_utils.py", line 170, in __init__
    self._build_client()
TypeError: _build_client() takes 0 positional arguments but 1 was given
```

### Materials and Reference

<!-- Help us debug this issue by providing resources such as: sample code, background context, or links to references. -->
N/A

---

<!-- Don't delete message below to encourage users to support your issue! -->
Impacted by this bug? Give it a 👍. We prioritise the issues with the most 👍.


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `components/gcp/container/component_sdk/python/kfp_component/google/common/_utils.py`
Content:
```
1 # Copyright 2018 The Kubeflow Authors
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 #      http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14 
15 import abc
16 import logging
17 import re
18 import os
19 import time
20 from functools import wraps
21 from typing import Any, Callable, Optional, Tuple
22 
23 def normalize_name(name,
24               valid_first_char_pattern='a-zA-Z',
25               valid_char_pattern='0-9a-zA-Z_',
26               invalid_char_placeholder='_',
27               prefix_placeholder='x_'):
28         """Normalize a name to a valid resource name.
29 
30         Uses ``valid_first_char_pattern`` and ``valid_char_pattern`` regex pattern
31         to find invalid characters from ``name`` and replaces them with 
32         ``invalid_char_placeholder`` or prefix the name with ``prefix_placeholder``.
33 
34         Args:
35              name: The name to be normalized.
36              valid_first_char_pattern: The regex pattern for the first character.
37              valid_char_pattern: The regex pattern for all the characters in the name.
38              invalid_char_placeholder: The placeholder to replace invalid characters.
39              prefix_placeholder: The placeholder to prefix the name if the first char 
40                 is invalid.
41         
42         Returns:
43             The normalized name. Unchanged if all characters are valid.
44         """
45         if not name:
46             return name
47         normalized_name = re.sub('[^{}]+'.format(valid_char_pattern), 
48             invalid_char_placeholder, name)
49         if not re.match('[{}]'.format(valid_first_char_pattern), 
50             normalized_name[0]):
51             normalized_name = prefix_placeholder + normalized_name
52         if name != normalized_name:
53             logging.info('Normalize name from "{}" to "{}".'.format(
54                 name, normalized_name))
55         return normalized_name
56 
57 def dump_file(path, content):
58     """Dumps string into local file.
59 
60     Args:
61         path: the local path to the file.
62         content: the string content to dump.
63     """
64     directory = os.path.dirname(path)
65     if not os.path.exists(directory):
66         os.makedirs(directory)
67     elif os.path.exists(path):
68         logging.warning('The file {} will be overwritten.'.format(path))
69     with open(path, 'w') as f:
70             f.write(content)
71 
72 def check_resource_changed(requested_resource, 
73     existing_resource, property_names):
74     """Check if a resource has been changed.
75 
76     The function checks requested resource with existing resource
77     by comparing specified property names. Check fails if any property
78     name in the list is in ``requested_resource`` but its value is
79     different with the value in ``existing_resource``.
80 
81     Args:
82         requested_resource: the user requested resource paylod.
83         existing_resource: the existing resource payload from data storage.
84         property_names: a list of property names.
85 
86     Return:
87         True if ``requested_resource`` has been changed.
88     """
89     for property_name in property_names:
90         if not property_name in requested_resource:
91             continue
92         existing_value = existing_resource.get(property_name, None)
93         if requested_resource[property_name] != existing_value:
94             return True
95     return False
96 
97 def wait_operation_done(get_operation, wait_interval):
98     """Waits for an operation to be done.
99 
100     Args:
101         get_operation: the name of the operation.
102         wait_interval: the wait interview between pulling job
103             status.
104 
105     Returns:
106         The completed operation.
107     """
108     while True:
109         operation = get_operation()
110         operation_name = operation.get('name')
111         done = operation.get('done', False)
112         if not done:
113             logging.info('Operation {} is not done. Wait for {}s.'.format(
114                 operation_name, wait_interval))
115             time.sleep(wait_interval)
116             continue
117         error = operation.get('error', None)
118         if error:
119             raise RuntimeError('Failed to complete operation {}: {} {}'.format(
120                 operation_name,
121                 error.get('code', 'Unknown code'),
122                 error.get('message', 'Unknown message'),
123             ))
124         return operation
125 
126 
127 def with_retries(
128     func: Callable,
129     on_error: Optional[Callable[[], Any]] = None,
130     errors: Tuple[Exception, ...] = Exception,
131     number_of_retries: int = 5,
132     delay: float = 1,
133 ):
134     """Retry decorator.
135 
136     The decorator catches `errors`, calls `on_error` and retries after waiting `delay` seconds.
137 
138     Args:
139         number_of_retries (int): Total number of retries if error is raised.
140         delay (float): Number of seconds to wait between consecutive retries.
141     """
142 
143     @wraps(func)
144     def wrapper(self, *args, **kwargs):
145         remaining_retries = number_of_retries
146         while remaining_retries:
147             try:
148                 return func(self, *args, **kwargs)
149             except errors as e:
150                 remaining_retries -= 1
151                 if not remaining_retries:
152                     raise
153 
154                 logging.warning(
155                     'Caught {}. Retrying in {} seconds...'.format(
156                         e.__class__.__name__, delay
157                     )
158                 )
159 
160                 time.sleep(delay)
161                 if on_error:
162                     on_error()
163 
164     return wrapper
165 
166 
167 class ClientWithRetries:
168 
169     def __init__(self):
170         self._build_client()
171         for name, member in self.__dict__.items():
172             if callable(member) and not name.startswith("_"):
173                 self.__dict__[name] = with_retries(func=member, errors=(BrokenPipeError, IOError), on_error=self._build_client)
174 
175     @abc.abstractmethod
176     def _build_client():
177         raise NotImplementedError()
178
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/components/gcp/container/component_sdk/python/kfp_component/google/common/_utils.py b/components/gcp/container/component_sdk/python/kfp_component/google/common/_utils.py
--- a/components/gcp/container/component_sdk/python/kfp_component/google/common/_utils.py
+++ b/components/gcp/container/component_sdk/python/kfp_component/google/common/_utils.py
@@ -173,5 +173,5 @@
                 self.__dict__[name] = with_retries(func=member, errors=(BrokenPipeError, IOError), on_error=self._build_client)
 
     @abc.abstractmethod
-    def _build_client():
+    def _build_client(self):
         raise NotImplementedError()

{"golden_diff": "diff --git a/components/gcp/container/component_sdk/python/kfp_component/google/common/_utils.py b/components/gcp/container/component_sdk/python/kfp_component/google/common/_utils.py\n--- a/components/gcp/container/component_sdk/python/kfp_component/google/common/_utils.py\n+++ b/components/gcp/container/component_sdk/python/kfp_component/google/common/_utils.py\n@@ -173,5 +173,5 @@\n                 self.__dict__[name] = with_retries(func=member, errors=(BrokenPipeError, IOError), on_error=self._build_client)\n \n     @abc.abstractmethod\n-    def _build_client():\n+    def _build_client(self):\n         raise NotImplementedError()\n", "issue": "[sample] Error running xgboost_training_cm.py\n### Environment\r\n\r\n*  How did you deploy Kubeflow Pipelines (KFP)?   GCP marketplace\r\n<!-- For more information, see an overview of KFP installation options: https://www.kubeflow.org/docs/pipelines/installation/overview/. -->\r\n*  KFP version:  1.7.1\r\n<!-- Specify the version of Kubeflow Pipelines that you are using. The version number appears in the left side navigation of user interface.\r\nTo find the version number, See version number shows on bottom of KFP UI left sidenav. -->\r\n*  KFP SDK version: \r\n<!-- Specify the output of the following shell command: $pip3 list | grep kfp -->\r\n```\r\nkfp                      1.8.11\r\nkfp-pipeline-spec        0.1.13\r\nkfp-server-api           1.8.1\r\n```\r\n\r\n### Steps to reproduce\r\n\r\n<!--\r\nSpecify how to reproduce the problem. \r\nThis may include information such as: a description of the process, code snippets, log output, or screenshots.\r\n-->\r\nFollow the steps given in the following link to deploy `xgboost_training_cm.py` \r\nhttps://github.com/kubeflow/pipelines/tree/master/samples/core/xgboost_training_cm\r\n\r\n### Expected result\r\n\r\n<!-- What should the correct behavior be? -->\r\nThere shows an error with `dataproc-create-cluster` (the second block)\r\n```\r\nTraceback (most recent call last):\r\n  File \"/usr/local/lib/python3.7/runpy.py\", line 193, in _run_module_as_main\r\n    \"__main__\", mod_spec)\r\n  File \"/usr/local/lib/python3.7/runpy.py\", line 85, in _run_code\r\n    exec(code, run_globals)\r\n  File \"/ml/kfp_component/launcher/__main__.py\", line 45, in <module>\r\n    main()\r\n  File \"/ml/kfp_component/launcher/__main__.py\", line 42, in main\r\n    launch(args.file_or_module, args.args)\r\n  File \"/ml/kfp_component/launcher/launcher.py\", line 45, in launch\r\n    return fire.Fire(module, command=args, name=module.__name__)\r\n  File \"/usr/local/lib/python3.7/site-packages/fire/core.py\", line 127, in Fire\r\n    component_trace = _Fire(component, args, context, name)\r\n  File \"/usr/local/lib/python3.7/site-packages/fire/core.py\", line 366, in _Fire\r\n    component, remaining_args)\r\n  File \"/usr/local/lib/python3.7/site-packages/fire/core.py\", line 542, in _CallCallable\r\n    result = fn(*varargs, **kwargs)\r\n  File \"/ml/kfp_component/google/dataproc/_create_cluster.py\", line 76, in create_cluster\r\n    client = DataprocClient()\r\n  File \"/ml/kfp_component/google/common/_utils.py\", line 170, in __init__\r\n    self._build_client()\r\nTypeError: _build_client() takes 0 positional arguments but 1 was given\r\n```\r\n\r\n### Materials and Reference\r\n\r\n<!-- Help us debug this issue by providing resources such as: sample code, background context, or links to references. -->\r\nN/A\r\n\r\n---\r\n\r\n<!-- Don't delete message below to encourage users to support your issue! -->\r\nImpacted by this bug? Give it a \ud83d\udc4d. We prioritise the issues with the most \ud83d\udc4d.\r\n\n", "before_files": [{"content": "# Copyright 2018 The Kubeflow Authors\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\nimport abc\nimport logging\nimport re\nimport os\nimport time\nfrom functools import wraps\nfrom typing import Any, Callable, Optional, Tuple\n\ndef normalize_name(name,\n              valid_first_char_pattern='a-zA-Z',\n              valid_char_pattern='0-9a-zA-Z_',\n              invalid_char_placeholder='_',\n              prefix_placeholder='x_'):\n        \"\"\"Normalize a name to a valid resource name.\n\n        Uses ``valid_first_char_pattern`` and ``valid_char_pattern`` regex pattern\n        to find invalid characters from ``name`` and replaces them with \n        ``invalid_char_placeholder`` or prefix the name with ``prefix_placeholder``.\n\n        Args:\n             name: The name to be normalized.\n             valid_first_char_pattern: The regex pattern for the first character.\n             valid_char_pattern: The regex pattern for all the characters in the name.\n             invalid_char_placeholder: The placeholder to replace invalid characters.\n             prefix_placeholder: The placeholder to prefix the name if the first char \n                is invalid.\n        \n        Returns:\n            The normalized name. Unchanged if all characters are valid.\n        \"\"\"\n        if not name:\n            return name\n        normalized_name = re.sub('[^{}]+'.format(valid_char_pattern), \n            invalid_char_placeholder, name)\n        if not re.match('[{}]'.format(valid_first_char_pattern), \n            normalized_name[0]):\n            normalized_name = prefix_placeholder + normalized_name\n        if name != normalized_name:\n            logging.info('Normalize name from \"{}\" to \"{}\".'.format(\n                name, normalized_name))\n        return normalized_name\n\ndef dump_file(path, content):\n    \"\"\"Dumps string into local file.\n\n    Args:\n        path: the local path to the file.\n        content: the string content to dump.\n    \"\"\"\n    directory = os.path.dirname(path)\n    if not os.path.exists(directory):\n        os.makedirs(directory)\n    elif os.path.exists(path):\n        logging.warning('The file {} will be overwritten.'.format(path))\n    with open(path, 'w') as f:\n            f.write(content)\n\ndef check_resource_changed(requested_resource, \n    existing_resource, property_names):\n    \"\"\"Check if a resource has been changed.\n\n    The function checks requested resource with existing resource\n    by comparing specified property names. Check fails if any property\n    name in the list is in ``requested_resource`` but its value is\n    different with the value in ``existing_resource``.\n\n    Args:\n        requested_resource: the user requested resource paylod.\n        existing_resource: the existing resource payload from data storage.\n        property_names: a list of property names.\n\n    Return:\n        True if ``requested_resource`` has been changed.\n    \"\"\"\n    for property_name in property_names:\n        if not property_name in requested_resource:\n            continue\n        existing_value = existing_resource.get(property_name, None)\n        if requested_resource[property_name] != existing_value:\n            return True\n    return False\n\ndef wait_operation_done(get_operation, wait_interval):\n    \"\"\"Waits for an operation to be done.\n\n    Args:\n        get_operation: the name of the operation.\n        wait_interval: the wait interview between pulling job\n            status.\n\n    Returns:\n        The completed operation.\n    \"\"\"\n    while True:\n        operation = get_operation()\n        operation_name = operation.get('name')\n        done = operation.get('done', False)\n        if not done:\n            logging.info('Operation {} is not done. Wait for {}s.'.format(\n                operation_name, wait_interval))\n            time.sleep(wait_interval)\n            continue\n        error = operation.get('error', None)\n        if error:\n            raise RuntimeError('Failed to complete operation {}: {} {}'.format(\n                operation_name,\n                error.get('code', 'Unknown code'),\n                error.get('message', 'Unknown message'),\n            ))\n        return operation\n\n\ndef with_retries(\n    func: Callable,\n    on_error: Optional[Callable[[], Any]] = None,\n    errors: Tuple[Exception, ...] = Exception,\n    number_of_retries: int = 5,\n    delay: float = 1,\n):\n    \"\"\"Retry decorator.\n\n    The decorator catches `errors`, calls `on_error` and retries after waiting `delay` seconds.\n\n    Args:\n        number_of_retries (int): Total number of retries if error is raised.\n        delay (float): Number of seconds to wait between consecutive retries.\n    \"\"\"\n\n    @wraps(func)\n    def wrapper(self, *args, **kwargs):\n        remaining_retries = number_of_retries\n        while remaining_retries:\n            try:\n                return func(self, *args, **kwargs)\n            except errors as e:\n                remaining_retries -= 1\n                if not remaining_retries:\n                    raise\n\n                logging.warning(\n                    'Caught {}. Retrying in {} seconds...'.format(\n                        e.__class__.__name__, delay\n                    )\n                )\n\n                time.sleep(delay)\n                if on_error:\n                    on_error()\n\n    return wrapper\n\n\nclass ClientWithRetries:\n\n    def __init__(self):\n        self._build_client()\n        for name, member in self.__dict__.items():\n            if callable(member) and not name.startswith(\"_\"):\n                self.__dict__[name] = with_retries(func=member, errors=(BrokenPipeError, IOError), on_error=self._build_client)\n\n    @abc.abstractmethod\n    def _build_client():\n        raise NotImplementedError()\n", "path": "components/gcp/container/component_sdk/python/kfp_component/google/common/_utils.py"}], "after_files": [{"content": "# Copyright 2018 The Kubeflow Authors\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\nimport abc\nimport logging\nimport re\nimport os\nimport time\nfrom functools import wraps\nfrom typing import Any, Callable, Optional, Tuple\n\ndef normalize_name(name,\n              valid_first_char_pattern='a-zA-Z',\n              valid_char_pattern='0-9a-zA-Z_',\n              invalid_char_placeholder='_',\n              prefix_placeholder='x_'):\n        \"\"\"Normalize a name to a valid resource name.\n\n        Uses ``valid_first_char_pattern`` and ``valid_char_pattern`` regex pattern\n        to find invalid characters from ``name`` and replaces them with \n        ``invalid_char_placeholder`` or prefix the name with ``prefix_placeholder``.\n\n        Args:\n             name: The name to be normalized.\n             valid_first_char_pattern: The regex pattern for the first character.\n             valid_char_pattern: The regex pattern for all the characters in the name.\n             invalid_char_placeholder: The placeholder to replace invalid characters.\n             prefix_placeholder: The placeholder to prefix the name if the first char \n                is invalid.\n        \n        Returns:\n            The normalized name. Unchanged if all characters are valid.\n        \"\"\"\n        if not name:\n            return name\n        normalized_name = re.sub('[^{}]+'.format(valid_char_pattern), \n            invalid_char_placeholder, name)\n        if not re.match('[{}]'.format(valid_first_char_pattern), \n            normalized_name[0]):\n            normalized_name = prefix_placeholder + normalized_name\n        if name != normalized_name:\n            logging.info('Normalize name from \"{}\" to \"{}\".'.format(\n                name, normalized_name))\n        return normalized_name\n\ndef dump_file(path, content):\n    \"\"\"Dumps string into local file.\n\n    Args:\n        path: the local path to the file.\n        content: the string content to dump.\n    \"\"\"\n    directory = os.path.dirname(path)\n    if not os.path.exists(directory):\n        os.makedirs(directory)\n    elif os.path.exists(path):\n        logging.warning('The file {} will be overwritten.'.format(path))\n    with open(path, 'w') as f:\n            f.write(content)\n\ndef check_resource_changed(requested_resource, \n    existing_resource, property_names):\n    \"\"\"Check if a resource has been changed.\n\n    The function checks requested resource with existing resource\n    by comparing specified property names. Check fails if any property\n    name in the list is in ``requested_resource`` but its value is\n    different with the value in ``existing_resource``.\n\n    Args:\n        requested_resource: the user requested resource paylod.\n        existing_resource: the existing resource payload from data storage.\n        property_names: a list of property names.\n\n    Return:\n        True if ``requested_resource`` has been changed.\n    \"\"\"\n    for property_name in property_names:\n        if not property_name in requested_resource:\n            continue\n        existing_value = existing_resource.get(property_name, None)\n        if requested_resource[property_name] != existing_value:\n            return True\n    return False\n\ndef wait_operation_done(get_operation, wait_interval):\n    \"\"\"Waits for an operation to be done.\n\n    Args:\n        get_operation: the name of the operation.\n        wait_interval: the wait interview between pulling job\n            status.\n\n    Returns:\n        The completed operation.\n    \"\"\"\n    while True:\n        operation = get_operation()\n        operation_name = operation.get('name')\n        done = operation.get('done', False)\n        if not done:\n            logging.info('Operation {} is not done. Wait for {}s.'.format(\n                operation_name, wait_interval))\n            time.sleep(wait_interval)\n            continue\n        error = operation.get('error', None)\n        if error:\n            raise RuntimeError('Failed to complete operation {}: {} {}'.format(\n                operation_name,\n                error.get('code', 'Unknown code'),\n                error.get('message', 'Unknown message'),\n            ))\n        return operation\n\n\ndef with_retries(\n    func: Callable,\n    on_error: Optional[Callable[[], Any]] = None,\n    errors: Tuple[Exception, ...] = Exception,\n    number_of_retries: int = 5,\n    delay: float = 1,\n):\n    \"\"\"Retry decorator.\n\n    The decorator catches `errors`, calls `on_error` and retries after waiting `delay` seconds.\n\n    Args:\n        number_of_retries (int): Total number of retries if error is raised.\n        delay (float): Number of seconds to wait between consecutive retries.\n    \"\"\"\n\n    @wraps(func)\n    def wrapper(self, *args, **kwargs):\n        remaining_retries = number_of_retries\n        while remaining_retries:\n            try:\n                return func(self, *args, **kwargs)\n            except errors as e:\n                remaining_retries -= 1\n                if not remaining_retries:\n                    raise\n\n                logging.warning(\n                    'Caught {}. Retrying in {} seconds...'.format(\n                        e.__class__.__name__, delay\n                    )\n                )\n\n                time.sleep(delay)\n                if on_error:\n                    on_error()\n\n    return wrapper\n\n\nclass ClientWithRetries:\n\n    def __init__(self):\n        self._build_client()\n        for name, member in self.__dict__.items():\n            if callable(member) and not name.startswith(\"_\"):\n                self.__dict__[name] = with_retries(func=member, errors=(BrokenPipeError, IOError), on_error=self._build_client)\n\n    @abc.abstractmethod\n    def _build_client(self):\n        raise NotImplementedError()\n", "path": "components/gcp/container/component_sdk/python/kfp_component/google/common/_utils.py"}]}