Skip to content

Commit babe5ff

Browse files
authored
[ADS OPCTL] Display prebuilt watch command for monitoring jobs with OPCTL. (#225)
2 parents be1e35f + b727750 commit babe5ff

File tree

8 files changed

+62
-22
lines changed

8 files changed

+62
-22
lines changed

ads/opctl/backend/ads_dataflow.py

+6-4
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
from typing import Dict, Union
1212

1313
from ads.opctl.backend.base import Backend
14+
from ads.opctl.decorator.common import print_watch_command
1415
from ads.common.auth import create_signer, AuthContext
1516
from ads.common.oci_client import OCIClientFactory
1617

@@ -114,21 +115,22 @@ def init(
114115
**kwargs,
115116
)
116117

117-
def apply(self):
118+
def apply(self) -> Dict:
118119
"""
119120
Create DataFlow and DataFlow Run from YAML.
120121
"""
121122
# TODO add the logic for build dataflow and dataflow run from YAML.
122123
raise NotImplementedError(f"`apply` hasn't been supported for data flow yet.")
123124

124-
def run(self) -> None:
125+
@print_watch_command
126+
def run(self) -> Dict:
125127
"""
126128
Create DataFlow and DataFlow Run from OCID or cli parameters.
127129
"""
128130
with AuthContext(auth=self.auth_type, profile=self.profile):
129131
if self.config["execution"].get("ocid", None):
130-
data_flow_id = self.config["execution"]["ocid"]
131-
run_id = Job.from_dataflow_job(data_flow_id).run().id
132+
job_id = self.config["execution"]["ocid"]
133+
run_id = Job.from_dataflow_job(job_id).run().id
132134
else:
133135
infra = self.config.get("infrastructure", {})
134136
if any(k not in infra for k in REQUIRED_FIELDS):

ads/opctl/backend/ads_ml_job.py

+7-6
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,10 @@
2727
ScriptRuntime,
2828
)
2929
from ads.opctl import logger
30-
from ads.opctl.backend.base import (
31-
Backend,
32-
RuntimeFactory,
33-
)
30+
from ads.opctl.backend.base import Backend, RuntimeFactory
3431
from ads.opctl.config.resolver import ConfigResolver
3532
from ads.opctl.constants import DEFAULT_IMAGE_SCRIPT_DIR
33+
from ads.opctl.decorator.common import print_watch_command
3634
from ads.opctl.distributed.common.cluster_config_helper import (
3735
ClusterConfigToJobSpecConverter,
3836
)
@@ -126,7 +124,8 @@ def init(
126124
**kwargs,
127125
)
128126

129-
def apply(self) -> None:
127+
@print_watch_command
128+
def apply(self) -> Dict:
130129
"""
131130
Create Job and Job Run from YAML.
132131
"""
@@ -136,8 +135,10 @@ def apply(self) -> None:
136135
job_run = job.run()
137136
print("JOB OCID:", job.id)
138137
print("JOB RUN OCID:", job_run.id)
138+
return {"job_id": job.id, "run_id": job_run.id}
139139

140-
def run(self) -> None:
140+
@print_watch_command
141+
def run(self) -> Dict:
141142
"""
142143
Create Job and Job Run from OCID or cli parameters.
143144
"""

ads/opctl/backend/ads_ml_pipeline.py

+9-3
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
from ads.common.oci_client import OCIClientFactory
1010
from ads.opctl.backend.base import Backend
1111
from ads.opctl.backend.ads_ml_job import JobRuntimeFactory
12+
from ads.opctl.decorator.common import print_watch_command
1213
from ads.pipeline import Pipeline, PipelineRun, PipelineStep, CustomScriptStep
1314

1415
from ads.jobs import PythonRuntime
@@ -34,7 +35,8 @@ def __init__(self, config: Dict) -> None:
3435
self.profile = config["execution"].get("oci_profile", None)
3536
self.client = OCIClientFactory(**self.oci_auth).data_science
3637

37-
def apply(self) -> None:
38+
@print_watch_command
39+
def apply(self) -> Dict:
3840
"""
3941
Create Pipeline and Pipeline Run from YAML.
4042
"""
@@ -44,16 +46,20 @@ def apply(self) -> None:
4446
pipeline_run = pipeline.run()
4547
print("PIPELINE OCID:", pipeline.id)
4648
print("PIPELINE RUN OCID:", pipeline_run.id)
49+
return {"job_id": pipeline.id, "run_id": pipeline_run.id}
4750

