Skip to content

Commit 2f1d661

Browse files
committed
updated as per comments and added missing api and column
1 parent cfa6bef commit 2f1d661

File tree

2 files changed

+96
-69
lines changed

2 files changed

+96
-69
lines changed

ads/model/datascience_model.py

Lines changed: 69 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,29 @@ def lifecycle_state(self) -> Union[str, None]:
333333
if self.dsc_model:
334334
return self.dsc_model.status
335335
return None
336+
337+
@property
338+
def lifecycle_details(self) -> str:
339+
"""
340+
Gets the lifecycle_details of this DataScienceModel.
341+
Details about the lifecycle state of the model.
342+
343+
:return: The lifecycle_details of this DataScienceModel.
344+
:rtype: str
345+
"""
346+
return self.get_spec(self.CONST_LIFECYCLE_DETAILS)
347+
348+
@lifecycle_details.setter
349+
def lifecycle_details(self, lifecycle_details: str) -> "DataScienceModel":
350+
"""
351+
Sets the lifecycle_details of this DataScienceModel.
352+
Details about the lifecycle state of the model.
353+
354+
:param lifecycle_details: The lifecycle_details of this DataScienceModel.
355+
:type: str
356+
"""
357+
return self.set_spec(self.CONST_LIFECYCLE_DETAILS, lifecycle_details)
358+
336359

