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 +1 -1
- qwak_sdk/commands/models/deployments/undeploy/_logic/request_undeploy.py +103 -1
- qwak_sdk/commands/models/deployments/undeploy/ui.py +8 -5
- {qwak_sdk-0.5.31.dist-info → qwak_sdk-0.5.32.dist-info}/METADATA +2 -2
- {qwak_sdk-0.5.31.dist-info → qwak_sdk-0.5.32.dist-info}/RECORD +7 -7
- {qwak_sdk-0.5.31.dist-info → qwak_sdk-0.5.32.dist-info}/WHEEL +0 -0
- {qwak_sdk-0.5.31.dist-info → qwak_sdk-0.5.32.dist-info}/entry_points.txt +0 -0
qwak_sdk/__init__.py
CHANGED
|
@@ -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.
|
|
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.
|
|
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=
|
|
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=
|
|
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=
|
|
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.
|
|
365
|
-
qwak_sdk-0.5.
|
|
366
|
-
qwak_sdk-0.5.
|
|
367
|
-
qwak_sdk-0.5.
|
|
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,,
|
|
File without changes
|
|
File without changes
|