We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
allow output artifact store configuration (vs hard coded)
it seems like the output artifacts are always stored in a specific minio service, port, namespace, bucket, secrets, etc (`minio-service.kubeflow:9000`). 

see: https://github.com/kubeflow/pipelines/blob/f40a22a3f4a8e06d20cf3e3f425b5058d5c87e0b/sdk/python/kfp/compiler/_op_to_template.py#L148

it would be great to make it flexible, e.g. allow using S3, or change namespace or bucket names.
i suggest making it configurable, i can do such PR if we agree its needed. 
flexible pipeline service (host) path in client SDK 
when creating an SDK `Client()` the path to `ml-pipeline` API service is loaded from a hard coded value (`ml-pipeline.kubeflow.svc.cluster.local:8888`) which indicate a specific k8s namespace. it can be valuable to load that default value from an env variable, i.e. changing the line in `_client.py` from:

`config.host = host if host else Client.IN_CLUSTER_DNS_NAME`

to:

`config.host = host or os.environ.get('ML_PIPELINE_DNS_NAME',Client.IN_CLUSTER_DNS_NAME)`

also note that when a user provide the `host` parameter, the ipython output points to the API server and not to the UI service (see the logic in `_get_url_prefix()`), it seems like a potential bug

if its acceptable i can submit a PR for the line change above
 

