oracle-ads 2.12.1__py3-none-any.whl → 2.12.3__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. ads/aqua/common/enums.py +9 -0
  2. ads/aqua/common/utils.py +83 -6
  3. ads/aqua/config/config.py +0 -15
  4. ads/aqua/constants.py +2 -0
  5. ads/aqua/extension/deployment_handler.py +2 -0
  6. ads/aqua/extension/finetune_handler.py +1 -2
  7. ads/aqua/extension/ui_handler.py +22 -3
  8. ads/aqua/finetuning/entities.py +5 -4
  9. ads/aqua/finetuning/finetuning.py +13 -8
  10. ads/aqua/model/constants.py +1 -0
  11. ads/aqua/model/entities.py +2 -0
  12. ads/aqua/model/model.py +223 -138
  13. ads/aqua/modeldeployment/deployment.py +106 -62
  14. ads/aqua/modeldeployment/entities.py +10 -2
  15. ads/aqua/ui.py +29 -16
  16. ads/config.py +3 -8
  17. ads/llm/deploy.py +6 -0
  18. ads/llm/guardrails/base.py +0 -1
  19. ads/llm/langchain/plugins/chat_models/oci_data_science.py +118 -41
  20. ads/llm/langchain/plugins/llms/oci_data_science_model_deployment_endpoint.py +18 -14
  21. ads/llm/templates/score_chain.jinja2 +0 -1
  22. ads/model/datascience_model.py +519 -16
  23. ads/model/deployment/model_deployment.py +13 -0
  24. ads/model/deployment/model_deployment_infrastructure.py +34 -0
  25. ads/model/generic_model.py +10 -0
  26. ads/model/model_properties.py +1 -0
  27. ads/model/service/oci_datascience_model.py +28 -0
  28. ads/opctl/operator/common/data/synthetic.csv +16001 -0
  29. ads/opctl/operator/lowcode/anomaly/MLoperator +1 -0
  30. ads/opctl/operator/lowcode/anomaly/const.py +66 -1
  31. ads/opctl/operator/lowcode/anomaly/model/anomaly_merlion.py +161 -0
  32. ads/opctl/operator/lowcode/anomaly/model/autots.py +30 -15
  33. ads/opctl/operator/lowcode/anomaly/model/factory.py +15 -3
  34. ads/opctl/operator/lowcode/anomaly/model/randomcutforest.py +1 -1
  35. ads/opctl/operator/lowcode/anomaly/schema.yaml +10 -0
  36. ads/opctl/operator/lowcode/anomaly/utils.py +3 -0
  37. {oracle_ads-2.12.1.dist-info → oracle_ads-2.12.3.dist-info}/METADATA +2 -1
  38. {oracle_ads-2.12.1.dist-info → oracle_ads-2.12.3.dist-info}/RECORD +41 -41
  39. ads/aqua/config/deployment_config_defaults.json +0 -37
  40. ads/aqua/config/resource_limit_names.json +0 -8
  41. {oracle_ads-2.12.1.dist-info → oracle_ads-2.12.3.dist-info}/LICENSE.txt +0 -0
  42. {oracle_ads-2.12.1.dist-info → oracle_ads-2.12.3.dist-info}/WHEEL +0 -0
  43. {oracle_ads-2.12.1.dist-info → oracle_ads-2.12.3.dist-info}/entry_points.txt +0 -0
@@ -11,12 +11,15 @@ import os
11
11
  import shutil
12
12
  import tempfile
13
13
  from copy import deepcopy
14
- from typing import Dict, List, Optional, Union, Tuple
14
+ from typing import Dict, List, Optional, Tuple, Union
15
15
 
16
16
  import pandas
17
+ import yaml
17
18
  from jsonschema import ValidationError, validate
18
19
 
20
+ from ads.common import oci_client as oc
19
21
  from ads.common import utils
22
+ from ads.common.extended_enum import ExtendedEnumMeta
20
23
  from ads.common.object_storage_details import ObjectStorageDetails
