Skip to content

Commit f8acd71

Browse files
authored
Merge branch 'main' into ahosler-patch-2
2 parents 56c69e6 + d5552b1 commit f8acd71

File tree

26 files changed

+408
-148
lines changed

26 files changed

+408
-148
lines changed

THIRD_PARTY_LICENSES.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -453,6 +453,12 @@ mlforecast
453453
* Source code: https://github.com/Nixtla/mlforecast
454454
* Project home: https://github.com/Nixtla/mlforecast
455455

456+
rrcf
457+
* Copyright 2018 kLabUM
458+
* License: MIT License
459+
* Source code: https://github.com/kLabUM/rrcf
460+
* Project home: https://github.com/kLabUM/rrcf
461+
456462
=======
457463
=============================== Licenses ===============================
458464
------------------------------------------------------------------------

ads/common/auth.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ def __post_init__(self):
7373
self.oci_key_profile = self.oci_key_profile or os.environ.get(
7474
"OCI_CONFIG_PROFILE", DEFAULT_PROFILE
7575
)
76-
self.oci_config = self.oci_config or {}
76+
self.oci_config = self.oci_config or {"region": os.environ["OCI_RESOURCE_REGION"]} if os.environ.get("OCI_RESOURCE_REGION") else {}
7777
self.oci_signer_kwargs = self.oci_signer_kwargs or {}
7878
self.oci_client_kwargs = self.oci_client_kwargs or {}
7979

@@ -82,7 +82,7 @@ def set_auth(
8282
auth: Optional[str] = AuthType.API_KEY,
8383
oci_config_location: Optional[str] = DEFAULT_LOCATION,
8484
profile: Optional[str] = DEFAULT_PROFILE,
85-
config: Optional[Dict] = {},
85+
config: Optional[Dict] = {"region": os.environ["OCI_RESOURCE_REGION"]} if os.environ.get("OCI_RESOURCE_REGION") else {},
8686
signer: Optional[Any] = None,
8787
signer_callable: Optional[Callable] = None,
8888
signer_kwargs: Optional[Dict] = {},
@@ -678,7 +678,7 @@ def create_signer(self) -> Dict:
678678
>>> signer_generator = AuthFactory().signerGenerator(AuthType.RESOURCE_PRINCIPAL)
679679
>>> signer_generator(signer_args).create_signer()
680680
"""
681-
configuration = ads.telemetry.update_oci_client_config()
681+
configuration = ads.telemetry.update_oci_client_config(AuthState().oci_config)
682682
signer_dict = {
683683
"config": configuration,
684684
"signer": oci.auth.signers.get_resource_principals_signer(),
@@ -739,7 +739,7 @@ def create_signer(self) -> Dict:
739739
>>> signer_generator = AuthFactory().signerGenerator(AuthType.INSTANCE_PRINCIPAL)
740740
>>> signer_generator(signer_args).create_signer()
741741
"""
742-
configuration = ads.telemetry.update_oci_client_config()
742+
configuration = ads.telemetry.update_oci_client_config(AuthState().oci_config)
743743
signer_dict = {
744744
"config": configuration,
745745
"signer": oci.auth.signers.InstancePrincipalsSecurityTokenSigner(

ads/jobs/builders/infrastructure/dsc_job.py

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -312,7 +312,7 @@ 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":
315+
if not self.artifact:
316316
return
317317
try:
318318
if issubclass(self.artifact.__class__, Artifact):
@@ -487,7 +487,9 @@ def run(self, **kwargs) -> DataScienceJobRun:
487487
oci.data_science.models.DefaultJobConfigurationDetails().swagger_types.keys()
488488
)
489489
env_config_swagger_types = {}
490-
if hasattr(oci.data_science.models, "OcirContainerJobEnvironmentConfigurationDetails"):
490+
if hasattr(
491+
oci.data_science.models, "OcirContainerJobEnvironmentConfigurationDetails"
492+
):
491493
env_config_swagger_types = (
492494
oci.data_science.models.OcirContainerJobEnvironmentConfigurationDetails().swagger_types.keys()
493495
)
@@ -501,7 +503,7 @@ def run(self, **kwargs) -> DataScienceJobRun:
501503
value = kwargs.pop(key)
502504
if key in [
503505
ContainerRuntime.CONST_CMD,
504-
ContainerRuntime.CONST_ENTRYPOINT
506+
ContainerRuntime.CONST_ENTRYPOINT,
505507
] and isinstance(value, str):
506508
value = ContainerRuntimeHandler.split_args(value)
507509
env_config_kwargs[key] = value
@@ -535,9 +537,13 @@ def run(self, **kwargs) -> DataScienceJobRun:
535537

536538
if env_config_kwargs:
537539
env_config_kwargs["jobEnvironmentType"] = "OCIR_CONTAINER"
538-
env_config_override = kwargs.get("job_environment_configuration_override_details", {})
540+
env_config_override = kwargs.get(
541+
"job_environment_configuration_override_details", {}
542+
)
539543
env_config_override.update(env_config_kwargs)
540-
kwargs["job_environment_configuration_override_details"] = env_config_override
544+
kwargs["job_environment_configuration_override_details"] = (
545+
env_config_override
546+
)
541547

542548
wait = kwargs.pop("wait", False)
543549
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/artifact.py

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -183,11 +183,6 @@ def build(self):
183183
if os.path.isdir(source):
184184
basename = os.path.basename(str(source).rstrip("/"))
185185
source = str(source).rstrip("/")
186-
# Runtime must have entrypoint if the source is a directory
187-
if self.runtime and not self.runtime.entrypoint:
188-
raise ValueError(
189-
"Please specify entrypoint when script source is a directory."
190-
)
191186
output = os.path.join(self.temp_dir.name, basename)
192187
shutil.make_archive(
193188
output, "zip", os.path.dirname(source), base_dir=basename

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)