--- 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/ibm-components/watson/train/src/wml-train.py`
Content:
```
1 # Licensed under the Apache License, Version 2.0 (the "License");
2 # you may not use this file except in compliance with the License.
3 # You may obtain a copy of the License at
4 #
5 # http://www.apache.org/licenses/LICENSE-2.0
6 #
7 # Unless required by applicable law or agreed to in writing, software
8 # distributed under the License is distributed on an "AS IS" BASIS,
9 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10 # See the License for the specific language governing permissions and
11 # limitations under the License.
12 
13 # define the function to train a model on wml
14 
15 def getSecret(secret):
16     with open(secret, 'r') as f:
17         res = f.readline().strip('\'')
18     f.close()
19     return res
20 
21 def train(args):
22     from watson_machine_learning_client import WatsonMachineLearningAPIClient
23     from minio import Minio
24     from urllib.parse import urlsplit
25     from pathlib import Path
26     import os,time
27 
28     wml_train_code = args.train_code
29     wml_execution_command = args.execution_command.strip('\'')
30     wml_framework_name = args.framework if args.framework else 'tensorflow'
31     wml_framework_version = args.framework_version if args.framework_version else '1.15'
32     wml_runtime_name = args.runtime if args.runtime else 'python'
33     wml_runtime_version = args.runtime_version if args.runtime_version else '3.6'
34     wml_run_definition = args.run_definition if args.run_definition else 'python-tensorflow-definition'
35     wml_run_name = args.run_name if args.run_name else 'python-tensorflow-run'
36     wml_author_name = args.author_name if args.author_name else 'default-author'
37     wml_compute_name = args.compute_name if args.compute_name else 'k80'
38     wml_compute_nodes = args.compute_nodes if args.compute_nodes else '1'
39 
40     wml_runtime_version_v4 = wml_framework_version + '-py' + wml_runtime_version
41     wml_compute_nodes_v4 = int(wml_compute_nodes)
42 
43     # retrieve credentials
44     wml_url = getSecret("/app/secrets/wml_url")
45     wml_apikey = getSecret("/app/secrets/wml_apikey")
46     wml_instance_id = getSecret("/app/secrets/wml_instance_id")
47 
48     wml_data_source_type = getSecret("/app/secrets/wml_data_source_type")
49     
50     cos_endpoint = getSecret("/app/secrets/cos_endpoint")
51     cos_endpoint_parts = urlsplit(cos_endpoint)
52     if bool(cos_endpoint_parts.scheme):
53         cos_endpoint_hostname = cos_endpoint_parts.hostname
54     else:
55         cos_endpoint_hostname = cos_endpoint
56         cos_endpoint = 'https://' + cos_endpoint
57     cos_access_key = getSecret("/app/secrets/cos_access_key")
58     cos_secret_key = getSecret("/app/secrets/cos_secret_key")
59     cos_input_bucket = getSecret("/app/secrets/cos_input_bucket")
60     cos_output_bucket = getSecret("/app/secrets/cos_output_bucket")
61 
62     # download model code
63     model_code = os.path.join('/app', wml_train_code)
64 
65     cos = Minio(cos_endpoint_hostname,
66                access_key=cos_access_key,
67                secret_key=cos_secret_key,
68                secure=True)
69 
70     cos.fget_object(cos_input_bucket, wml_train_code, model_code)
71 
72     # set up the WML client
73     wml_credentials = {
74                        "url": wml_url,
75                        "instance_id": wml_instance_id,
76                        "apikey": wml_apikey
77                       }
78     client = WatsonMachineLearningAPIClient(wml_credentials)
79     # define the model
80     lib_meta = {
81         client.runtimes.LibraryMetaNames.NAME: wml_run_definition,
82         client.runtimes.LibraryMetaNames.VERSION: wml_framework_version,
83         client.runtimes.LibraryMetaNames.FILEPATH: model_code,
84         client.runtimes.LibraryMetaNames.PLATFORM: {"name": wml_framework_name, "versions": [wml_framework_version]}
85     }
86     # check exisiting library
87     library_details = client.runtimes.get_library_details()
88     for library_detail in library_details['resources']:
89         if library_detail['entity']['name'] == wml_run_definition:
90             # Delete library if exist because we cannot update model_code
91             uid = client.runtimes.get_library_uid(library_detail)
92             client.repository.delete(uid)
93             break
94     custom_library_details = client.runtimes.store_library(lib_meta)
95     custom_library_uid = client.runtimes.get_library_uid(custom_library_details)
96 
97     # create a pipeline with the model definitions included
98     doc = {
99         "doc_type": "pipeline",
100         "version": "2.0",
101         "primary_pipeline": wml_framework_name,
102         "pipelines": [{
103             "id": wml_framework_name,
104             "runtime_ref": "hybrid",
105             "nodes": [{
106                 "id": "training",
107                 "type": "model_node",
108                 "op": "dl_train",
109                 "runtime_ref": wml_run_name,
110                 "inputs": [],
111                 "outputs": [],
112                 "parameters": {
113                     "name": "tf-mnist",
114                     "description": wml_run_definition,
115                     "command": wml_execution_command,
116                     "training_lib_href": "/v4/libraries/"+custom_library_uid,
117                     "compute": {
118                         "name": wml_compute_name,
119                         "nodes": wml_compute_nodes_v4
120                     }
121                 }
122             }]
123         }],
124         "runtimes": [{
125             "id": wml_run_name,
126             "name": wml_framework_name,
127             "version": wml_runtime_version_v4
128         }]
129     }
130 
131     metadata = {
132         client.repository.PipelineMetaNames.NAME: wml_run_name,
133         client.repository.PipelineMetaNames.DOCUMENT: doc
134     }
135     pipeline_id = client.pipelines.get_uid(client.repository.store_pipeline(meta_props=metadata))
136         
137     client.pipelines.get_details(pipeline_id)
138 
139     # start the training run for v4
140     metadata = {
141         client.training.ConfigurationMetaNames.TRAINING_RESULTS_REFERENCE: {
142             "name": "training-results-reference_name",
143             "connection": {
144                 "endpoint_url": cos_endpoint,
145                 "access_key_id": cos_access_key,
146                 "secret_access_key": cos_secret_key
147             },
148             "location": {
149                 "bucket": cos_output_bucket
150             },
151             "type": wml_data_source_type
152         },
153         client.training.ConfigurationMetaNames.TRAINING_DATA_REFERENCES:[{
154             "name": "training_input_data",
155             "type": wml_data_source_type,
156             "connection": {
157                 "endpoint_url": cos_endpoint,
158                 "access_key_id": cos_access_key,
159                 "secret_access_key": cos_secret_key
160             },
161             "location": {
162                 "bucket": cos_input_bucket
163             }
164         }],
165         client.training.ConfigurationMetaNames.PIPELINE_UID: pipeline_id
166     }
167 
168     training_id = client.training.get_uid(client.training.run(meta_props=metadata))
169     print("training_id", client.training.get_details(training_id))
170     print("get status", client.training.get_status(training_id))
171     # for v4
172     run_details = client.training.get_details(training_id)
173     run_uid = training_id
174 
175     # print logs
176     client.training.monitor_logs(run_uid)
177     client.training.monitor_metrics(run_uid)
178 
179     # checking the result
180     status = client.training.get_status(run_uid)
181     print("status: ", status)
182     while status['state'] != 'completed':
183         time.sleep(20)
184         status = client.training.get_status(run_uid)
185     print(status)
186 
187     Path(args.output_run_uid_path).parent.mkdir(parents=True, exist_ok=True)
188     Path(args.output_run_uid_path).write_text(run_uid)
189 
190     # Get training details
191     training_details = client.training.get_details(run_uid)
192     print("training_details", training_details)
193  
194     training_uid = training_details['entity']['results_reference']['location']['training']
195     Path(args.output_training_uid_path).parent.mkdir(parents=True, exist_ok=True)
196     Path(args.output_training_uid_path).write_text(training_uid)
197 
198 if __name__ == "__main__":
199     import argparse
200     parser = argparse.ArgumentParser()
201     parser.add_argument('--train-code', type=str, required=True)
202     parser.add_argument('--execution-command', type=str, required=True)
203     parser.add_argument('--framework', type=str)
204     parser.add_argument('--framework-version', type=str)
205     parser.add_argument('--runtime', type=str)
206     parser.add_argument('--runtime-version', type=str)
207     parser.add_argument('--run-definition', type=str)
208     parser.add_argument('--run-name', type=str)
209     parser.add_argument('--author-name', type=str)
210     parser.add_argument('--config', type=str, default="secret_name")
211     parser.add_argument('--compute-name', type=str)
212     parser.add_argument('--compute-nodes', type=str)
213     parser.add_argument('--output-run-uid-path', type=str, default="/tmp/run_uid")
214     parser.add_argument('--output-training-uid-path', type=str, default="/tmp/training_uid")
215     args = parser.parse_args()
216     # Check secret name is not empty
217     if (not args.config):
218         print("Secret for this pipeline is not properly created, exiting with status 1...")
219         exit(1)
220     train(args)
221
```
--- 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/ibm-components/watson/train/src/wml-train.py b/components/ibm-components/watson/train/src/wml-train.py
--- a/components/ibm-components/watson/train/src/wml-train.py
+++ b/components/ibm-components/watson/train/src/wml-train.py
@@ -191,9 +191,8 @@
     training_details = client.training.get_details(run_uid)
     print("training_details", training_details)
  
-    training_uid = training_details['entity']['results_reference']['location']['training']
     Path(args.output_training_uid_path).parent.mkdir(parents=True, exist_ok=True)
-    Path(args.output_training_uid_path).write_text(training_uid)
+    Path(args.output_training_uid_path).write_text(run_uid)
 
 if __name__ == "__main__":
     import argparse

{"golden_diff": "diff --git a/components/ibm-components/watson/train/src/wml-train.py b/components/ibm-components/watson/train/src/wml-train.py\n--- a/components/ibm-components/watson/train/src/wml-train.py\n+++ b/components/ibm-components/watson/train/src/wml-train.py\n@@ -191,9 +191,8 @@\n     training_details = client.training.get_details(run_uid)\n     print(\"training_details\", training_details)\n  \n-    training_uid = training_details['entity']['results_reference']['location']['training']\n     Path(args.output_training_uid_path).parent.mkdir(parents=True, exist_ok=True)\n-    Path(args.output_training_uid_path).write_text(training_uid)\n+    Path(args.output_training_uid_path).write_text(run_uid)\n \n if __name__ == \"__main__\":\n     import argparse\n", "issue": "allow output artifact store configuration (vs hard coded)\nit seems like the output artifacts are always stored in a specific minio service, port, namespace, bucket, secrets, etc (`minio-service.kubeflow:9000`). \r\n\r\nsee: https://github.com/kubeflow/pipelines/blob/f40a22a3f4a8e06d20cf3e3f425b5058d5c87e0b/sdk/python/kfp/compiler/_op_to_template.py#L148\r\n\r\nit would be great to make it flexible, e.g. allow using S3, or change namespace or bucket names.\r\ni suggest making it configurable, i can do such PR if we agree its needed. \nflexible pipeline service (host) path in client SDK \nwhen creating an SDK `Client()` the path to `ml-pipeline` API service is loaded from a hard coded value (`ml-pipeline.kubeflow.svc.cluster.local:8888`) which indicate a specific k8s namespace. it can be valuable to load that default value from an env variable, i.e. changing the line in `_client.py` from:\r\n\r\n`config.host = host if host else Client.IN_CLUSTER_DNS_NAME`\r\n\r\nto:\r\n\r\n`config.host = host or os.environ.get('ML_PIPELINE_DNS_NAME',Client.IN_CLUSTER_DNS_NAME)`\r\n\r\nalso note that when a user provide the `host` parameter, the ipython output points to the API server and not to the UI service (see the logic in `_get_url_prefix()`), it seems like a potential bug\r\n\r\nif its acceptable i can submit a PR for the line change above\r\n \n", "before_files": [{"content": "# 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\n# define the function to train a model on wml\n\ndef getSecret(secret):\n    with open(secret, 'r') as f:\n        res = f.readline().strip('\\'')\n    f.close()\n    return res\n\ndef train(args):\n    from watson_machine_learning_client import WatsonMachineLearningAPIClient\n    from minio import Minio\n    from urllib.parse import urlsplit\n    from pathlib import Path\n    import os,time\n\n    wml_train_code = args.train_code\n    wml_execution_command = args.execution_command.strip('\\'')\n    wml_framework_name = args.framework if args.framework else 'tensorflow'\n    wml_framework_version = args.framework_version if args.framework_version else '1.15'\n    wml_runtime_name = args.runtime if args.runtime else 'python'\n    wml_runtime_version = args.runtime_version if args.runtime_version else '3.6'\n    wml_run_definition = args.run_definition if args.run_definition else 'python-tensorflow-definition'\n    wml_run_name = args.run_name if args.run_name else 'python-tensorflow-run'\n    wml_author_name = args.author_name if args.author_name else 'default-author'\n    wml_compute_name = args.compute_name if args.compute_name else 'k80'\n    wml_compute_nodes = args.compute_nodes if args.compute_nodes else '1'\n\n    wml_runtime_version_v4 = wml_framework_version + '-py' + wml_runtime_version\n    wml_compute_nodes_v4 = int(wml_compute_nodes)\n\n    # retrieve credentials\n    wml_url = getSecret(\"/app/secrets/wml_url\")\n    wml_apikey = getSecret(\"/app/secrets/wml_apikey\")\n    wml_instance_id = getSecret(\"/app/secrets/wml_instance_id\")\n\n    wml_data_source_type = getSecret(\"/app/secrets/wml_data_source_type\")\n    \n    cos_endpoint = getSecret(\"/app/secrets/cos_endpoint\")\n    cos_endpoint_parts = urlsplit(cos_endpoint)\n    if bool(cos_endpoint_parts.scheme):\n        cos_endpoint_hostname = cos_endpoint_parts.hostname\n    else:\n        cos_endpoint_hostname = cos_endpoint\n        cos_endpoint = 'https://' + cos_endpoint\n    cos_access_key = getSecret(\"/app/secrets/cos_access_key\")\n    cos_secret_key = getSecret(\"/app/secrets/cos_secret_key\")\n    cos_input_bucket = getSecret(\"/app/secrets/cos_input_bucket\")\n    cos_output_bucket = getSecret(\"/app/secrets/cos_output_bucket\")\n\n    # download model code\n    model_code = os.path.join('/app', wml_train_code)\n\n    cos = Minio(cos_endpoint_hostname,\n               access_key=cos_access_key,\n               secret_key=cos_secret_key,\n               secure=True)\n\n    cos.fget_object(cos_input_bucket, wml_train_code, model_code)\n\n    # set up the WML client\n    wml_credentials = {\n                       \"url\": wml_url,\n                       \"instance_id\": wml_instance_id,\n                       \"apikey\": wml_apikey\n                      }\n    client = WatsonMachineLearningAPIClient(wml_credentials)\n    # define the model\n    lib_meta = {\n        client.runtimes.LibraryMetaNames.NAME: wml_run_definition,\n        client.runtimes.LibraryMetaNames.VERSION: wml_framework_version,\n        client.runtimes.LibraryMetaNames.FILEPATH: model_code,\n        client.runtimes.LibraryMetaNames.PLATFORM: {\"name\": wml_framework_name, \"versions\": [wml_framework_version]}\n    }\n    # check exisiting library\n    library_details = client.runtimes.get_library_details()\n    for library_detail in library_details['resources']:\n        if library_detail['entity']['name'] == wml_run_definition:\n            # Delete library if exist because we cannot update model_code\n            uid = client.runtimes.get_library_uid(library_detail)\n            client.repository.delete(uid)\n            break\n    custom_library_details = client.runtimes.store_library(lib_meta)\n    custom_library_uid = client.runtimes.get_library_uid(custom_library_details)\n\n    # create a pipeline with the model definitions included\n    doc = {\n        \"doc_type\": \"pipeline\",\n        \"version\": \"2.0\",\n        \"primary_pipeline\": wml_framework_name,\n        \"pipelines\": [{\n            \"id\": wml_framework_name,\n            \"runtime_ref\": \"hybrid\",\n            \"nodes\": [{\n                \"id\": \"training\",\n                \"type\": \"model_node\",\n                \"op\": \"dl_train\",\n                \"runtime_ref\": wml_run_name,\n                \"inputs\": [],\n                \"outputs\": [],\n                \"parameters\": {\n                    \"name\": \"tf-mnist\",\n                    \"description\": wml_run_definition,\n                    \"command\": wml_execution_command,\n                    \"training_lib_href\": \"/v4/libraries/\"+custom_library_uid,\n                    \"compute\": {\n                        \"name\": wml_compute_name,\n                        \"nodes\": wml_compute_nodes_v4\n                    }\n                }\n            }]\n        }],\n        \"runtimes\": [{\n            \"id\": wml_run_name,\n            \"name\": wml_framework_name,\n            \"version\": wml_runtime_version_v4\n        }]\n    }\n\n    metadata = {\n        client.repository.PipelineMetaNames.NAME: wml_run_name,\n        client.repository.PipelineMetaNames.DOCUMENT: doc\n    }\n    pipeline_id = client.pipelines.get_uid(client.repository.store_pipeline(meta_props=metadata))\n        \n    client.pipelines.get_details(pipeline_id)\n\n    # start the training run for v4\n    metadata = {\n        client.training.ConfigurationMetaNames.TRAINING_RESULTS_REFERENCE: {\n            \"name\": \"training-results-reference_name\",\n            \"connection\": {\n                \"endpoint_url\": cos_endpoint,\n                \"access_key_id\": cos_access_key,\n                \"secret_access_key\": cos_secret_key\n            },\n            \"location\": {\n                \"bucket\": cos_output_bucket\n            },\n            \"type\": wml_data_source_type\n        },\n        client.training.ConfigurationMetaNames.TRAINING_DATA_REFERENCES:[{\n            \"name\": \"training_input_data\",\n            \"type\": wml_data_source_type,\n            \"connection\": {\n                \"endpoint_url\": cos_endpoint,\n                \"access_key_id\": cos_access_key,\n                \"secret_access_key\": cos_secret_key\n            },\n            \"location\": {\n                \"bucket\": cos_input_bucket\n            }\n        }],\n        client.training.ConfigurationMetaNames.PIPELINE_UID: pipeline_id\n    }\n\n    training_id = client.training.get_uid(client.training.run(meta_props=metadata))\n    print(\"training_id\", client.training.get_details(training_id))\n    print(\"get status\", client.training.get_status(training_id))\n    # for v4\n    run_details = client.training.get_details(training_id)\n    run_uid = training_id\n\n    # print logs\n    client.training.monitor_logs(run_uid)\n    client.training.monitor_metrics(run_uid)\n\n    # checking the result\n    status = client.training.get_status(run_uid)\n    print(\"status: \", status)\n    while status['state'] != 'completed':\n        time.sleep(20)\n        status = client.training.get_status(run_uid)\n    print(status)\n\n    Path(args.output_run_uid_path).parent.mkdir(parents=True, exist_ok=True)\n    Path(args.output_run_uid_path).write_text(run_uid)\n\n    # Get training details\n    training_details = client.training.get_details(run_uid)\n    print(\"training_details\", training_details)\n \n    training_uid = training_details['entity']['results_reference']['location']['training']\n    Path(args.output_training_uid_path).parent.mkdir(parents=True, exist_ok=True)\n    Path(args.output_training_uid_path).write_text(training_uid)\n\nif __name__ == \"__main__\":\n    import argparse\n    parser = argparse.ArgumentParser()\n    parser.add_argument('--train-code', type=str, required=True)\n    parser.add_argument('--execution-command', type=str, required=True)\n    parser.add_argument('--framework', type=str)\n    parser.add_argument('--framework-version', type=str)\n    parser.add_argument('--runtime', type=str)\n    parser.add_argument('--runtime-version', type=str)\n    parser.add_argument('--run-definition', type=str)\n    parser.add_argument('--run-name', type=str)\n    parser.add_argument('--author-name', type=str)\n    parser.add_argument('--config', type=str, default=\"secret_name\")\n    parser.add_argument('--compute-name', type=str)\n    parser.add_argument('--compute-nodes', type=str)\n    parser.add_argument('--output-run-uid-path', type=str, default=\"/tmp/run_uid\")\n    parser.add_argument('--output-training-uid-path', type=str, default=\"/tmp/training_uid\")\n    args = parser.parse_args()\n    # Check secret name is not empty\n    if (not args.config):\n        print(\"Secret for this pipeline is not properly created, exiting with status 1...\")\n        exit(1)\n    train(args)\n", "path": "components/ibm-components/watson/train/src/wml-train.py"}], "after_files": [{"content": "# 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\n# define the function to train a model on wml\n\ndef getSecret(secret):\n    with open(secret, 'r') as f:\n        res = f.readline().strip('\\'')\n    f.close()\n    return res\n\ndef train(args):\n    from watson_machine_learning_client import WatsonMachineLearningAPIClient\n    from minio import Minio\n    from urllib.parse import urlsplit\n    from pathlib import Path\n    import os,time\n\n    wml_train_code = args.train_code\n    wml_execution_command = args.execution_command.strip('\\'')\n    wml_framework_name = args.framework if args.framework else 'tensorflow'\n    wml_framework_version = args.framework_version if args.framework_version else '1.15'\n    wml_runtime_name = args.runtime if args.runtime else 'python'\n    wml_runtime_version = args.runtime_version if args.runtime_version else '3.6'\n    wml_run_definition = args.run_definition if args.run_definition else 'python-tensorflow-definition'\n    wml_run_name = args.run_name if args.run_name else 'python-tensorflow-run'\n    wml_author_name = args.author_name if args.author_name else 'default-author'\n    wml_compute_name = args.compute_name if args.compute_name else 'k80'\n    wml_compute_nodes = args.compute_nodes if args.compute_nodes else '1'\n\n    wml_runtime_version_v4 = wml_framework_version + '-py' + wml_runtime_version\n    wml_compute_nodes_v4 = int(wml_compute_nodes)\n\n    # retrieve credentials\n    wml_url = getSecret(\"/app/secrets/wml_url\")\n    wml_apikey = getSecret(\"/app/secrets/wml_apikey\")\n    wml_instance_id = getSecret(\"/app/secrets/wml_instance_id\")\n\n    wml_data_source_type = getSecret(\"/app/secrets/wml_data_source_type\")\n    \n    cos_endpoint = getSecret(\"/app/secrets/cos_endpoint\")\n    cos_endpoint_parts = urlsplit(cos_endpoint)\n    if bool(cos_endpoint_parts.scheme):\n        cos_endpoint_hostname = cos_endpoint_parts.hostname\n    else:\n        cos_endpoint_hostname = cos_endpoint\n        cos_endpoint = 'https://' + cos_endpoint\n    cos_access_key = getSecret(\"/app/secrets/cos_access_key\")\n    cos_secret_key = getSecret(\"/app/secrets/cos_secret_key\")\n    cos_input_bucket = getSecret(\"/app/secrets/cos_input_bucket\")\n    cos_output_bucket = getSecret(\"/app/secrets/cos_output_bucket\")\n\n    # download model code\n    model_code = os.path.join('/app', wml_train_code)\n\n    cos = Minio(cos_endpoint_hostname,\n               access_key=cos_access_key,\n               secret_key=cos_secret_key,\n               secure=True)\n\n    cos.fget_object(cos_input_bucket, wml_train_code, model_code)\n\n    # set up the WML client\n    wml_credentials = {\n                       \"url\": wml_url,\n                       \"instance_id\": wml_instance_id,\n                       \"apikey\": wml_apikey\n                      }\n    client = WatsonMachineLearningAPIClient(wml_credentials)\n    # define the model\n    lib_meta = {\n        client.runtimes.LibraryMetaNames.NAME: wml_run_definition,\n        client.runtimes.LibraryMetaNames.VERSION: wml_framework_version,\n        client.runtimes.LibraryMetaNames.FILEPATH: model_code,\n        client.runtimes.LibraryMetaNames.PLATFORM: {\"name\": wml_framework_name, \"versions\": [wml_framework_version]}\n    }\n    # check exisiting library\n    library_details = client.runtimes.get_library_details()\n    for library_detail in library_details['resources']:\n        if library_detail['entity']['name'] == wml_run_definition:\n            # Delete library if exist because we cannot update model_code\n            uid = client.runtimes.get_library_uid(library_detail)\n            client.repository.delete(uid)\n            break\n    custom_library_details = client.runtimes.store_library(lib_meta)\n    custom_library_uid = client.runtimes.get_library_uid(custom_library_details)\n\n    # create a pipeline with the model definitions included\n    doc = {\n        \"doc_type\": \"pipeline\",\n        \"version\": \"2.0\",\n        \"primary_pipeline\": wml_framework_name,\n        \"pipelines\": [{\n            \"id\": wml_framework_name,\n            \"runtime_ref\": \"hybrid\",\n            \"nodes\": [{\n                \"id\": \"training\",\n                \"type\": \"model_node\",\n                \"op\": \"dl_train\",\n                \"runtime_ref\": wml_run_name,\n                \"inputs\": [],\n                \"outputs\": [],\n                \"parameters\": {\n                    \"name\": \"tf-mnist\",\n                    \"description\": wml_run_definition,\n                    \"command\": wml_execution_command,\n                    \"training_lib_href\": \"/v4/libraries/\"+custom_library_uid,\n                    \"compute\": {\n                        \"name\": wml_compute_name,\n                        \"nodes\": wml_compute_nodes_v4\n                    }\n                }\n            }]\n        }],\n        \"runtimes\": [{\n            \"id\": wml_run_name,\n            \"name\": wml_framework_name,\n            \"version\": wml_runtime_version_v4\n        }]\n    }\n\n    metadata = {\n        client.repository.PipelineMetaNames.NAME: wml_run_name,\n        client.repository.PipelineMetaNames.DOCUMENT: doc\n    }\n    pipeline_id = client.pipelines.get_uid(client.repository.store_pipeline(meta_props=metadata))\n        \n    client.pipelines.get_details(pipeline_id)\n\n    # start the training run for v4\n    metadata = {\n        client.training.ConfigurationMetaNames.TRAINING_RESULTS_REFERENCE: {\n            \"name\": \"training-results-reference_name\",\n            \"connection\": {\n                \"endpoint_url\": cos_endpoint,\n                \"access_key_id\": cos_access_key,\n                \"secret_access_key\": cos_secret_key\n            },\n            \"location\": {\n                \"bucket\": cos_output_bucket\n            },\n            \"type\": wml_data_source_type\n        },\n        client.training.ConfigurationMetaNames.TRAINING_DATA_REFERENCES:[{\n            \"name\": \"training_input_data\",\n            \"type\": wml_data_source_type,\n            \"connection\": {\n                \"endpoint_url\": cos_endpoint,\n                \"access_key_id\": cos_access_key,\n                \"secret_access_key\": cos_secret_key\n            },\n            \"location\": {\n                \"bucket\": cos_input_bucket\n            }\n        }],\n        client.training.ConfigurationMetaNames.PIPELINE_UID: pipeline_id\n    }\n\n    training_id = client.training.get_uid(client.training.run(meta_props=metadata))\n    print(\"training_id\", client.training.get_details(training_id))\n    print(\"get status\", client.training.get_status(training_id))\n    # for v4\n    run_details = client.training.get_details(training_id)\n    run_uid = training_id\n\n    # print logs\n    client.training.monitor_logs(run_uid)\n    client.training.monitor_metrics(run_uid)\n\n    # checking the result\n    status = client.training.get_status(run_uid)\n    print(\"status: \", status)\n    while status['state'] != 'completed':\n        time.sleep(20)\n        status = client.training.get_status(run_uid)\n    print(status)\n\n    Path(args.output_run_uid_path).parent.mkdir(parents=True, exist_ok=True)\n    Path(args.output_run_uid_path).write_text(run_uid)\n\n    # Get training details\n    training_details = client.training.get_details(run_uid)\n    print(\"training_details\", training_details)\n \n    Path(args.output_training_uid_path).parent.mkdir(parents=True, exist_ok=True)\n    Path(args.output_training_uid_path).write_text(run_uid)\n\nif __name__ == \"__main__\":\n    import argparse\n    parser = argparse.ArgumentParser()\n    parser.add_argument('--train-code', type=str, required=True)\n    parser.add_argument('--execution-command', type=str, required=True)\n    parser.add_argument('--framework', type=str)\n    parser.add_argument('--framework-version', type=str)\n    parser.add_argument('--runtime', type=str)\n    parser.add_argument('--runtime-version', type=str)\n    parser.add_argument('--run-definition', type=str)\n    parser.add_argument('--run-name', type=str)\n    parser.add_argument('--author-name', type=str)\n    parser.add_argument('--config', type=str, default=\"secret_name\")\n    parser.add_argument('--compute-name', type=str)\n    parser.add_argument('--compute-nodes', type=str)\n    parser.add_argument('--output-run-uid-path', type=str, default=\"/tmp/run_uid\")\n    parser.add_argument('--output-training-uid-path', type=str, default=\"/tmp/training_uid\")\n    args = parser.parse_args()\n    # Check secret name is not empty\n    if (not args.config):\n        print(\"Secret for this pipeline is not properly created, exiting with status 1...\")\n        exit(1)\n    train(args)\n", "path": "components/ibm-components/watson/train/src/wml-train.py"}]}