We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
[sdk] Containerized Python Component module not found error 
There is a bug when building a containerized Python component that happens (at least) in the case when the longest path of the import graph ending at the component involves >2 modules. 

### Environment
KFP SDK 2.0.0-beta.6

### Steps to reproduce
For example:

```python
# component.py
from module_one import one
from kfp import dsl

@dsl.component
def comp(): ...
```

```python
# module_one.py
from module_two import two
one = 1
```

```python
# module_two.py
two = 2
```

Then: `kfp component build .`

You get a `No module named` error.

### Expected result

Should build without an error.

### Materials and Reference
Related: https://github.com/kubeflow/pipelines/issues/8353

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `sdk/python/kfp/components/utils.py`
Content:
```
1 # Copyright 2021 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 """Definitions of utils methods."""
15 
16 import importlib
17 import os
18 import re
19 import sys
20 import types
21 from typing import List
22 
23 _COMPONENT_NAME_PREFIX = 'comp-'
24 _EXECUTOR_LABEL_PREFIX = 'exec-'
25 
26 
27 def load_module(module_name: str, module_directory: str) -> types.ModuleType:
28     """Dynamically imports the Python module with the given name and package
29     path.
30 
31     E.g., Assuming there is a file called `my_module.py` under
32     `/some/directory/my_module`, we can use::
33 
34         load_module('my_module', '/some/directory')
35 
36     to effectively `import mymodule`.
37 
38     Args:
39         module_name: The name of the module.
40         package_path: The package under which the specified module resides.
41     """
42     module_spec = importlib.util.spec_from_file_location(
43         name=module_name,
44         location=os.path.join(module_directory, f'{module_name}.py'))
45     module = importlib.util.module_from_spec(module_spec)
46     sys.modules[module_spec.name] = module
47     module_spec.loader.exec_module(module)
48     return module
49 
50 
51 def maybe_rename_for_k8s(name: str) -> str:
52     """Cleans and converts a name to be k8s compatible.
53 
54     Args:
55       name: The original name.
56 
57     Returns:
58       A sanitized name.
59     """
60     return re.sub('-+', '-', re.sub('[^-0-9a-z]+', '-',
61                                     name.lower())).lstrip('-').rstrip('-')
62 
63 
64 def sanitize_input_name(name: str) -> str:
65     """Sanitizes input name."""
66     return re.sub('[^_0-9a-z]+', '_', name.lower()).lstrip('_').rstrip('_')
67 
68 
69 def sanitize_component_name(name: str) -> str:
70     """Sanitizes component name."""
71     return _COMPONENT_NAME_PREFIX + maybe_rename_for_k8s(name)
72 
73 
74 def sanitize_task_name(name: str) -> str:
75     """Sanitizes task name."""
76     return maybe_rename_for_k8s(name)
77 
78 
79 def sanitize_executor_label(label: str) -> str:
80     """Sanitizes executor label."""
81     return _EXECUTOR_LABEL_PREFIX + maybe_rename_for_k8s(label)
82 
83 
84 def make_name_unique_by_adding_index(
85     name: str,
86     collection: List[str],
87     delimiter: str,
88 ) -> str:
89     """Makes a unique name by adding index.
90 
91     The index starts from 2 and increase by 1 until we find a unique name.
92 
93     Args:
94         name: The original name.
95         collection: The collection of existing names.
96         delimiter: The delimiter to connect the original name and an index.
97 
98     Returns:
99         A unique name composed of name+delimiter+next index
100     """
101     unique_name = name
102     if unique_name in collection:
103         for i in range(2, sys.maxsize**10):
104             unique_name = name + delimiter + str(i)
105             if unique_name not in collection:
106                 break
107     return unique_name
108 
109 
110 def validate_pipeline_name(name: str) -> None:
111     """Validate pipeline name.
112 
113     A valid pipeline name should match ^[a-z0-9][a-z0-9-]{0,127}$.
114 
115     Args:
116         name: The pipeline name.
117 
118     Raises:
119         ValueError if the pipeline name doesn't conform to the regular expression.
120     """
121     pattern = re.compile(r'^[a-z0-9][a-z0-9-]{0,127}$')
122     if not pattern.match(name):
123         raise ValueError(
124             'Invalid pipeline name: %s.\n'
125             'Please specify a pipeline name that matches the regular '
126             'expression "^[a-z0-9][a-z0-9-]{0,127}$" using '
127             '`dsl.pipeline(name=...)` decorator.' % name)
128
```
--- 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/sdk/python/kfp/components/utils.py b/sdk/python/kfp/components/utils.py
--- a/sdk/python/kfp/components/utils.py
+++ b/sdk/python/kfp/components/utils.py
@@ -44,6 +44,7 @@
         location=os.path.join(module_directory, f'{module_name}.py'))
     module = importlib.util.module_from_spec(module_spec)
     sys.modules[module_spec.name] = module
