Repository: kubeflow/pipelines

Issue:
[feature] support timeout option for watching
### Feature Area

<!-- Uncomment the labels below which are relevant to this feature: -->
<!-- /area frontend -->
<!-- /area backend -->
/area sdk
<!-- /area samples -->
<!-- /area components -->


### What feature would you like to see?
- When we use `kfp run submit -w`, we have to wait forever when run stay at pending.
- However, I'd like to specify the timeout option with it.

### What is the use case or pain point?
- `kfp run submit -t 60` will wait 60 seconds max, until run be completed
- it would use [kfp client's wait_for_run_completion function](https://github.com/kubeflow/pipelines/blob/6a1b841db923e39016f5c6e66eac8698af27831d/sdk/python/kfp/_client.py#L922)

<!-- It helps us understand the benefit of this feature for your use case. -->

### Is there a workaround currently?

If you guys agree, I'd like to implement this feature.

<!-- Without this feature, how do you accomplish your task today? -->


---

<!-- Don't delete message below to encourage users to support your feature request! -->
Love this idea? Give it a 👍. We prioritize fulfilling features with the most 👍.



Discussion:
Welcome contribution! This seems useful
/assign @anencore94 

Resolving patch:
diff --git a/sdk/python/kfp/cli/run.py b/sdk/python/kfp/cli/run.py
--- a/sdk/python/kfp/cli/run.py
+++ b/sdk/python/kfp/cli/run.py
@@ -58,10 +58,11 @@ def list(ctx, experiment_id, max_size):
 @click.option('-w', '--watch', is_flag=True, default=False,
               help='Watch the run status until it finishes.')
 @click.option('-v', '--version', help='ID of the pipeline version.')
+@click.option('-t', '--timeout', default=0, help='Wait for a run to complete until timeout in seconds.', type=int)
 @click.argument('args', nargs=-1)
 @click.pass_context
 def submit(ctx, experiment_name, run_name, package_file, pipeline_id, pipeline_name, watch,
-           version, args):
+           timeout, version, args):
     """submit a KFP run"""
     client = ctx.obj['client']
     namespace = ctx.obj['namespace']
@@ -81,7 +82,10 @@ def submit(ctx, experiment_name, run_name, package_file, pipeline_id, pipeline_n
     experiment = client.create_experiment(experiment_name)
     run = client.run_pipeline(experiment.id, run_name, package_file, arg_dict, pipeline_id,
                               version_id=version)
-    _display_run(client, namespace, run.id, watch, output_format)
+    if timeout > 0:
+        _wait_for_run_completion(client, run.id, timeout, output_format)
+    else:
+        _display_run(client, namespace, run.id, watch, output_format)
 
 
 @run.command()
@@ -127,6 +131,11 @@ def _display_run(client, namespace, run_id, watch, output_format):
         _print_runs([run], output_format)
 
 
+def _wait_for_run_completion(client, run_id, timeout, output_format):
+    run_detail = client.wait_for_run_completion(run_id, timeout)
+    _print_runs([run_detail.run], output_format)
+
+
 def _print_runs(runs, output_format):
     headers = ['run id', 'name', 'status', 'created at']
     data = [[run.id, run.name, run.status, run.created_at.isoformat()] for run in runs]


Test patch: