Skip to content

Commit 75cd758

Browse files
committed
Support uploading artifact for container job.
1 parent 6ae41bf commit 75cd758

File tree

3 files changed

+48
-34
lines changed

3 files changed

+48
-34
lines changed

ads/jobs/builders/infrastructure/dsc_job.py

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -312,8 +312,6 @@ def _create_with_oci_api(self) -> None:
312312
logger.debug(oci_model)
313313
res = self.client.create_job(oci_model)
314314
self.update_from_oci_model(res.data)
315-
if self.lifecycle_state == "ACTIVE":
316-
return
317315
try:
318316
if issubclass(self.artifact.__class__, Artifact):
319317
with self.artifact as artifact:
@@ -487,7 +485,9 @@ def run(self, **kwargs) -> DataScienceJobRun:
487485
oci.data_science.models.DefaultJobConfigurationDetails().swagger_types.keys()
488486
)
489487
env_config_swagger_types = {}
490-
if hasattr(oci.data_science.models, "OcirContainerJobEnvironmentConfigurationDetails"):
488+
if hasattr(
489+
oci.data_science.models, "OcirContainerJobEnvironmentConfigurationDetails"
490+
):
491491
env_config_swagger_types = (
492492
oci.data_science.models.OcirContainerJobEnvironmentConfigurationDetails().swagger_types.keys()
493493
)
@@ -501,7 +501,7 @@ def run(self, **kwargs) -> DataScienceJobRun:
501501
value = kwargs.pop(key)
502502
if key in [
503503
ContainerRuntime.CONST_CMD,
504-
ContainerRuntime.CONST_ENTRYPOINT
504+
ContainerRuntime.CONST_ENTRYPOINT,
505505
] and isinstance(value, str):
506506
value = ContainerRuntimeHandler.split_args(value)
507507
env_config_kwargs[key] = value
@@ -535,9 +535,13 @@ def run(self, **kwargs) -> DataScienceJobRun:
535535

536536
if env_config_kwargs:
537537
env_config_kwargs["jobEnvironmentType"] = "OCIR_CONTAINER"
538-
env_config_override = kwargs.get("job_environment_configuration_override_details", {})
538+
env_config_override = kwargs.get(
539+
"job_environment_configuration_override_details", {}
540+
)
539541
env_config_override.update(env_config_kwargs)
540-
kwargs["job_environment_configuration_override_details"] = env_config_override
542+
kwargs["job_environment_configuration_override_details"] = (
543+
env_config_override
544+
)
541545

542546
wait = kwargs.pop("wait", False)
543547
run = DataScienceJobRun(**kwargs, **self.auth).create()

ads/jobs/builders/infrastructure/dsc_job_runtime.py

Lines changed: 12 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -181,9 +181,9 @@ def _translate_config(self, runtime: Runtime) -> dict:
181181
"jobType": self.data_science_job.job_type,
182182
}
183183
if runtime.maximum_runtime_in_minutes:
184-
job_configuration_details[
185-
"maximum_runtime_in_minutes"
186-
] = runtime.maximum_runtime_in_minutes
184+
job_configuration_details["maximum_runtime_in_minutes"] = (
185+
runtime.maximum_runtime_in_minutes
186+
)
187187
job_configuration_details["environment_variables"] = self._translate_env(
188188
runtime
189189
)
@@ -310,7 +310,7 @@ def extract(self, dsc_job):
310310
for extraction in extractions:
311311
runtime_spec.update(extraction(dsc_job))
312312
return self.RUNTIME_CLASS(self._format_env_var(runtime_spec))
313-
313+
314314
def _extract_properties(self, dsc_job) -> dict:
315315
"""Extract the job runtime properties from data science job.
316316
@@ -968,23 +968,10 @@ def translate(self, runtime: Runtime) -> dict:
968968
payload["job_environment_configuration_details"] = job_env_config
969969
return payload
970970

971-
def _translate_artifact(self, runtime: Runtime):
972-
"""Specifies a dummy script as the job artifact.
973-
runtime is not used in this method.
974-
975-
Parameters
976-
----------
977-
runtime : Runtime
978-
This is not used.
979-
980-
Returns
981-
-------
982-
str
983-
Path to the dummy script.
984-
"""
985-
return os.path.join(
986-
os.path.dirname(__file__), "../../templates", "container.py"
987-
)
971+
def _translate_artifact(self, runtime: ContainerRuntime):
972+
"""Additional artifact for the container"""
973+
if runtime.artifact_uri:
974+
return ScriptArtifact(runtime.artifact_uri, runtime)
988975

989976
def _translate_env_config(self, runtime: Runtime) -> dict:
990977
"""Converts runtime properties to ``OcirContainerJobEnvironmentConfigurationDetails`` payload required by OCI Data Science job.
@@ -1007,7 +994,7 @@ def _translate_env_config(self, runtime: Runtime) -> dict:
1007994
property = runtime.get_spec(key, None)
1008995
if key in [
1009996
ContainerRuntime.CONST_CMD,
1010-
ContainerRuntime.CONST_ENTRYPOINT
997+
ContainerRuntime.CONST_ENTRYPOINT,
1011998
] and isinstance(property, str):
1012999
property = self.split_args(property)
10131000
if property is not None:
@@ -1063,7 +1050,7 @@ def _extract_envs(self, dsc_job):
10631050
spec[ContainerRuntime.CONST_ENV_VAR] = envs
10641051

10651052
return spec
1066-
1053+
10671054
def _extract_properties(self, dsc_job) -> dict:
10681055
"""Extract the runtime properties from data science job.
10691056
@@ -1078,10 +1065,10 @@ def _extract_properties(self, dsc_job) -> dict:
10781065
A runtime specification dictionary for initializing a runtime.
10791066
"""
10801067
spec = super()._extract_envs(dsc_job)
1081-
1068+
10821069
job_env_config = getattr(dsc_job, "job_environment_configuration_details", None)
10831070
job_env_type = getattr(job_env_config, "job_environment_type", None)
1084-
1071+
10851072
if not (job_env_config and job_env_type == "OCIR_CONTAINER"):
10861073
raise IncompatibleRuntime()
10871074

ads/jobs/builders/runtimes/container_runtime.py

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ class ContainerRuntime(MultiNodeRuntime):
5656
CONST_CMD = "cmd"
5757
CONST_IMAGE_DIGEST = "imageDigest"
5858
CONST_IMAGE_SIGNATURE_ID = "imageSignatureId"
59+
CONST_SCRIPT_PATH = "scriptPathURI"
5960
attribute_map = {
6061
CONST_IMAGE: CONST_IMAGE,
6162
CONST_ENTRYPOINT: CONST_ENTRYPOINT,
@@ -121,7 +122,7 @@ def with_image(
121122
def image_digest(self) -> str:
122123
"""The container image digest."""
123124
return self.get_spec(self.CONST_IMAGE_DIGEST)
124-
125+
125126
def with_image_digest(self, image_digest: str) -> "ContainerRuntime":
126127
"""Sets the digest of custom image.
127128
@@ -136,12 +137,12 @@ def with_image_digest(self, image_digest: str) -> "ContainerRuntime":
136137
The runtime instance.
137138
"""
138139
return self.set_spec(self.CONST_IMAGE_DIGEST, image_digest)
139-
140+
140141
@property
141142
def image_signature_id(self) -> str:
142143
"""The container image signature id."""
143144
return self.get_spec(self.CONST_IMAGE_SIGNATURE_ID)
144-
145+
145146
def with_image_signature_id(self, image_signature_id: str) -> "ContainerRuntime":
146147
"""Sets the signature id of custom image.
147148
@@ -217,3 +218,25 @@ def init(self, **kwargs) -> "ContainerRuntime":
217218
entrypoint=["bash", "--login", "-c"],
218219
cmd="{Container CMD. For MLflow and Operator will be auto generated}",
219220
)
221+
222+
@property
223+
def artifact_uri(self) -> str:
224+
"""The URI of the source code"""
225+
return self.get_spec(self.CONST_SCRIPT_PATH)
226+
227+
def with_artifact(self, uri: str):
228+
"""Specifies the artifact to be added to the container.
229+
230+
Parameters
231+
----------
232+
uri : str
233+
URI to the source code script, which can be any URI supported by fsspec,
234+
including http://, https:// and OCI object storage.
235+
For example: oci://your_bucket@your_namespace/path/to/script.py
236+
237+
Returns
238+
-------
239+
self
240+
The runtime instance.
241+
"""
242+
return self.set_spec(self.CONST_SCRIPT_PATH, uri)

0 commit comments

Comments
 (0)