|
21 | 21 | # See the License for the specific language governing permissions and |
22 | 22 | # limitations under the License. |
23 | 23 |
|
| 24 | +import sys |
| 25 | +import time |
| 26 | +from json import loads as json_loads |
| 27 | + |
24 | 28 | import click |
25 | 29 | from tabulate import tabulate |
26 | 30 |
|
27 | 31 | from databricks_cli.click_types import OutputClickType, JsonClickType, RunIdClickType |
28 | 32 | from databricks_cli.jobs.cli import check_version |
29 | | -from databricks_cli.utils import eat_exceptions, CONTEXT_SETTINGS, pretty_format, json_cli_base, \ |
30 | | - truncate_string |
| 33 | +from databricks_cli.utils import eat_exceptions, CONTEXT_SETTINGS, pretty_format, truncate_string, \ |
| 34 | + error_and_quit, backoff_with_jitter |
31 | 35 | from databricks_cli.configure.config import provide_api_client, profile_option, debug_option, \ |
32 | 36 | api_version_option |
33 | 37 | from databricks_cli.runs.api import RunsApi |
|
39 | 43 | help='File containing JSON request to POST to /api/2.*/jobs/runs/submit.') |
40 | 44 | @click.option('--json', default=None, type=JsonClickType(), |
41 | 45 | help=JsonClickType.help('/api/2.*/jobs/runs/submit')) |
| 46 | +@click.option('--wait', is_flag=True, default=False, |
| 47 | + help='Waits for the submitted run to complete.') |
42 | 48 | @api_version_option |
43 | 49 | @debug_option |
44 | 50 | @profile_option |
45 | 51 | @eat_exceptions |
46 | 52 | @provide_api_client |
47 | | -def submit_cli(api_client, json_file, json, version): |
| 53 | +def submit_cli(api_client, json_file, json, wait, version): |
48 | 54 | """ |
49 | | - Submits a one-time run. |
| 55 | + Submits a one-time run and optionally waits for its completion. |
50 | 56 |
|
51 | 57 | The specification for the request json can be found |
52 | 58 | https://docs.databricks.com/api/latest/jobs.html#runs-submit |
53 | 59 | """ |
54 | 60 | check_version(api_client, version) |
55 | | - json_cli_base(json_file, json, lambda json: RunsApi( |
56 | | - api_client).submit_run(json, version=version)) |
| 61 | + if json_file: |
| 62 | + with open(json_file, 'r') as f: |
| 63 | + json = f.read() |
| 64 | + submit_res = RunsApi(api_client).submit_run(json_loads(json), version=version) |
| 65 | + click.echo(pretty_format(submit_res)) |
| 66 | + if wait: |
| 67 | + run_id = submit_res['run_id'] |
| 68 | + completed_states = set(['TERMINATED', 'SKIPPED', 'INTERNAL_ERROR']) |
| 69 | + prev_life_cycle_state = "" |
| 70 | + attempt = 0 |
| 71 | + # Wait for run to complete |
| 72 | + while True: |
| 73 | + run = RunsApi(api_client).get_run(run_id, version=version) |
| 74 | + run_state = run['state'] |
| 75 | + life_cycle_state = run_state['life_cycle_state'] |
| 76 | + if life_cycle_state in completed_states: |
| 77 | + if run_state['result_state'] == 'SUCCESS': |
| 78 | + sys.exit(0) |
| 79 | + else: |
| 80 | + error_and_quit('Run failed with state ' + run_state['result_state'] + |
| 81 | + ' and state message ' + run_state['state_message']) |
| 82 | + if prev_life_cycle_state != life_cycle_state: |
| 83 | + click.echo('Waiting on run to complete. Current state: ' + life_cycle_state + |
| 84 | + '. URL: ' + run['run_page_url'], err=True) |
| 85 | + prev_life_cycle_state = life_cycle_state |
| 86 | + time.sleep(backoff_with_jitter(attempt)) |
| 87 | + attempt += 1 |
57 | 88 |
|
58 | 89 |
|
59 | 90 | def _runs_to_table(runs_json): |
|
0 commit comments