21
24
  from ads.config import (
22
25
  COMPARTMENT_OCID,
@@ -41,7 +44,6 @@ from ads.model.service.oci_datascience_model import (
41
44
  ModelProvenanceNotFoundError,
42
45
  OCIDataScienceModel,
43
46
  )
44
- from ads.common import oci_client as oc
45
47
 
46
48
  logger = logging.getLogger(__name__)
47
49
 
@@ -78,6 +80,345 @@ class InvalidArtifactType(Exception): # pragma: no cover
78
80
  pass
79
81
 
80
82
 
83
+ class CustomerNotificationType(str, metaclass=ExtendedEnumMeta):
84
+ NONE = "NONE"
85
+ ALL = "ALL"
86
+ ON_FAILURE = "ON_FAILURE"
87
+ ON_SUCCESS = "ON_SUCCESS"
88
+
89
+
90
+ class SettingStatus(str, metaclass=ExtendedEnumMeta):
91
+ """Enum to represent the status of retention settings."""
92
+
93
+ PENDING = "PENDING"
94
+ SUCCEEDED = "SUCCEEDED"
95
+ FAILED = "FAILED"
96
+
97
+
98
+ class ModelBackupSetting:
99
+ """
100
+ Class that represents Model Backup Setting Details Metadata.
101
+
102
+ Methods
103
+ -------
104
+ to_dict(self) -> Dict:
105
+ Serializes the backup settings into a dictionary.
106
+ from_dict(cls, data: Dict) -> 'ModelBackupSetting':
107
+ Constructs backup settings from a dictionary.
108
+ to_json(self) -> str:
109
+ Serializes the backup settings into a JSON string.
110
+ from_json(cls, json_str: str) -> 'ModelBackupSetting':
111
+ Constructs backup settings from a JSON string.
112
+ to_yaml(self) -> str:
113
+ Serializes the backup settings into a YAML string.
114
+ validate(self) -> bool:
115
+ Validates the backup settings details.
116
+ """
117
+
118
+ def __init__(
119
+ self,
120
+ is_backup_enabled: Optional[bool] = None,
121
+ backup_region: Optional[str] = None,
122
+ customer_notification_type: Optional[CustomerNotificationType] = None,
123
+ ):
124
+ self.is_backup_enabled = (
125
+ is_backup_enabled if is_backup_enabled is not None else False
126
+ )
127
+ self.backup_region = backup_region
128
+ self.customer_notification_type = (
129
+ customer_notification_type or CustomerNotificationType.NONE
130
+ )
131
+
132
+ def to_dict(self) -> Dict:
133
+ """Serializes the backup settings into a dictionary."""
134
+ return {
135
+ "is_backup_enabled": self.is_backup_enabled,
136
+ "backup_region": self.backup_region,
137
+ "customer_notification_type": self.customer_notification_type,
138
+ }
139
+
140
+ @classmethod
141
+ def from_dict(cls, data: Dict) -> "ModelBackupSetting":
142
+ """Constructs backup settings from a dictionary."""
143
+ return cls(
144
+ is_backup_enabled=data.get("is_backup_enabled"),
145
+ backup_region=data.get("backup_region"),
146
+ customer_notification_type=CustomerNotificationType(
147
+ data.get("customer_notification_type")
148
+ )
149
+ or None,
150
+ )
151
+
152
+ def to_json(self) -> str:
153
+ """Serializes the backup settings into a JSON string."""
154
+ return json.dumps(self.to_dict())
155
+
156
+ @classmethod
157
+ def from_json(cls, json_str) -> "ModelBackupSetting":
158
+ """Constructs backup settings from a JSON string or dictionary."""
159
+ data = json.loads(json_str) if isinstance(json_str, str) else json_str
160
+
161
+ return cls.from_dict(data)
162
+
163
+ def to_yaml(self) -> str:
164
+ """Serializes the backup settings into a YAML string."""
165
+ return yaml.dump(self.to_dict())
166
+
167
+ def validate(self) -> bool:
168
+ """Validates the backup settings details. Returns True if valid, False otherwise."""
169
+ return all([
170
+ isinstance(self.is_backup_enabled, bool),
171
+ not self.backup_region or isinstance(self.backup_region, str),
172
+ isinstance(self.customer_notification_type, str) and self.customer_notification_type in
173
+ CustomerNotificationType.values()
174
+ ])
175
+
176
+ def __repr__(self):
177
+ return self.to_yaml()
178
+
179
+
180
+ class ModelRetentionSetting:
181
+ """
182
+ Class that represents Model Retention Setting Details Metadata.
183
+
184
+ Methods
185
+ -------
186
+ to_dict(self) -> Dict:
187
+ Serializes the retention settings into a dictionary.
188
+ from_dict(cls, data: Dict) -> 'ModelRetentionSetting':
189
+ Constructs retention settings from a dictionary.
190
+ to_json(self) -> str:
191
+ Serializes the retention settings into a JSON string.
192
+ from_json(cls, json_str: str) -> 'ModelRetentionSetting':
193
+ Constructs retention settings from a JSON string.
194
+ to_yaml(self) -> str:
195
+ Serializes the retention settings into a YAML string.
196
+ validate(self) -> bool:
197
+ Validates the retention settings details.
198
+ """
199
+
200
+ def __init__(
201
+ self,
202
+ archive_after_days: Optional[int] = None,
203
+ delete_after_days: Optional[int] = None,
204
+ customer_notification_type: Optional[CustomerNotificationType] = None,
205
+ ):
206
+ self.archive_after_days = archive_after_days
207
+ self.delete_after_days = delete_after_days
208
+ self.customer_notification_type = (
209
+ customer_notification_type or CustomerNotificationType.NONE
210
+ )
211
+
212
+ def to_dict(self) -> Dict:
213
+ """Serializes the retention settings into a dictionary."""
214
+ return {
215
+ "archive_after_days": self.archive_after_days,
216
+ "delete_after_days": self.delete_after_days,
217
+ "customer_notification_type": self.customer_notification_type,
218
+ }
219
+
220
+ @classmethod
221
+ def from_dict(cls, data: Dict) -> "ModelRetentionSetting":
222
+ """Constructs retention settings from a dictionary."""
223
+ return cls(
224
+ archive_after_days=data.get("archive_after_days"),
225
+ delete_after_days=data.get("delete_after_days"),
226
+ customer_notification_type=CustomerNotificationType(
227
+ data.get("customer_notification_type")
228
+ )
229
+ or None,
230
+ )
231
+
232
+ def to_json(self) -> str:
233
+ """Serializes the retention settings into a JSON string."""
234
+ return json.dumps(self.to_dict())
235
+
236
+ @classmethod
237
+ def from_json(cls, json_str) -> "ModelRetentionSetting":
238
+ """Constructs retention settings from a JSON string."""
239
+ data = json.loads(json_str) if isinstance(json_str, str) else json_str
240
+ return cls.from_dict(data)
241
+
242
+ def to_yaml(self) -> str:
243
+ """Serializes the retention settings into a YAML string."""
244
+ return yaml.dump(self.to_dict())
245
+
246
+ def validate(self) -> bool:
247
+ """Validates the retention settings details. Returns True if valid, False otherwise."""
248
+ return all([
249
+ self.archive_after_days is None or (
250
+ isinstance(self.archive_after_days, int) and self.archive_after_days >= 0),
251
+ self.delete_after_days is None or (isinstance(self.delete_after_days, int) and self.delete_after_days >= 0),
252
+ isinstance(self.customer_notification_type, str) and self.customer_notification_type in
253
+ CustomerNotificationType.values()
254
+ ])
255
+
256
+ def __repr__(self):
257
+ return self.to_yaml()
258
+
259
+
260
+ class ModelRetentionOperationDetails:
261
+ """
262
+ Class that represents Model Retention Operation Details Metadata.
263
+
264
+ Methods
265
+ -------
266
+ to_dict(self) -> Dict:
267
+ Serializes the retention operation details into a dictionary.
268
+ from_dict(cls, data: Dict) -> 'ModelRetentionOperationDetails':
269
+ Constructs retention operation details from a dictionary.
270
+ to_json(self) -> str:
271
+ Serializes the retention operation details into a JSON string.
272
+ from_json(cls, json_str: str) -> 'ModelRetentionOperationDetails':
273
+ Constructs retention operation details from a JSON string.
274
+ to_yaml(self) -> str:
275
+ Serializes the retention operation details into a YAML string.
276
+ validate(self) -> bool:
277
+ Validates the retention operation details.
278
+ """
279
+
280
+ def __init__(
281
+ self,
282
+ archive_state: Optional[SettingStatus] = None,
283
+ archive_state_details: Optional[str] = None,
284
+ delete_state: Optional[SettingStatus] = None,
285
+ delete_state_details: Optional[str] = None,
286
+ time_archival_scheduled: Optional[int] = None,
287
+ time_deletion_scheduled: Optional[int] = None,
288
+ ):
289
+ self.archive_state = archive_state
290
+ self.archive_state_details = archive_state_details
291
+ self.delete_state = delete_state
292
+ self.delete_state_details = delete_state_details
293
+ self.time_archival_scheduled = time_archival_scheduled
294
+ self.time_deletion_scheduled = time_deletion_scheduled
295
+
296
+ def to_dict(self) -> Dict:
297
+ """Serializes the retention operation details into a dictionary."""
298
+ return {
299
+ "archive_state": self.archive_state or None,
300
+ "archive_state_details": self.archive_state_details,
301
+ "delete_state": self.delete_state or None,
302
+ "delete_state_details": self.delete_state_details,
303
+ "time_archival_scheduled": self.time_archival_scheduled,
304
+ "time_deletion_scheduled": self.time_deletion_scheduled,
305
+ }
306
+
307
+ @classmethod
308
+ def from_dict(cls, data: Dict) -> "ModelRetentionOperationDetails":
309
+ """Constructs retention operation details from a dictionary."""
310
+ return cls(
311
+ archive_state=SettingStatus(data.get("archive_state")) or None,
312
+ archive_state_details=data.get("archive_state_details"),
313
+ delete_state=SettingStatus(data.get("delete_state")) or None,
314
+ delete_state_details=data.get("delete_state_details"),
315
+ time_archival_scheduled=data.get("time_archival_scheduled"),
316
+ time_deletion_scheduled=data.get("time_deletion_scheduled"),
317
+ )
318
+
319
+ def to_json(self) -> str:
320
+ """Serializes the retention operation details into a JSON string."""
321
+ return json.dumps(self.to_dict())
322
+
323
+ @classmethod
324
+ def from_json(cls, json_str: str) -> "ModelRetentionOperationDetails":
325
+ """Constructs retention operation details from a JSON string."""
326
+ data = json.loads(json_str)
327
+ return cls.from_dict(data)
328
+
329
+ def to_yaml(self) -> str:
330
+ """Serializes the retention operation details into a YAML string."""
331
+ return yaml.dump(self.to_dict())
332
+
333
+ def validate(self) -> bool:
334
+ """Validates the retention operation details."""
335
+ return all(
336
+ [
337
+ self.archive_state is None or self.archive_state in SettingStatus.values(),
338
+ self.delete_state is None or self.delete_state in SettingStatus.values(),
339
+ self.time_archival_scheduled is None
340
+ or isinstance(self.time_archival_scheduled, int),
341
+ self.time_deletion_scheduled is None
342
+ or isinstance(self.time_deletion_scheduled, int),
343
+ ]
344
+ )
345
+
346
+ def __repr__(self):
347
+ return self.to_yaml()
348
+
349
+
350
+ class ModelBackupOperationDetails:
351
+ """
352
+ Class that represents Model Backup Operation Details Metadata.
353
+
354
+ Methods
355
+ -------
356
+ to_dict(self) -> Dict:
357
+ Serializes the backup operation details into a dictionary.
358
+ from_dict(cls, data: Dict) -> 'ModelBackupOperationDetails':
359
+ Constructs backup operation details from a dictionary.
360
+ to_json(self) -> str:
361
+ Serializes the backup operation details into a JSON string.
362
+ from_json(cls, json_str: str) -> 'ModelBackupOperationDetails':
363
+ Constructs backup operation details from a JSON string.
364
+ to_yaml(self) -> str:
365
+ Serializes the backup operation details into a YAML string.
366
+ validate(self) -> bool:
367
+ Validates the backup operation details.
368
+ """
369
+
370
+ def __init__(
371
+ self,
372
+ backup_state: Optional[SettingStatus] = None,
373
+ backup_state_details: Optional[str] = None,
374
+ time_last_backup: Optional[int] = None,
375
+ ):
376
+ self.backup_state = backup_state
377
+ self.backup_state_details = backup_state_details
378
+ self.time_last_backup = time_last_backup
379
+
380
+ def to_dict(self) -> Dict:
381
+ """Serializes the backup operation details into a dictionary."""
382
+ return {
383
+ "backup_state": self.backup_state or None,
384
+ "backup_state_details": self.backup_state_details,
385
+ "time_last_backup": self.time_last_backup,
386
+ }
387
+
388
+ @classmethod
389
+ def from_dict(cls, data: Dict) -> "ModelBackupOperationDetails":
390
+ """Constructs backup operation details from a dictionary."""
391
+ return cls(
392
+ backup_state=SettingStatus(data.get("backup_state")) or None,
393
+ backup_state_details=data.get("backup_state_details"),
394
+ time_last_backup=data.get("time_last_backup"),
395
+ )
396
+
397
+ def to_json(self) -> str:
398
+ """Serializes the backup operation details into a JSON string."""
399
+ return json.dumps(self.to_dict())
400
+
401
+ @classmethod
402
+ def from_json(cls, json_str: str) -> "ModelBackupOperationDetails":
403
+ """Constructs backup operation details from a JSON string."""
404
+ data = json.loads(json_str)
405
+ return cls.from_dict(data)
406
+
407
+ def to_yaml(self) -> str:
408
+ """Serializes the backup operation details into a YAML string."""
409
+ return yaml.dump(self.to_dict())
410
+
411
+ def validate(self) -> bool:
412
+ """Validates the backup operation details."""
413
+ return not (
414
+ (self.backup_state is not None and self.backup_state not in SettingStatus.values()) or
415
+ (self.time_last_backup is not None and not isinstance(self.time_last_backup, int))
416
+ )
417
+
418
+ def __repr__(self):
419
+ return self.to_yaml()
420
+
421
+
81
422
  class DataScienceModel(Builder):
82
423
  """Represents a Data Science Model.
83
424
 
@@ -120,6 +461,14 @@ class DataScienceModel(Builder):
120
461
  Model version id
121
462
  model_file_description: dict
122
463
  Contains object path details for models created by reference.
464
+ backup_setting: ModelBackupSetting
465
+ The value to assign to the backup_setting property of this CreateModelDetails.
466
+ retention_setting: ModelRetentionSetting
467
+ The value to assign to the retention_setting property of this CreateModelDetails.
468
+ retention_operation_details: ModelRetentionOperationDetails
469
+ The value to assign to the retention_operation_details property for the Model.
470
+ backup_operation_details: ModelBackupOperationDetails
471
+ The value to assign to the backup_operation_details property for the Model.
123
472
 
124
473
  Methods
125
474
  -------
@@ -217,7 +566,12 @@ class DataScienceModel(Builder):
217
566
  CONST_MODEL_VERSION_ID = "versionId"
218
567
  CONST_TIME_CREATED = "timeCreated"
219
568
  CONST_LIFECYCLE_STATE = "lifecycleState"
569
+ CONST_LIFECYCLE_DETAILS = "lifecycleDetails"
220
570
  CONST_MODEL_FILE_DESCRIPTION = "modelDescription"
571
+ CONST_BACKUP_SETTING = "backupSetting"
572
+ CONST_RETENTION_SETTING = "retentionSetting"
573
+ CONST_BACKUP_OPERATION_DETAILS = "backupOperationDetails"
574
+ CONST_RETENTION_OPERATION_DETAILS = "retentionOperationDetails"
221
575
 
222
576
  attribute_map = {
223
577
  CONST_ID: "id",
@@ -239,7 +593,12 @@ class DataScienceModel(Builder):
239
593
  CONST_MODEL_VERSION_ID: "version_id",
240
594
  CONST_TIME_CREATED: "time_created",
241
595
  CONST_LIFECYCLE_STATE: "lifecycle_state",
596
+ CONST_LIFECYCLE_DETAILS: "lifecycle_details",
242
597
  CONST_MODEL_FILE_DESCRIPTION: "model_description",
598
+ CONST_BACKUP_SETTING: "backup_setting",
599
+ CONST_RETENTION_SETTING: "retention_setting",
600
+ CONST_BACKUP_OPERATION_DETAILS: "backup_operation_details",
601
+ CONST_RETENTION_OPERATION_DETAILS: "retention_operation_details",
243
602
  }
244
603
 
245
604
  def __init__(self, spec: Dict = None, **kwargs) -> None:
@@ -308,6 +667,28 @@ class DataScienceModel(Builder):
308
667
  return self.dsc_model.status
309
668
  return None
310
669
 
670
+ @property
671
+ def lifecycle_details(self) -> str:
672
+ """
673
+ Gets the lifecycle_details of this DataScienceModel.
674
+ Details about the lifecycle state of the model.
675
+
676
+ :return: The lifecycle_details of this DataScienceModel.
677
+ :rtype: str
678
+ """
679
+ return self.get_spec(self.CONST_LIFECYCLE_DETAILS)
680
+
681
+ @lifecycle_details.setter
682
+ def lifecycle_details(self, lifecycle_details: str) -> "DataScienceModel":
683
+ """
684
+ Sets the lifecycle_details of this DataScienceModel.
685
+ Details about the lifecycle state of the model.
686
+
687
+ :param lifecycle_details: The lifecycle_details of this DataScienceModel.
688
+ :type: str
689
+ """
690
+ return self.set_spec(self.CONST_LIFECYCLE_DETAILS, lifecycle_details)
691
+
311
692
  @property
312
693
  def kind(self) -> str:
313
694
  """The kind of the object as showing in a YAML."""
@@ -685,6 +1066,85 @@ class DataScienceModel(Builder):
685
1066
 
686
1067
  return self.set_spec(self.CONST_MODEL_FILE_DESCRIPTION, json_data)
687
1068
 
1069
+ @property
1070
+ def retention_setting(self) -> ModelRetentionSetting:
1071
+ """
1072
+ Gets the retention_setting of this model.
1073
+
1074
+ :return: The retention_setting of this model.
1075
+ :rtype: RetentionSetting
1076
+ """
1077
+ return self.get_spec(self.CONST_RETENTION_SETTING)
1078
+
1079
+ def with_retention_setting(
1080
+ self, retention_setting: Union[Dict, ModelRetentionSetting]
1081
+ ) -> "DataScienceModel":
1082
+ """
1083
+ Sets the retention setting details for the model.
1084
+
1085
+ Parameters
1086
+ ----------
1087
+ retention_setting : Union[Dict, RetentionSetting]
1088
+ The retention setting details for the model. Can be provided as either a dictionary or
1089
+ an instance of the `RetentionSetting` class.
1090
+
1091
+ Returns
1092
+ -------
1093
+ DataScienceModel
1094
+ The `DataScienceModel` instance (self) for method chaining.
1095
+ """
1096
+ return self.set_spec(self.CONST_RETENTION_SETTING, retention_setting)
1097
+
1098
+ @property
1099
+ def backup_setting(self) -> ModelBackupSetting:
1100
+ """
1101
+ Gets the backup_setting of this model.
1102
+
1103
+ :return: The backup_setting of this model.
1104
+ :rtype: BackupSetting
1105
+ """
1106
+ return self.get_spec(self.CONST_BACKUP_SETTING)
1107
+
1108
+ def with_backup_setting(
1109
+ self, backup_setting: Union[Dict, ModelBackupSetting]
1110
+ ) -> "DataScienceModel":
1111
+ """
1112
+ Sets the model's backup setting details.
1113
+
1114
+ Parameters
1115
+ ----------
1116
+ backup_setting : Union[Dict, BackupSetting]
1117
+ The backup setting details for the model. This can be passed as either a dictionary or
1118
+ an instance of the `BackupSetting` class.
1119
+
1120
+ Returns
1121
+ -------
1122
+ DataScienceModel
1123
+ The `DataScienceModel` instance (self) for method chaining.
1124
+ """
1125
+
1126
+ return self.set_spec(self.CONST_BACKUP_SETTING, backup_setting)
1127
+
1128
+ @property
1129
+ def retention_operation_details(self) -> ModelRetentionOperationDetails:
1130
+ """
1131
+ Gets the retention_operation_details of this Model using the spec constant.
1132
+
1133
+ :return: The retention_operation_details of this Model.
1134
+ :rtype: ModelRetentionOperationDetails
1135
+ """
1136
+ return self.get_spec(self.CONST_RETENTION_OPERATION_DETAILS)
1137
+
1138
+ @property
1139
+ def backup_operation_details(self) -> "ModelBackupOperationDetails":
1140
+ """
1141
+ Gets the backup_operation_details of this Model using the spec constant.
1142
+
1143
+ :return: The backup_operation_details of this Model.
1144
+ :rtype: ModelBackupOperationDetails
1145
+ """
1146
+ return self.get_spec(self.CONST_BACKUP_OPERATION_DETAILS)
1147
+
688
1148
  def create(self, **kwargs) -> "DataScienceModel":
689
1149
  """Creates datascience model.
690
1150
 
@@ -907,6 +1367,44 @@ class DataScienceModel(Builder):
907
1367
  if self.local_copy_dir:
908
1368
  shutil.rmtree(self.local_copy_dir, ignore_errors=True)
909
1369
 
1370
+ def restore_model(
1371
+ self,
1372
+ restore_model_for_hours_specified: Optional[int] = None,
1373
+ ) -> None:
1374
+ """
1375
+ Restore archived model artifact.
1376
+
1377
+ Parameters
1378
+ ----------
1379
+
1380
+ restore_model_for_hours_specified : Optional[int]
1381
+ Duration in hours for which the archived model is available for access.
1382
+
1383
+ Returns
1384
+ -------
1385
+ None
1386
+
1387
+ Raises
1388
+ ------
1389
+ ValueError
1390
+ If the model ID is invalid or if any parameters are incorrect.
1391
+ """
1392
+ # Validate model_id
1393
+ if not self.id:
1394
+ logger.warn(
1395
+ "Model needs to be saved to the model catalog before it can be restored."
1396
+ )
1397
+ return
1398
+
1399
+ # Optional: Validate restore_model_for_hours_specified
1400
+ if restore_model_for_hours_specified is not None and (
1401
+ not isinstance(restore_model_for_hours_specified, int) or restore_model_for_hours_specified <= 0):
1402
+ raise ValueError("restore_model_for_hours_specified must be a positive integer.")
1403
+
1404
+ self.dsc_model.restore_archived_model_artifact(
1405
+ restore_model_for_hours_specified=restore_model_for_hours_specified,
1406
+ )
1407
+
910
1408
  def download_artifact(
911
1409
  self,
912
1410
  target_dir: str,
@@ -1039,15 +1537,16 @@ class DataScienceModel(Builder):
1039
1537
  self.dsc_model = self._to_oci_dsc_model(**kwargs).update()
1040
1538
 
1041
1539
  logger.debug(f"Updating a model provenance metadata {self.provenance_metadata}")
1042
- try:
1043
- self.dsc_model.get_model_provenance()
1044
- self.dsc_model.update_model_provenance(
1045
- self.provenance_metadata._to_oci_metadata()
1046
- )
1047
- except ModelProvenanceNotFoundError:
1048
- self.dsc_model.create_model_provenance(
1049
- self.provenance_metadata._to_oci_metadata()
1050
- )
1540
+ if self.provenance_metadata:
1541
+ try:
1542
+ self.dsc_model.get_model_provenance()
1543
+ self.dsc_model.update_model_provenance(
1544
+ self.provenance_metadata._to_oci_metadata()
1545
+ )
1546
+ except ModelProvenanceNotFoundError:
1547
+ self.dsc_model.create_model_provenance(
1548
+ self.provenance_metadata._to_oci_metadata()
1549
+ )
1051
1550
 
1052
1551
  return self.sync()
1053
1552
 
@@ -1219,6 +1718,10 @@ class DataScienceModel(Builder):
1219
1718
  self.CONST_OUTPUT_SCHEMA: [Schema.from_json, json.loads],
1220
1719
  self.CONST_CUSTOM_METADATA: ModelCustomMetadata._from_oci_metadata,
1221
1720
  self.CONST_DEFINED_METADATA: ModelTaxonomyMetadata._from_oci_metadata,
1721
+ self.CONST_BACKUP_SETTING: ModelBackupSetting.to_dict,
1722
+ self.CONST_RETENTION_SETTING: ModelRetentionSetting.to_dict,
1723
+ self.CONST_BACKUP_OPERATION_DETAILS: ModelBackupOperationDetails.to_dict,
1724
+ self.CONST_RETENTION_OPERATION_DETAILS: ModelRetentionOperationDetails.to_dict
1222
1725
  }
1223
1726
 
1224
1727
  # Update the main properties
@@ -1533,7 +2036,7 @@ class DataScienceModel(Builder):
1533
2036
  "Both 'prefix' and 'files' cannot be provided. Please provide only one."
1534
2037
  )