48-
def run(self) -> None:
51+
@print_watch_command
52+
def run(self) -> Dict:
4953
"""
5054
Create Pipeline and Pipeline Run from OCID.
5155
"""
5256
pipeline_id = self.config["execution"]["ocid"]
5357
with AuthContext(auth=self.auth_type, profile=self.profile):
5458
pipeline = Pipeline.from_ocid(ocid=pipeline_id)
5559
pipeline_run = pipeline.run()
60+
print("PIPELINE OCID:", pipeline.id)
5661
print("PIPELINE RUN OCID:", pipeline_run.id)
62+
return {"job_id": pipeline.id, "run_id": pipeline_run.id}
5763

5864
def delete(self) -> None:
5965
"""
@@ -84,7 +90,7 @@ def watch(self) -> None:
8490
Watch Pipeline Run from OCID.
8591
"""
8692
run_id = self.config["execution"]["run_id"]
87-
log_type = self.config["execution"]["log_type"]
93+
log_type = self.config["execution"].get("log_type")
8894
with AuthContext(auth=self.auth_type, profile=self.profile):
8995
PipelineRun.from_ocid(run_id).watch(log_type=log_type)
9096

ads/opctl/backend/base.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ def run(self) -> Dict:
3232
3333
Returns
3434
-------
35-
None
35+
Dict
3636
"""
3737

3838
def delete(self) -> None:
@@ -62,13 +62,13 @@ def cancel(self) -> None:
6262
None
6363
"""
6464

65-
def apply(self) -> None:
65+
def apply(self) -> Dict:
6666
"""
6767
Initiate Data Science service from YAML.
6868
6969
Returns
7070
-------
71-
None
71+
Dict
7272
"""
7373

7474
def activate(self) -> None:

ads/opctl/cmds.py

+1
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,7 @@ def run(config: Dict, **kwargs) -> Dict:
246246
if (
247247
"kind" in p.config
248248
and p.config["execution"].get("backend", None) != BACKEND_NAME.LOCAL.value
249+
and "ocid" not in p.config["execution"]
249250
):
250251
p.config["execution"]["backend"] = p.config["kind"]
251252
return _BackendFactory(p.config).backend.apply()

ads/opctl/decorator/__init__.py

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#!/usr/bin/env python
2+
# -*- coding: utf-8; -*-
3+
4+
# Copyright (c) 2023 Oracle and its affiliates.
5+
# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/

ads/opctl/decorator/common.py

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#!/usr/bin/env python
2+
# -*- coding: utf-8; -*-
3+
4+
# Copyright (c) 2023 Oracle and/or its affiliates.
5+
# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/
6+
7+
from typing import Dict, Callable
8+
from functools import wraps
9+
10+
RUN_ID_FIELD = "run_id"
11+
12+
def print_watch_command(func: callable)->Callable:
13+
"""The decorator to help build the `opctl watch` command."""
14+
@wraps(func)
15+
def wrapper(*args, **kwargs)->Dict:
16+
result = func(*args, **kwargs)
17+
if result and isinstance(result, Dict) and RUN_ID_FIELD in result:
18+
msg_header = (
19+
f"{'*' * 40} To monitor the progress of a task, execute the following command {'*' * 40}"
20+
)
21+
print(msg_header)
22+
print(f"ads opctl watch {result[RUN_ID_FIELD]}")
23+
print("*" * len(msg_header))
24+
return result
25+
return wrapper

docs/source/user_guide/cli/opctl/_template/jobs.rst

+6-6
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,12 @@ Prerequisite
77

88
:doc:`Install ADS CLI <../../quickstart>`
99

10-
Running a Pre Defined Job
10+
Running a Pre Defined Job
1111
-------------------------
1212

1313
.. code-block:: shell
1414
15-
ads opctl run -j <job ocid>
15+
ads opctl run --ocid <job ocid>
1616
1717
Delete Job or Job Run
1818
---------------------
@@ -36,15 +36,15 @@ Stop a running cluster using ``cancel`` subcommand.
3636
**Option 1: Using Job OCID and Work Dir**
3737

3838
.. code-block:: shell
39-
40-
ads opctl cancel -j <job ocid> --work-dir <Object storage working directory specified when the cluster was created>
39+
40+
ads opctl cancel <job ocid> --work-dir <Object storage working directory specified when the cluster was created>
4141
4242
**Option 2: Using cluster info file**
4343

4444
Cluster info file is a yaml file with output generated from ``ads opctl run -f``
4545

4646
.. code-block:: shell
47-
48-
ads opctl cancel -j <job ocid> --work-dir <Object storage working directory specified when the cluster was created>
47+
48+
ads opctl cancel <job ocid> --work-dir <Object storage working directory specified when the cluster was created>
4949
5050
This command requires an api key or resource principal setup. The logs are streamed from the logging service. If your job is not attached to logging service, this option will show only the lifecycle state.

0 commit comments

Comments
 (0)