+    sys.path.insert(0, str(module_directory))
     module_spec.loader.exec_module(module)
     return module

{"golden_diff": "diff --git a/sdk/python/kfp/components/utils.py b/sdk/python/kfp/components/utils.py\n--- a/sdk/python/kfp/components/utils.py\n+++ b/sdk/python/kfp/components/utils.py\n@@ -44,6 +44,7 @@\n         location=os.path.join(module_directory, f'{module_name}.py'))\n     module = importlib.util.module_from_spec(module_spec)\n     sys.modules[module_spec.name] = module\n+    sys.path.insert(0, str(module_directory))\n     module_spec.loader.exec_module(module)\n     return module\n", "issue": "[sdk] Containerized Python Component module not found error \nThere is a bug when building a containerized Python component that happens (at least) in the case when the longest path of the import graph ending at the component involves >2 modules. \r\n\r\n### Environment\r\nKFP SDK 2.0.0-beta.6\r\n\r\n### Steps to reproduce\r\nFor example:\r\n\r\n```python\r\n# component.py\r\nfrom module_one import one\r\nfrom kfp import dsl\r\n\r\n@dsl.component\r\ndef comp(): ...\r\n```\r\n\r\n```python\r\n# module_one.py\r\nfrom module_two import two\r\none = 1\r\n```\r\n\r\n```python\r\n# module_two.py\r\ntwo = 2\r\n```\r\n\r\nThen: `kfp component build .`\r\n\r\nYou get a `No module named` error.\r\n\r\n### Expected result\r\n\r\nShould build without an error.\r\n\r\n### Materials and Reference\r\nRelated: https://github.com/kubeflow/pipelines/issues/8353\n", "before_files": [{"content": "# Copyright 2021 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\"\"\"Definitions of utils methods.\"\"\"\n\nimport importlib\nimport os\nimport re\nimport sys\nimport types\nfrom typing import List\n\n_COMPONENT_NAME_PREFIX = 'comp-'\n_EXECUTOR_LABEL_PREFIX = 'exec-'\n\n\ndef load_module(module_name: str, module_directory: str) -> types.ModuleType:\n    \"\"\"Dynamically imports the Python module with the given name and package\n    path.\n\n    E.g., Assuming there is a file called `my_module.py` under\n    `/some/directory/my_module`, we can use::\n\n        load_module('my_module', '/some/directory')\n\n    to effectively `import mymodule`.\n\n    Args:\n        module_name: The name of the module.\n        package_path: The package under which the specified module resides.\n    \"\"\"\n    module_spec = importlib.util.spec_from_file_location(\n        name=module_name,\n        location=os.path.join(module_directory, f'{module_name}.py'))\n    module = importlib.util.module_from_spec(module_spec)\n    sys.modules[module_spec.name] = module\n    module_spec.loader.exec_module(module)\n    return module\n\n\ndef maybe_rename_for_k8s(name: str) -> str:\n    \"\"\"Cleans and converts a name to be k8s compatible.\n\n    Args:\n      name: The original name.\n\n    Returns:\n      A sanitized name.\n    \"\"\"\n    return re.sub('-+', '-', re.sub('[^-0-9a-z]+', '-',\n                                    name.lower())).lstrip('-').rstrip('-')\n\n\ndef sanitize_input_name(name: str) -> str:\n    \"\"\"Sanitizes input name.\"\"\"\n    return re.sub('[^_0-9a-z]+', '_', name.lower()).lstrip('_').rstrip('_')\n\n\ndef sanitize_component_name(name: str) -> str:\n    \"\"\"Sanitizes component name.\"\"\"\n    return _COMPONENT_NAME_PREFIX + maybe_rename_for_k8s(name)\n\n\ndef sanitize_task_name(name: str) -> str:\n    \"\"\"Sanitizes task name.\"\"\"\n    return maybe_rename_for_k8s(name)\n\n\ndef sanitize_executor_label(label: str) -> str:\n    \"\"\"Sanitizes executor label.\"\"\"\n    return _EXECUTOR_LABEL_PREFIX + maybe_rename_for_k8s(label)\n\n\ndef make_name_unique_by_adding_index(\n    name: str,\n    collection: List[str],\n    delimiter: str,\n) -> str:\n    \"\"\"Makes a unique name by adding index.\n\n    The index starts from 2 and increase by 1 until we find a unique name.\n\n    Args:\n        name: The original name.\n        collection: The collection of existing names.\n        delimiter: The delimiter to connect the original name and an index.\n\n    Returns:\n        A unique name composed of name+delimiter+next index\n    \"\"\"\n    unique_name = name\n    if unique_name in collection:\n        for i in range(2, sys.maxsize**10):\n            unique_name = name + delimiter + str(i)\n            if unique_name not in collection:\n                break\n    return unique_name\n\n\ndef validate_pipeline_name(name: str) -> None:\n    \"\"\"Validate pipeline name.\n\n    A valid pipeline name should match ^[a-z0-9][a-z0-9-]{0,127}$.\n\n    Args:\n        name: The pipeline name.\n\n    Raises:\n        ValueError if the pipeline name doesn't conform to the regular expression.\n    \"\"\"\n    pattern = re.compile(r'^[a-z0-9][a-z0-9-]{0,127}$')\n    if not pattern.match(name):\n        raise ValueError(\n            'Invalid pipeline name: %s.\\n'\n            'Please specify a pipeline name that matches the regular '\n            'expression \"^[a-z0-9][a-z0-9-]{0,127}$\" using '\n            '`dsl.pipeline(name=...)` decorator.' % name)\n", "path": "sdk/python/kfp/components/utils.py"}], "after_files": [{"content": "# Copyright 2021 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\"\"\"Definitions of utils methods.\"\"\"\n\nimport importlib\nimport os\nimport re\nimport sys\nimport types\nfrom typing import List\n\n_COMPONENT_NAME_PREFIX = 'comp-'\n_EXECUTOR_LABEL_PREFIX = 'exec-'\n\n\ndef load_module(module_name: str, module_directory: str) -> types.ModuleType:\n    \"\"\"Dynamically imports the Python module with the given name and package\n    path.\n\n    E.g., Assuming there is a file called `my_module.py` under\n    `/some/directory/my_module`, we can use::\n\n        load_module('my_module', '/some/directory')\n\n    to effectively `import mymodule`.\n\n    Args:\n        module_name: The name of the module.\n        package_path: The package under which the specified module resides.\n    \"\"\"\n    module_spec = importlib.util.spec_from_file_location(\n        name=module_name,\n        location=os.path.join(module_directory, f'{module_name}.py'))\n    module = importlib.util.module_from_spec(module_spec)\n    sys.modules[module_spec.name] = module\n    sys.path.insert(0, str(module_directory))\n    module_spec.loader.exec_module(module)\n    return module\n\n\ndef maybe_rename_for_k8s(name: str) -> str:\n    \"\"\"Cleans and converts a name to be k8s compatible.\n\n    Args:\n      name: The original name.\n\n    Returns:\n      A sanitized name.\n    \"\"\"\n    return re.sub('-+', '-', re.sub('[^-0-9a-z]+', '-',\n                                    name.lower())).lstrip('-').rstrip('-')\n\n\ndef sanitize_input_name(name: str) -> str:\n    \"\"\"Sanitizes input name.\"\"\"\n    return re.sub('[^_0-9a-z]+', '_', name.lower()).lstrip('_').rstrip('_')\n\n\ndef sanitize_component_name(name: str) -> str:\n    \"\"\"Sanitizes component name.\"\"\"\n    return _COMPONENT_NAME_PREFIX + maybe_rename_for_k8s(name)\n\n\ndef sanitize_task_name(name: str) -> str:\n    \"\"\"Sanitizes task name.\"\"\"\n    return maybe_rename_for_k8s(name)\n\n\ndef sanitize_executor_label(label: str) -> str:\n    \"\"\"Sanitizes executor label.\"\"\"\n    return _EXECUTOR_LABEL_PREFIX + maybe_rename_for_k8s(label)\n\n\ndef make_name_unique_by_adding_index(\n    name: str,\n    collection: List[str],\n    delimiter: str,\n) -> str:\n    \"\"\"Makes a unique name by adding index.\n\n    The index starts from 2 and increase by 1 until we find a unique name.\n\n    Args:\n        name: The original name.\n        collection: The collection of existing names.\n        delimiter: The delimiter to connect the original name and an index.\n\n    Returns:\n        A unique name composed of name+delimiter+next index\n    \"\"\"\n    unique_name = name\n    if unique_name in collection:\n        for i in range(2, sys.maxsize**10):\n            unique_name = name + delimiter + str(i)\n            if unique_name not in collection:\n                break\n    return unique_name\n\n\ndef validate_pipeline_name(name: str) -> None:\n    \"\"\"Validate pipeline name.\n\n    A valid pipeline name should match ^[a-z0-9][a-z0-9-]{0,127}$.\n\n    Args:\n        name: The pipeline name.\n\n    Raises:\n        ValueError if the pipeline name doesn't conform to the regular expression.\n    \"\"\"\n    pattern = re.compile(r'^[a-z0-9][a-z0-9-]{0,127}$')\n    if not pattern.match(name):\n        raise ValueError(\n            'Invalid pipeline name: %s.\\n'\n            'Please specify a pipeline name that matches the regular '\n            'expression \"^[a-z0-9][a-z0-9-]{0,127}$\" using '\n            '`dsl.pipeline(name=...)` decorator.' % name)\n", "path": "sdk/python/kfp/components/utils.py"}]}