qwak-sdk 0.5.31__py3-none-any.whl → 0.5.32__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.

Potentially problematic release.


This version of qwak-sdk might be problematic. Click here for more details.

qwak_sdk/__init__.py CHANGED
@@ -1,6 +1,6 @@
1
1
  # fmt: off
2
2
  __author__ = '''Qwak.ai'''
3
- __version__ = '0.5.31'
3
+ __version__ = '0.5.32'
4
4
 
5
5
  from qwak.inner import wire_dependencies
6
6
 
@@ -1,3 +1,4 @@
1
+ from time import sleep
1
2
  from typing import Dict, List, Set
2
3
 
3
4
  from _qwak_proto.qwak.audience.v1.audience_pb2 import AudienceRoutesEntry
@@ -24,13 +25,19 @@ from qwak_sdk.commands.models.deployments.deploy._logic.deploy_config import (
24
25
  from qwak_sdk.commands.models.deployments.undeploy._logic.variations import (
25
26
  validate_variations_for_undeploy,
26
27
  )
28
+ from qwak_sdk.tools.utils import qwak_spinner
27
29
 
28
30
  NO_DEPLOYED_VARIATIONS_ERROR_MSG = (
29
31
  "There are currently no deployed variations for model {model_id} in {env_name}"
30
32
  )
31
-
33
+ UNDEPLOY_ERROR_MSG = "Environment {environment_id} failed with status: {status}"
32
34
  logger = get_qwak_logger()
33
35
 
36
+ FAILED_UNDEPLOYMENT_STATUS = ["FAILED_UNDEPLOYMENT"]
37
+ SUCCESSFUL_UNDEPLOYMENT_STATUS = ["SUCCESSFUL_UNDEPLOYMENT"]
38
+ END_UNDEPLOYMENT_STATUSES = SUCCESSFUL_UNDEPLOYMENT_STATUS + FAILED_UNDEPLOYMENT_STATUS
39
+ TIME_TO_WAIT_FOR_UNDEPLOYMENT_POLLING = 5
40
+
34
41
 
35
42
  def get_deployed_variation_name(existing_variations_names: Set[str]) -> str:
36
43
  return list(existing_variations_names)[0]
@@ -123,6 +130,7 @@ def undeploy(
123
130
  model_id: str,
124
131
  config: DeployConfig,
125
132
  model_uuid: str = "",
133
+ sync: bool = False,
126
134
  ):
127
135
  deployment_client = DeploymentManagementClient()
128
136
  ecosystem_client = EcosystemClient()
@@ -161,14 +169,108 @@ def undeploy(
161
169
  config.realtime.fallback_variation,
162
170
  )
163
171
 
172
+ environment_to_deployment_id = {}
173
+ if sync:
174
+ environment_to_deployment_id = __get_environment_to_deployment_id(
175
+ deployment_client, model_id, model_uuid, env_undeployment_requests
176
+ )
177
+
164
178
  undeployment_response = deployment_client.undeploy_model(
165
179
  model_id=model_id,
166
180
  model_uuid=model_uuid,
167
181
  env_undeployment_requests=env_undeployment_requests,
168
182
  )
169
183
 
184
+ if sync:
185
+ __sync_undeploy(
186
+ environment_to_deployment_id=environment_to_deployment_id,
187
+ model_id=model_id,
188
+ deployment_client=deployment_client,
189
+ )
170
190
  logger.info(
171
191
  f"Current status is {ModelDeploymentStatus.Name(undeployment_response.status)}."
172
192
  )
173
193
 
174
194
  return undeployment_response
195
+
196
+
197
+ def __get_environment_to_deployment_id(
198
+ deployment_client: DeploymentManagementClient,
199
+ model_id: str,
200
+ model_uuid: str,
201
+ env_undeployment_requests: Dict,
202
+ ) -> Dict:
203
+ deployment_details = deployment_client.get_deployment_details(
204
+ model_id, model_uuid
205
+ ).environment_to_deployment_details
206
+ result = {}
207
+ for env_id, env_deployment_details in env_undeployment_requests.items():
208
+ deployment_detail_by_env = deployment_details.get(env_id)
209
+ if deployment_detail_by_env:
210
+ for deployment_detail in deployment_detail_by_env.deployments_details:
211
+ if (
212
+ env_id == deployment_detail.environment_id
213
+ and deployment_detail.variation.name
214
+ == env_deployment_details.traffic_config.selected_variation_name
215
+ ):
216
+ result[env_id] = deployment_detail.deployment_id
217
+ return result
218
+
219
+
220
+ def __sync_undeploy(
221
+ environment_to_deployment_id: Dict,
222
+ model_id: str,
223
+ deployment_client: DeploymentManagementClient,
224
+ ):
225
+ with qwak_spinner(
226
+ begin_text=f"Undeploy - model: {model_id}",
227
+ end_text="Successful undeployment",
228
+ print_callback=print,
229
+ ):
230
+ for environment_id, deployment_id in environment_to_deployment_id.items():
231
+ status_result = _poll_undeployment_status(
232
+ deployment_id=deployment_id,
233
+ deployment_client=deployment_client,
234
+ check_every_n_seconds=TIME_TO_WAIT_FOR_UNDEPLOYMENT_POLLING,
235
+ )
236
+ failed_to_undeployment = []
237
+ for _, status in status_result.items():
238
+ if status in FAILED_UNDEPLOYMENT_STATUS:
239
+ failed_to_undeployment.append(
240
+ UNDEPLOY_ERROR_MSG.format(
241
+ environment_id=environment_id, status=status
242
+ )
243
+ )
244
+ if failed_to_undeployment:
245
+ raise QwakException("\n".join(failed_to_undeployment))
246
+
247
+
248
+ def _poll_undeployment_status(
249
+ deployment_id: str,
250
+ deployment_client: DeploymentManagementClient,
251
+ check_every_n_seconds: int,
252
+ ) -> Dict:
253
+ deployment_status = ""
254
+
255
+ while deployment_status not in END_UNDEPLOYMENT_STATUSES:
256
+ sleep(check_every_n_seconds)
257
+ deployment_status = __get_deployment_status(
258
+ deployment_id=deployment_id, deployment_client=deployment_client
259
+ )
260
+ return {deployment_id: deployment_status}
261
+
262
+
263
+ def __get_deployment_status(
264
+ deployment_id: str, deployment_client: DeploymentManagementClient
265
+ ):
266
+ try:
267
+ return ModelDeploymentStatus.Name(
268
+ deployment_client.get_deployment_status(
269
+ deployment_named_id=deployment_id,
270
+ ).status
271
+ )
272
+ except QwakException as e:
273
+ logger.error(
274
+ f"Got error while trying to get deployment id: {deployment_id} status. Error is: {e.message}"
275
+ )
276
+ return ""
@@ -42,11 +42,18 @@ logger = get_qwak_logger()
42
42
  required=False,
43
43
  type=click.Path(exists=True, resolve_path=True, dir_okay=False),
44
44
  )
