Skip to content

Commit 85326a9

Browse files
authored
Added pre check for Model Deployment operations and fixed unit tests (#142)
2 parents ec177e9 + 876550c commit 85326a9

File tree

5 files changed

+385
-287
lines changed

5 files changed

+385
-287
lines changed

ads/model/deployment/model_deployment.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1532,6 +1532,9 @@ def _build_model_deployment_configuration_details(self) -> Dict:
15321532
infrastructure.CONST_MEMORY_IN_GBS: infrastructure.shape_config_details.get(
15331533
"memory_in_gbs", None
15341534
)
1535+
or infrastructure.shape_config_details.get(
1536+
"memoryInGBs", None
1537+
)
15351538
or MODEL_DEPLOYMENT_INSTANCE_MEMORY_IN_GBS,
15361539
}
15371540

ads/model/service/oci_datascience_model_deployment.py

Lines changed: 88 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -178,29 +178,46 @@ def activate(
178178
OCIDataScienceModelDeployment
179179
The `OCIDataScienceModelDeployment` instance (self).
180180
"""
181-
logger.info(f"Activating model deployment `{self.id}`.")
182-
response = self.client.activate_model_deployment(
183-
self.id,
184-
)
181+
dsc_model_deployment = OCIDataScienceModelDeployment.from_id(self.id)
182+
if (
183+
dsc_model_deployment.lifecycle_state
184+
== self.LIFECYCLE_STATE_ACTIVE
185+
):
186+
raise Exception(
187+
f"Model deployment {dsc_model_deployment.id} is already in active state."
188+
)
185189

186-
if wait_for_completion:
190+
if (
191+
dsc_model_deployment.lifecycle_state
192+
== self.LIFECYCLE_STATE_INACTIVE
193+
):
194+
logger.info(f"Activating model deployment `{self.id}`.")
195+
response = self.client.activate_model_deployment(
196+
self.id,
197+
)
187198

188-
self.workflow_req_id = response.headers.get("opc-work-request-id", None)
199+
if wait_for_completion:
189200

190-
try:
191-
self.wait_for_progress(
192-
self.workflow_req_id,
193-
ACTIVATE_WORKFLOW_STEPS,
194-
max_wait_time,
195-
poll_interval
196-
)
197-
except Exception as e:
198-
logger.error(
199-
f"Error while trying to activate model deployment: {self.id}"
200-
)
201-
raise e
201+
self.workflow_req_id = response.headers.get("opc-work-request-id", None)
202202

203-
return self.sync()
203+
try:
204+
self.wait_for_progress(
205+
self.workflow_req_id,
206+
ACTIVATE_WORKFLOW_STEPS,
207+
max_wait_time,
208+
poll_interval
209+
)
210+
except Exception as e:
211+
logger.error(
212+
f"Error while trying to activate model deployment: {self.id}"
213+
)
214+
raise e
215+
216+
return self.sync()
217+
else:
218+
raise Exception(
219+
f"Can't activate model deployment {dsc_model_deployment.id} when it's in {dsc_model_deployment.lifecycle_state} state."
220+
)
204221

205222
def create(
206223
self,
@@ -277,29 +294,46 @@ def deactivate(
277294
OCIDataScienceModelDeployment
278295
The `OCIDataScienceModelDeployment` instance (self).
279296
"""
280-
logger.info(f"Deactivating model deployment `{self.id}`.")
281-
response = self.client.deactivate_model_deployment(
282-
self.id,
283-
)
297+
dsc_model_deployment = OCIDataScienceModelDeployment.from_id(self.id)
298+
if (
299+
dsc_model_deployment.lifecycle_state
300+
== self.LIFECYCLE_STATE_INACTIVE
301+
):
302+
raise Exception(
303+
f"Model deployment {dsc_model_deployment.id} is already in inactive state."
304+
)
284305

285-
if wait_for_completion:
306+
if (
307+
dsc_model_deployment.lifecycle_state
308+
== self.LIFECYCLE_STATE_ACTIVE
309+
):
310+
logger.info(f"Deactivating model deployment `{self.id}`.")
311+
response = self.client.deactivate_model_deployment(
312+
self.id,
313+
)
286314

287-
self.workflow_req_id = response.headers.get("opc-work-request-id", None)
315+
if wait_for_completion:
288316

289-
try:
290-
self.wait_for_progress(
291-
self.workflow_req_id,
292-
DEACTIVATE_WORKFLOW_STEPS,
293-
max_wait_time,
294-
poll_interval
295-
)
296-
except Exception as e:
297-
logger.error(
298-
f"Error while trying to deactivate model deployment: {self.id}"
299-
)
300-
raise e
317+
self.workflow_req_id = response.headers.get("opc-work-request-id", None)
301318

302-
return self.sync()
319+
try:
320+
self.wait_for_progress(
321+
self.workflow_req_id,
322+
DEACTIVATE_WORKFLOW_STEPS,
323+
max_wait_time,
324+
poll_interval
325+
)
326+
except Exception as e:
327+
logger.error(
328+
f"Error while trying to deactivate model deployment: {self.id}"
329+
)
330+
raise e
331+
332+
return self.sync()
333+
else:
334+
raise Exception(
335+
f"Can't deactivate model deployment {dsc_model_deployment.id} when it's in {dsc_model_deployment.lifecycle_state} state."
336+
)
303337

304338
@check_for_model_deployment_id(
305339
msg="Model deployment needs to be deployed before it can be deleted."
@@ -328,6 +362,22 @@ def delete(
328362
OCIDataScienceModelDeployment
329363
The `OCIDataScienceModelDeployment` instance (self).
330364
"""
365+
dsc_model_deployment = OCIDataScienceModelDeployment.from_id(self.id)
366+
if dsc_model_deployment.lifecycle_state in [
367+
self.LIFECYCLE_STATE_DELETED,
368+
self.LIFECYCLE_STATE_DELETING
369+
]:
370+
raise Exception(
371+
f"Model deployment {dsc_model_deployment.id} is either deleted or being deleted."
372+
)
373+
if dsc_model_deployment.lifecycle_state not in [
374+
self.LIFECYCLE_STATE_ACTIVE,
375+
self.LIFECYCLE_STATE_FAILED,
376+
self.LIFECYCLE_STATE_INACTIVE,
377+
]:
378+
raise Exception(
379+
f"Can't delete model deployment {dsc_model_deployment.id} when it's in {dsc_model_deployment.lifecycle_state} state."
380+
)
331381
logger.info(f"Deleting model deployment `{self.id}`.")
332382
response = self.client.delete_model_deployment(
333383
self.id,

ads/opctl/backend/ads_model_deployment.py

Lines changed: 16 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,11 @@
55
# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/
66

77
from typing import Dict
8-
import ads
98
from ads.common.auth import create_signer, AuthContext
109
from ads.common.oci_client import OCIClientFactory
1110
from ads.opctl.backend.base import Backend
1211
from ads.model.deployment import ModelDeployment
1312

14-
from oci.data_science.models import ModelDeployment as OCIModelDeployment
15-
1613

1714
class ModelDeploymentBackend(Backend):
1815
def __init__(self, config: Dict) -> None:
@@ -60,22 +57,6 @@ def delete(self) -> None:
6057
poll_interval = self.config["execution"].get("poll_interval")
6158
with AuthContext(auth=self.auth_type, profile=self.profile):
6259
model_deployment = ModelDeployment.from_id(model_deployment_id)
63-
if model_deployment.lifecycle_state in [
64-
OCIModelDeployment.LIFECYCLE_STATE_DELETED
65-
or OCIModelDeployment.LIFECYCLE_STATE_DELETING
66-
]:
67-
print(
68-
f"Model deployment {model_deployment.model_deployment_id} is either deleted or being deleted."
69-
)
70-
return
71-
if model_deployment.lifecycle_state not in [
72-
OCIModelDeployment.LIFECYCLE_STATE_ACTIVE,
73-
OCIModelDeployment.LIFECYCLE_STATE_FAILED,
74-
OCIModelDeployment.LIFECYCLE_STATE_INACTIVE,
75-
]:
76-
raise Exception(
77-
f"Can't delete model deployment {model_deployment.model_deployment_id} when it's in {model_deployment.lifecycle_state} state."
78-
)
7960
model_deployment.delete(
8061
wait_for_completion=wait_for_completion,
8162
max_wait_time=max_wait_time,
@@ -95,31 +76,14 @@ def activate(self) -> None:
9576
poll_interval = self.config["execution"].get("poll_interval")
9677
with AuthContext(auth=self.auth_type, profile=self.profile):
9778
model_deployment = ModelDeployment.from_id(model_deployment_id)
98-
if (
99-
model_deployment.lifecycle_state
100-
== OCIModelDeployment.LIFECYCLE_STATE_ACTIVE
101-
):
102-
print(
103-
f"Model deployment {model_deployment.model_deployment_id} is already active."
104-
)
105-
return
106-
107-
if (
108-
model_deployment.lifecycle_state
109-
== OCIModelDeployment.LIFECYCLE_STATE_INACTIVE
110-
):
111-
model_deployment.activate(
112-
wait_for_completion=wait_for_completion,
113-
max_wait_time=max_wait_time,
114-
poll_interval=poll_interval,
115-
)
116-
print(
117-
f"Model Deployment {model_deployment.model_deployment_id} has been activated."
118-
)
119-
else:
120-
raise Exception(
121-
f"Can't activate model deployment {model_deployment.model_deployment_id} when it's in {model_deployment.lifecycle_state} state."
122-
)
79+
model_deployment.activate(
80+
wait_for_completion=wait_for_completion,
81+
max_wait_time=max_wait_time,
82+
poll_interval=poll_interval,
83+
)
84+
print(
85+
f"Model Deployment {model_deployment.model_deployment_id} has been activated."
86+
)
12387

12488
def deactivate(self) -> None:
12589
"""
@@ -131,31 +95,14 @@ def deactivate(self) -> None:
13195
poll_interval = self.config["execution"].get("poll_interval")
13296
with AuthContext(auth=self.auth_type, profile=self.profile):
13397
model_deployment = ModelDeployment.from_id(model_deployment_id)
134-
if (
135-
model_deployment.lifecycle_state
136-
== OCIModelDeployment.LIFECYCLE_STATE_INACTIVE
137-
):
138-
print(
139-
f"Model deployment {model_deployment.model_deployment_id} is already inactive."
140-
)
141-
return
142-
143-
if (
144-
model_deployment.lifecycle_state
145-
== OCIModelDeployment.LIFECYCLE_STATE_ACTIVE
146-
):
147-
model_deployment.deactivate(
148-
wait_for_completion=wait_for_completion,
149-
max_wait_time=max_wait_time,
150-
poll_interval=poll_interval,
151-
)
152-
print(
153-
f"Model Deployment {model_deployment.model_deployment_id} has been deactivated."
154-
)
155-
else:
156-
raise Exception(
157-
f"Can't deactivate model deployment {model_deployment.model_deployment_id} when it's in {model_deployment.lifecycle_state} state."
158-
)
98+
model_deployment.deactivate(
99+
wait_for_completion=wait_for_completion,
100+
max_wait_time=max_wait_time,
101+
poll_interval=poll_interval,
102+
)
103+
print(
104+
f"Model Deployment {model_deployment.model_deployment_id} has been deactivated."
105+
)
159106

160107
def watch(self) -> None:
161108
"""

0 commit comments

Comments
 (0)