337360
@property
338361
def kind(self) -> str:
@@ -737,15 +760,13 @@ def with_retention_setting(self, retention_setting: Union[Dict, ModelRetentionSe
737760
The `DataScienceModel` instance (self) for method chaining.
738761
"""
739762
if retention_setting and isinstance(retention_setting, dict):
740-
try:
741-
retention_setting = ModelRetentionSetting.from_dict(retention_setting)
742-
except Exception as err:
743-
logger.warn(f"Failed to convert retention_setting from dict: {err}")
763+
retention_setting = ModelRetentionSetting.from_dict(retention_setting)
744764

745765
return self.set_spec(self.CONST_RETENTION_SETTING, retention_setting)
746766

747767

748768

769+
749770
@property
750771
def backup_setting(self) -> ModelBackupSetting:
751772
"""
@@ -769,15 +790,13 @@ def with_backup_setting(self, backup_setting: Union[Dict, ModelBackupSetting]) -
769790
Returns
770791
-------
771792
DataScienceModel
772-
The `DataScienceModel` instance (self) for method chaining.
793+
The `DataScienceModel` instance (self) for method chaining.
773794
"""
774795
if backup_setting and isinstance(backup_setting, dict):
775-
try:
776-
backup_setting = ModelBackupSetting.from_dict(backup_setting)
777-
except Exception as err:
778-
logger.warn(f"Failed to convert backup_setting from dict: {err}")
796+
backup_setting = ModelBackupSetting.from_dict(backup_setting)
779797

780798
return self.set_spec(self.CONST_BACKUP_SETTING, backup_setting)
799+
781800

782801
@property
783802
def retention_operation_details(self) -> ModelRetentionOperationDetails:
@@ -788,16 +807,6 @@ def retention_operation_details(self) -> ModelRetentionOperationDetails:
788807
:rtype: ModelRetentionOperationDetails
789808
"""
790809
return self.get_spec(self.CONST_RETENTION_OPERATION_DETAILS)
791-
792-
@retention_operation_details.setter
793-
def retention_operation_details(self, retention_operation_details: ModelRetentionOperationDetails) -> "DataScienceModel":
794-
"""
795-
Sets the retention_operation_details of this Model using the spec constant.
796-
797-
:param retention_operation_details: The retention_operation_details of this Model.
798-
:type: ModelRetentionOperationDetails
799-
"""
800-
return self.set_spec(self.CONST_RETENTION_OPERATION_DETAILS, retention_operation_details)
801810

802811
@property
803812
def backup_operation_details(self) -> "ModelBackupOperationDetails":
@@ -809,16 +818,6 @@ def backup_operation_details(self) -> "ModelBackupOperationDetails":
809818
"""
810819
return self.get_spec(self.CONST_BACKUP_OPERATION_DETAILS)
811820

812-
@backup_operation_details.setter
813-
def backup_operation_details(self, backup_operation_details: "ModelBackupOperationDetails") -> "DataScienceModel":
814-
"""
815-
Sets the backup_operation_details of this Model using the spec constant.
816-
817-
:param backup_operation_details: The backup_operation_details of this Model.
818-
:type: ModelBackupOperationDetails
819-
"""
820-
return self.set_spec(self.CONST_BACKUP_OPERATION_DETAILS, backup_operation_details)
821-
822821
def create(self, **kwargs) -> "DataScienceModel":
823822
"""Creates datascience model.
824823
@@ -1043,6 +1042,45 @@ def _remove_file_description_artifact(self):
10431042
if self.local_copy_dir:
10441043
shutil.rmtree(self.local_copy_dir, ignore_errors=True)
10451044

1045+
1046+
def restore_model(
1047+
self,
1048+
model_id: str,
1049+
restore_model_for_hours_specified: Optional[int] = None,
1050+
):
1051+
"""
1052+
Restore archived model artifact.
1053+
1054+
Parameters
1055+
----------
1056+
model_id : str
1057+
The `OCID` of the model to be restored.
1058+
restore_model_for_hours_specified : Optional[int]
1059+
Duration in hours for which the archived model is available for access.
1060+
1061+
Returns
1062+
-------
1063+
None
1064+
1065+
Raises
1066+
------
1067+
ValueError
1068+
If the model ID is invalid or if any parameters are incorrect.
1069+
"""
1070+
# Validate model_id
1071+
if not model_id or not isinstance(model_id, str):
1072+
raise ValueError("model_id must be a non-empty string.")
1073+
1074+
# Optional: Validate restore_model_for_hours_specified
1075+
if restore_model_for_hours_specified is not None:
1076+
if not isinstance(restore_model_for_hours_specified, int) or restore_model_for_hours_specified <= 0:
1077+
raise ValueError("restore_model_for_hours_specified must be a positive integer.")
1078+
1079+
self.dsc_model.restore_archived_model_artifact(
1080+
model_id=model_id,
1081+
restore_model_for_hours_specified=restore_model_for_hours_specified)
1082+
1083+
10461084
def download_artifact(
10471085
self,
10481086
target_dir: str,
@@ -1298,6 +1336,8 @@ def _init_complex_attributes(self):
12981336
self.with_provenance_metadata(self.provenance_metadata)
12991337
self.with_input_schema(self.input_schema)
13001338
self.with_output_schema(self.output_schema)
1339+
self.with_backup_setting(self.backup_setting)
1340+
self.with_retention_setting(self.retention_setting)
13011341

13021342
def _to_oci_dsc_model(self, **kwargs):
13031343
"""Creates an `OCIDataScienceModel` instance from the `DataScienceModel`.

ads/model/model_metadata.py

Lines changed: 27 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1794,7 +1794,7 @@ def __init__(self, is_backup_enabled: Optional[bool] = None, backup_region: Opti
17941794
customer_notification_type: Optional[CustomerNotificationType] = None):
17951795
self.is_backup_enabled = is_backup_enabled if is_backup_enabled is not None else False
17961796
self.backup_region = backup_region
1797-
self.customer_notification_type = customer_notification_type if customer_notification_type is not None else CustomerNotificationType.NONE
1797+
self.customer_notification_type = customer_notification_type or CustomerNotificationType.NONE
17981798

17991799
def to_dict(self) -> Dict:
18001800
"""Serializes the backup settings into a dictionary."""
@@ -1810,7 +1810,7 @@ def from_dict(cls, data: Dict) -> 'ModelBackupSetting':
18101810
return cls(
18111811
is_backup_enabled=data.get("is_backup_enabled"),
18121812
backup_region=data.get("backup_region"),
1813-
customer_notification_type=CustomerNotificationType(data.get("customer_notification_type", CustomerNotificationType.NONE.value))
1813+
customer_notification_type = CustomerNotificationType(data.get("customer_notification_type")) or None
18141814
)
18151815

18161816
def to_json(self) -> str:
@@ -1838,7 +1838,8 @@ def validate(self) -> bool:
18381838
return True
18391839

18401840
def __repr__(self):
1841-
return f"ModelBackupSetting(is_backup_enabled={self.is_backup_enabled}, backup_region={self.backup_region}, customer_notification_type={self.customer_notification_type})"
1841+
return self.to_yaml()
1842+
18421843

18431844

18441845
class ModelRetentionSetting:
@@ -1865,7 +1866,7 @@ def __init__(self, archive_after_days: Optional[int] = None, delete_after_days:
18651866
customer_notification_type: Optional[CustomerNotificationType] = None):
18661867
self.archive_after_days = archive_after_days
18671868
self.delete_after_days = delete_after_days
1868-
self.customer_notification_type = customer_notification_type if customer_notification_type is not None else CustomerNotificationType.NONE
1869+
self.customer_notification_type = customer_notification_type or CustomerNotificationType.NONE
18691870

18701871
def to_dict(self) -> Dict:
18711872
"""Serializes the retention settings into a dictionary."""
@@ -1881,7 +1882,7 @@ def from_dict(cls, data: Dict) -> 'ModelRetentionSetting':
18811882
return cls(
18821883
archive_after_days=data.get("archive_after_days"),
18831884
delete_after_days=data.get("delete_after_days"),
1884-
customer_notification_type=CustomerNotificationType(data.get("customer_notification_type", CustomerNotificationType.NONE.value))
1885+
customer_notification_type = CustomerNotificationType(data.get("customer_notification_type")) or None
18851886
)
18861887

18871888
def to_json(self) -> str:
@@ -1909,7 +1910,7 @@ def validate(self) -> bool:
19091910
return True
19101911

19111912
def __repr__(self):
1912-
return f"ModelRetentionSetting(archive_after_days={self.archive_after_days}, delete_after_days={self.delete_after_days}, customer_notification_type={self.customer_notification_type})"
1913+
return self.to_yaml()
19131914

19141915

19151916
class SettingStatus(str, ExtendedEnumMeta):
@@ -1945,19 +1946,19 @@ def __init__(self,
19451946
delete_state_details: Optional[str] = None,
19461947
time_archival_scheduled: Optional[int] = None,
19471948
time_deletion_scheduled: Optional[int] = None):
1948-
self.archive_state = archive_state if archive_state is not None else SettingStatus.PENDING
1949+
self.archive_state = archive_state
19491950
self.archive_state_details = archive_state_details
1950-
self.delete_state = delete_state if delete_state is not None else SettingStatus.PENDING
1951+
self.delete_state = delete_state
19511952
self.delete_state_details = delete_state_details
19521953
self.time_archival_scheduled = time_archival_scheduled
19531954
self.time_deletion_scheduled = time_deletion_scheduled
19541955

19551956
def to_dict(self) -> Dict:
19561957
"""Serializes the retention operation details into a dictionary."""
19571958
return {
1958-
"archive_state": self.archive_state.value,
1959+
"archive_state": self.archive_state.value or None,
19591960
"archive_state_details": self.archive_state_details,
1960-
"delete_state": self.delete_state.value,
1961+
"delete_state": self.delete_state.value or None,
19611962
"delete_state_details": self.delete_state_details,
19621963
"time_archival_scheduled": self.time_archival_scheduled,
19631964
"time_deletion_scheduled": self.time_deletion_scheduled
@@ -1967,9 +1968,9 @@ def to_dict(self) -> Dict:
19671968
def from_dict(cls, data: Dict) -> 'ModelRetentionOperationDetails':
19681969
"""Constructs retention operation details from a dictionary."""
19691970
return cls(
1970-
archive_state=SettingStatus(data.get("archive_state", SettingStatus.PENDING.value)),
1971+
archive_state = SettingStatus(data.get("archive_state")) or None,
19711972
archive_state_details=data.get("archive_state_details"),
1972-
delete_state=SettingStatus(data.get("delete_state", SettingStatus.PENDING.value)),
1973+
delete_state = SettingStatus(data.get("delete_state")) or None,
19731974
delete_state_details=data.get("delete_state_details"),
19741975
time_archival_scheduled=data.get("time_archival_scheduled"),
19751976
time_deletion_scheduled=data.get("time_deletion_scheduled")
@@ -1991,24 +1992,16 @@ def to_yaml(self) -> str:
19911992

19921993
def validate(self) -> bool:
19931994
"""Validates the retention operation details."""
1994-
if not isinstance(self.archive_state, SettingStatus):
1995-
return False
1996-
if not isinstance(self.delete_state, SettingStatus):
1997-
return False
1998-
if self.time_archival_scheduled is not None and not isinstance(self.time_archival_scheduled, int):
1999-
return False
2000-
if self.time_deletion_scheduled is not None and not isinstance(self.time_deletion_scheduled, int):
2001-
return False
2002-
return True
1995+
return all([
1996+
self.archive_state is None or isinstance(self.archive_state, SettingStatus),
1997+
self.delete_state is None or isinstance(self.delete_state, SettingStatus),
1998+
self.time_archival_scheduled is None or isinstance(self.time_archival_scheduled, int),
1999+
self.time_deletion_scheduled is None or isinstance(self.time_deletion_scheduled, int),
2000+
])
2001+
20032002

20042003
def __repr__(self):
2005-
return (f"ModelRetentionOperationDetails("
2006-
f"archive_state={self.archive_state}, "
2007-
f"archive_state_details={self.archive_state_details}, "
2008-
f"delete_state={self.delete_state}, "
2009-
f"delete_state_details={self.delete_state_details}, "
2010-
f"time_archival_scheduled={self.time_archival_scheduled}, "
2011-
f"time_deletion_scheduled={self.time_deletion_scheduled})")
2004+
return self.to_yaml()
20122005

20132006

20142007
class ModelBackupOperationDetails:
@@ -2032,17 +2025,17 @@ class ModelBackupOperationDetails:
20322025
"""
20332026

20342027
def __init__(self,
2035-
backup_state: Optional['SettingStatus'] = None,
2028+
backup_state: Optional[SettingStatus] = None,
20362029
backup_state_details: Optional[str] = None,
20372030
time_last_backed_up: Optional[int] = None):
2038-
self.backup_state = backup_state if backup_state is not None else SettingStatus.PENDING
2031+
self.backup_state = backup_state
20392032
self.backup_state_details = backup_state_details
20402033
self.time_last_backed_up = time_last_backed_up
20412034

20422035
def to_dict(self) -> Dict:
20432036
"""Serializes the backup operation details into a dictionary."""
20442037
return {
2045-
"backup_state": self.backup_state.value,
2038+
"backup_state": self.backup_state.value or None,
20462039
"backup_state_details": self.backup_state_details,
20472040
"time_last_backed_up": self.time_last_backed_up
20482041
}
@@ -2051,7 +2044,7 @@ def to_dict(self) -> Dict:
20512044
def from_dict(cls, data: Dict) -> 'ModelBackupOperationDetails':
20522045
"""Constructs backup operation details from a dictionary."""
20532046
return cls(
2054-
backup_state=SettingStatus(data.get("backup_state", SettingStatus.PENDING.value)),
2047+
backup_state=SettingStatus(data.get("backup_state")) or None,
20552048
backup_state_details=data.get("backup_state_details"),
20562049
time_last_backed_up=data.get("time_last_backed_up")
20572050
)
@@ -2072,17 +2065,11 @@ def to_yaml(self) -> str:
20722065

20732066
def validate(self) -> bool:
20742067
"""Validates the backup operation details."""
2075-
if not isinstance(self.backup_state, SettingStatus):
2068+
if self.backup_state is not None and not isinstance(self.backup_state, SettingStatus):
20762069
return False
20772070
if self.time_last_backed_up is not None and not isinstance(self.time_last_backed_up, int):
20782071
return False
20792072
return True
20802073

20812074
def __repr__(self):
2082-
return (f"ModelBackupOperationDetails("
2083-
f"backup_state={self.backup_state}, "
2084-
f"backup_state_details={self.backup_state_details}, "
2085-
f"time_last_backed_up={self.time_last_backed_up})")
2086-
2087-
2088-
2075+
return self.to_yaml()

0 commit comments

Comments
 (0)