45
+ @click.option(
46
+ "--sync",
47
+ is_flag=True,
48
+ default=False,
49
+ help="Waiting for deployments to be undeploy",
50
+ )
45
51
  def models_undeploy(
46
52
  model_id: str,
47
53
  variation_name: str,
48
54
  environment_name: List[str],
49
55
  from_file: str = None,
56
+ sync: bool = False,
50
57
  **kwargs,
51
58
  ):
52
59
  logger.info(f"Initiating undeployment for model '{model_id}'")
@@ -62,8 +69,4 @@ def models_undeploy(
62
69
  )
63
70
  model_uuid = models_management.get_model_uuid(model_id)
64
71
 
65
- undeploy(
66
- model_id=model_id,
67
- config=config,
68
- model_uuid=model_uuid,
69
- )
72
+ undeploy(model_id=model_id, config=config, model_uuid=model_uuid, sync=sync)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: qwak-sdk
3
- Version: 0.5.31
3
+ Version: 0.5.32
4
4
  Summary: Qwak SDK and CLI for qwak models
5
5
  License: Apache-2.0
6
6
  Keywords: mlops,ml,deployment,serving,model
@@ -28,7 +28,7 @@ Requires-Dist: pandas (<1.4) ; (python_full_version >= "3.7.1" and python_versio
28
28
  Requires-Dist: pandas (>=1.4.3,<2.0.0) ; (python_version >= "3.8" and python_version < "3.10") and (extra == "batch" or extra == "feedback")
29
29
  Requires-Dist: pyarrow (>=6.0.0,<11.0.0) ; extra == "batch"
30
30
  Requires-Dist: python-json-logger (>=2.0.2)
31
- Requires-Dist: qwak-core (==0.1.17)
31
+ Requires-Dist: qwak-core (==0.1.36)
32
32
  Requires-Dist: qwak-inference (==0.1.8)
33
33
  Requires-Dist: tabulate (>=0.8.0)
34
34
  Requires-Dist: yaspin (>=2.0.0)
@@ -1,4 +1,4 @@
1
- qwak_sdk/__init__.py,sha256=Rt4uYbogeR0ulOjOSGXFtDCRix2CdGqMlX0ulTvsPb0,135
1
+ qwak_sdk/__init__.py,sha256=huJCMSFUcwVASX5p43L2I3GPEx5O4EKNrTDBkQKeuI4,135
2
2
  qwak_sdk/cli.py,sha256=FIK1dUNxR57ypb-CeD7fKSJnPJ02lrjR9G4aj2qMLPU,2458
3
3
  qwak_sdk/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
4
  qwak_sdk/commands/_logic/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -199,9 +199,9 @@ qwak_sdk/commands/models/deployments/deploy/streaming/_logic/serving_strategy_ma
199
199
  qwak_sdk/commands/models/deployments/deploy/streaming/ui.py,sha256=9tPMnVnLNX3lYyBd4BAh-YThDFz99oyvrCRd_tDZufU,5796
200
200
  qwak_sdk/commands/models/deployments/undeploy/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
201
201
  qwak_sdk/commands/models/deployments/undeploy/_logic/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
202
- qwak_sdk/commands/models/deployments/undeploy/_logic/request_undeploy.py,sha256=8DMxVBFHa_Hf_iC-RwHZaCoiP3DEXvMeUP1Ah42zuZY,5677
202
+ qwak_sdk/commands/models/deployments/undeploy/_logic/request_undeploy.py,sha256=e-9lHQ2AbTyogUHxppPVli5pugl6ml4c1zAuFoLQTpw,9481
203
203
  qwak_sdk/commands/models/deployments/undeploy/_logic/variations.py,sha256=qo4qUB78voUhtM1YIuTz1OSBaLRS3xw97bwxgqRuLgI,3036
204
- qwak_sdk/commands/models/deployments/undeploy/ui.py,sha256=NDEir1x0s44r2iF_4hSe-lC7pXmHBYyZJ0Sr1cmV8Nk,1885
204
+ qwak_sdk/commands/models/deployments/undeploy/ui.py,sha256=1XYBouPgbJWOJCNR1UU1UOVnQS10iKsUqeNkvIBhHY8,2008
205
205
  qwak_sdk/commands/models/describe/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
206
206
  qwak_sdk/commands/models/describe/_logic.py,sha256=LN1r3zrXLHf83U5ate7ED7VdoZuWUqcHwLZPMMZXRfs,5589
207
207
  qwak_sdk/commands/models/describe/ui.py,sha256=6QHt_EQRe5yRV9e2yYOAROfqU-_BfmS0VHXP4hfY6D8,968
@@ -361,7 +361,7 @@ qwak_sdk/tools/colors.py,sha256=7pui_GGjC4uZKYFsIyXaJjYsjLxJVHb4OrfTgr93hqo,287
361
361
  qwak_sdk/tools/files.py,sha256=AyKJTOy7NhvP3SrqwIw_lxYNCOy1CvLgMmSJpWZ0OKM,2257
362
362
  qwak_sdk/tools/log_handling.py,sha256=NIQ-5uCb2NHzB7KwIbqbR9EhmhL1bawXLD_oamB6Gok,5711
363
363
  qwak_sdk/tools/utils.py,sha256=SHmU4r_m2ABZyFYMC03P17GvltPbYbmB39hvalIZEtI,1168
364
- qwak_sdk-0.5.31.dist-info/entry_points.txt,sha256=vSl0ELYDyj640oMM57u0AjBP87wtLYxCcGOendhEx80,47
365
- qwak_sdk-0.5.31.dist-info/WHEEL,sha256=vVCvjcmxuUltf8cYhJ0sJMRDLr1XsPuxEId8YDzbyCY,88
366
- qwak_sdk-0.5.31.dist-info/METADATA,sha256=wqDCmtDxGBcoYp8DB25q3l5VcFKV_TJ27QlSbk6B3Ok,1885
367
- qwak_sdk-0.5.31.dist-info/RECORD,,
364
+ qwak_sdk-0.5.32.dist-info/entry_points.txt,sha256=vSl0ELYDyj640oMM57u0AjBP87wtLYxCcGOendhEx80,47
365
+ qwak_sdk-0.5.32.dist-info/WHEEL,sha256=vVCvjcmxuUltf8cYhJ0sJMRDLr1XsPuxEId8YDzbyCY,88
366
+ qwak_sdk-0.5.32.dist-info/METADATA,sha256=tpM7nE5JSP8lkm_GJuMeSvSd5YQt8VEs2Nsgse0jxbk,1885
367
+ qwak_sdk-0.5.32.dist-info/RECORD,,