1535
2038
 
1536
- if self.model_file_description == None:
2039
+ if self.model_file_description is None:
1537
2040
  self.empty_json = {
1538
2041
  "version": "1.0",
1539
2042
  "type": "modelOSSReferenceDescription",
@@ -1583,7 +2086,7 @@ class DataScienceModel(Builder):
1583
2086
 
1584
2087
  # Fetch object details and put it into the objects variable
1585
2088
  objectStorageList = []
1586
- if files == None:
2089
+ if files is None:
1587
2090
  objectStorageList = list_obj_versions_unpaginated()
1588
2091
  else:
1589
2092
  for fileName in files:
@@ -1671,7 +2174,7 @@ class DataScienceModel(Builder):
1671
2174
  if (not namespace) or (not bucket):
1672
2175
  raise ValueError("Both 'namespace' and 'bucket' must be provided.")
1673
2176
 
1674
- def findModelIdx():
2177
+ def find_model_idx():
1675
2178
  for idx, model in enumerate(self.model_file_description["models"]):
1676
2179
  if (
1677
2180
  model["namespace"],
@@ -1681,10 +2184,10 @@ class DataScienceModel(Builder):
1681
2184
  return idx
1682
2185
  return -1
1683
2186
 
1684
- if self.model_file_description == None:
2187
+ if self.model_file_description is None:
1685
2188
  return
1686
2189
 
1687
- modelSearchIdx = findModelIdx()
2190
+ modelSearchIdx = find_model_idx()
1688
2191
  if modelSearchIdx == -1:
1689
2192
  return
1690
2193
  else:
@@ -1648,6 +1648,19 @@ class ModelDeployment(Builder):
1648
1648
  infrastructure.CONST_SUBNET_ID
1649
1649
  ] = infrastructure.subnet_id
1650
1650
 
1651
+ if infrastructure.private_endpoint_id:
1652
+ if not hasattr(
1653
+ oci.data_science.models.InstanceConfiguration, "private_endpoint_id"
1654
+ ):
1655
+ # TODO: add oci version with private endpoint support.
1656
+ raise EnvironmentError(
1657
+ "Private endpoint is not supported in the current OCI SDK installed."
1658
+ )
1659
+
1660
+ instance_configuration[
1661
+ infrastructure.CONST_PRIVATE_ENDPOINT_ID
1662
+ ] = infrastructure.private_endpoint_id
1663
+
1651
1664
  scaling_policy = {
1652
1665
  infrastructure.CONST_POLICY_TYPE: "FIXED_SIZE",
1653
1666
  infrastructure.CONST_INSTANCE_COUNT: infrastructure.replica