craft-ai-sdk 0.52.1__tar.gz → 0.53.0__tar.gz

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 craft-ai-sdk might be problematic. Click here for more details.

Files changed (22) hide show
  1. {craft_ai_sdk-0.52.1 → craft_ai_sdk-0.53.0}/PKG-INFO +1 -1
  2. {craft_ai_sdk-0.52.1 → craft_ai_sdk-0.53.0}/craft_ai_sdk/__init__.py +1 -1
  3. {craft_ai_sdk-0.52.1 → craft_ai_sdk-0.53.0}/craft_ai_sdk/core/deployments.py +58 -45
  4. {craft_ai_sdk-0.52.1 → craft_ai_sdk-0.53.0}/craft_ai_sdk/core/steps.py +39 -38
  5. {craft_ai_sdk-0.52.1 → craft_ai_sdk-0.53.0}/craft_ai_sdk/sdk.py +1 -1
  6. {craft_ai_sdk-0.52.1 → craft_ai_sdk-0.53.0}/documentation.pdf +0 -0
  7. {craft_ai_sdk-0.52.1 → craft_ai_sdk-0.53.0}/pyproject.toml +1 -1
  8. {craft_ai_sdk-0.52.1 → craft_ai_sdk-0.53.0}/LICENSE +0 -0
  9. {craft_ai_sdk-0.52.1 → craft_ai_sdk-0.53.0}/README.md +0 -0
  10. {craft_ai_sdk-0.52.1 → craft_ai_sdk-0.53.0}/craft_ai_sdk/constants.py +0 -0
  11. {craft_ai_sdk-0.52.1 → craft_ai_sdk-0.53.0}/craft_ai_sdk/core/data_store.py +0 -0
  12. {craft_ai_sdk-0.52.1 → craft_ai_sdk-0.53.0}/craft_ai_sdk/core/endpoints.py +0 -0
  13. {craft_ai_sdk-0.52.1 → craft_ai_sdk-0.53.0}/craft_ai_sdk/core/environment_variables.py +0 -0
  14. {craft_ai_sdk-0.52.1 → craft_ai_sdk-0.53.0}/craft_ai_sdk/core/pipeline_executions.py +0 -0
  15. {craft_ai_sdk-0.52.1 → craft_ai_sdk-0.53.0}/craft_ai_sdk/core/pipeline_metrics.py +0 -0
  16. {craft_ai_sdk-0.52.1 → craft_ai_sdk-0.53.0}/craft_ai_sdk/core/pipelines.py +0 -0
  17. {craft_ai_sdk-0.52.1 → craft_ai_sdk-0.53.0}/craft_ai_sdk/core/resource_metrics.py +0 -0
  18. {craft_ai_sdk-0.52.1 → craft_ai_sdk-0.53.0}/craft_ai_sdk/core/users.py +0 -0
  19. {craft_ai_sdk-0.52.1 → craft_ai_sdk-0.53.0}/craft_ai_sdk/exceptions.py +0 -0
  20. {craft_ai_sdk-0.52.1 → craft_ai_sdk-0.53.0}/craft_ai_sdk/io.py +0 -0
  21. {craft_ai_sdk-0.52.1 → craft_ai_sdk-0.53.0}/craft_ai_sdk/utils.py +0 -0
  22. {craft_ai_sdk-0.52.1 → craft_ai_sdk-0.53.0}/craft_ai_sdk/warnings.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: craft-ai-sdk
3
- Version: 0.52.1
3
+ Version: 0.53.0
4
4
  Summary: Craft AI MLOps platform SDK
5
5
  Home-page: https://www.craft.ai/
6
6
  License: Apache-2.0
@@ -14,4 +14,4 @@ from .io import ( # noqa: F401
14
14
  )
15
15
 
16
16
 
17
- __version__ = "0.52.1"
17
+ __version__ = "0.53.0"
@@ -29,7 +29,8 @@ def create_deployment(
29
29
  max_parallel_executions_per_pod=None,
30
30
  ram_request=None,
31
31
  gpu_request=None,
32
- timeout_s=3 * 60,
32
+ wait_for_completion=True,
33
+ timeout_s=None,
33
34
  ):
34
35
  """Create a deployment associated with a given pipeline.
35
36
 
@@ -145,8 +146,11 @@ def create_deployment(
145
146
  for "low_latency" deployments mode.
146
147
  gpu_request (:obj:`int`, optional): The number of GPUs requested for the
147
148
  deployment. This is only available for "low_latency" deployments mode.
149
+ wait_for_completion (:obj:`bool`, optional): Whether to wait for the deployment
150
+ to be ready. Defaults to ``True``.
148
151
  timeout_s (:obj:`int`): Maximum time (in seconds) to wait for the deployment to
149
- be ready. 3min (180s) by default, and at least 2min (120s).
152
+ be ready. Set to None to wait indefinitely. Defaults to None.
153
+ Only applicable if ``wait_for_completion`` is ``True``.
150
154
 
151
155
  Returns:
152
156
  :obj:`dict[str, str]`: Created deployment represented as a dict with the
@@ -312,6 +316,9 @@ def create_deployment(
312
316
 
313
317
  """
314
318
 
319
+ if timeout_s is not None and timeout_s <= 0:
320
+ raise ValueError("'timeout_s' must be greater than 0 or None.")
321
+
315
322
  if mode not in set(DEPLOYMENT_MODES):
316
323
  raise ValueError("Invalid 'mode', must be in ['elastic', 'low_latency'].")
317
324
 
@@ -320,9 +327,6 @@ def create_deployment(
320
327
  "Invalid 'execution_rule', must be in ['endpoint', 'periodic']."
321
328
  )
322
329
 
323
- if timeout_s < 120:
324
- raise ValueError("The timeout must be at least 2 minutes (120 seconds).")
325
-
326
330
  url = (
327
331
  f"{sdk.base_environment_api_url}/endpoints"
328
332
  if execution_rule == "endpoint"
@@ -383,50 +387,28 @@ def create_deployment(
383
387
  "Please wait while deployment is being created. This may take a while...",
384
388
  )
385
389
 
386
- start_time = sdk._get_time()
387
390
  sdk._post(url, json=data, get_response=True, allow_redirects=False)
388
391
 
389
- # The deployment is not ready. Keep checking its status until it is ready
390
- elapsed_time = sdk._get_time() - start_time
391
- deployment_status = DEPLOYMENT_STATUS.CREATION_PENDING
392
-
393
- while (
394
- deployment_status
395
- not in [
396
- DEPLOYMENT_STATUS.UP,
397
- DEPLOYMENT_STATUS.CREATION_FAILED,
398
- ]
399
- and elapsed_time < timeout_s
400
- ):
401
- created_deployment = get_deployment(
402
- sdk, deployment_name, wait_for_completion=True
403
- )
404
-
405
- if created_deployment is None:
406
- raise SdkException(
407
- f'The creation of deployment "{deployment_name}" has failed. '
408
- "Please try creating the step again. If this error keeps happening, "
409
- "please contact the support team.",
410
- name="UnexpectedError",
411
- )
412
-
413
- deployment_status = created_deployment.get("status", None)
414
- elapsed_time = sdk._get_time() - start_time
415
-
416
- if deployment_status != DEPLOYMENT_STATUS.UP:
417
- raise SdkException(
418
- 'The deployment was not ready in time. It is still being created but \
419
- this function stopped trying. Please check its status with "get_deployment".',
420
- name="TimeoutException",
421
- )
422
- return created_deployment
392
+ return get_deployment(
393
+ sdk,
394
+ deployment_name,
395
+ wait_for_completion=wait_for_completion,
396
+ timeout_s=timeout_s,
397
+ )
423
398
 
424
399
 
425
- def get_deployment(sdk: BaseCraftAiSdk, deployment_name, **kwargs):
400
+ def get_deployment(
401
+ sdk: BaseCraftAiSdk, deployment_name, wait_for_completion=False, timeout_s=None
402
+ ):
426
403
  """Get information of a deployment.
427
404
 
428
405
  Args:
429
406
  deployment_name (:obj:`str`): Name of the deployment.
407
+ wait_for_completion (:obj:`bool`, optional): Whether to wait for the deployment
408
+ to be ready. Defaults to ``False``.
409
+ timeout_s (:obj:`int`, optional): Maximum time (in seconds) to wait for the
410
+ deployment to be ready. Set to None to wait indefinitely. Defaults to None.
411
+ Only applicable if ``wait_for_completion`` is ``True``.
430
412
 
431
413
  Returns:
432
414
  :obj:`dict`: Deployment information represented as :obj:`dict` with the
@@ -524,10 +506,41 @@ def get_deployment(sdk: BaseCraftAiSdk, deployment_name, **kwargs):
524
506
  * ``pod_id`` (:obj:`str`): ID of the pod.
525
507
  * ``status`` (:obj:`str`): Status of the pod.
526
508
  """
527
- wait_for_completion = kwargs.get("wait_for_completion", False)
528
- url = f"{sdk.base_environment_api_url}/deployments/{deployment_name}\
529
- {'' if not wait_for_completion else '?wait_for_completion=true'}"
530
- deployment = sdk._get(url, allow_redirects=False)
509
+
510
+ if timeout_s is not None and timeout_s <= 0:
511
+ raise ValueError("'timeout_s' must be greater than 0 or None.")
512
+
513
+ deployment = None
514
+
515
+ base_url = f"{sdk.base_environment_api_url}/deployments/{deployment_name}"
516
+
517
+ if wait_for_completion:
518
+ start_time = sdk._get_time()
519
+ elapsed_time = 0
520
+ deployment_status = DEPLOYMENT_STATUS.CREATION_PENDING
521
+ while deployment_status not in [
522
+ DEPLOYMENT_STATUS.UP,
523
+ DEPLOYMENT_STATUS.CREATION_FAILED,
524
+ ] and (timeout_s is None or elapsed_time < timeout_s):
525
+ deployment = sdk._get(
526
+ f"{base_url}?wait_for_completion=true", allow_redirects=False
527
+ )
528
+
529
+ deployment_status = deployment.get("status", None)
530
+ elapsed_time = sdk._get_time() - start_time
531
+
532
+ if deployment_status not in [
533
+ DEPLOYMENT_STATUS.UP,
534
+ DEPLOYMENT_STATUS.CREATION_FAILED,
535
+ ]:
536
+ raise SdkException(
537
+ 'The deployment was not ready in time. It is still being created but \
538
+ this function stopped trying. Please check its status with "get_deployment" with \
539
+ wait_for_completion parameter set to false.',
540
+ name="TimeoutException",
541
+ )
542
+ else:
543
+ deployment = sdk._get(base_url)
531
544
  if deployment is not None:
532
545
  latest_execution = sdk._get(
533
546
  f"\
@@ -31,8 +31,8 @@ def _compress_folder_to_memory(local_folder, include):
31
31
 
32
32
 
33
33
  def _validate_create_step_parameters(inputs, outputs, timeout_s):
34
- if timeout_s < 120:
35
- raise ValueError("The timeout must be at least 2 minutes (120 seconds).")
34
+ if timeout_s is not None and timeout_s <= 0:
35
+ raise ValueError("The timeout must be greater than 0 or None.")
36
36
 
37
37
  if inputs is not None:
38
38
  if any([not isinstance(input_, Input) for input_ in inputs]):
@@ -123,7 +123,9 @@ def _remove_id_from_step(step):
123
123
  def _wait_create_until_ready(sdk, name, get_func, timeout_s, start_time, get_log_func):
124
124
  elapsed_time = sdk._get_time() - start_time
125
125
  status = "creation_pending"
126
- while status == "creation_pending" and elapsed_time < timeout_s:
126
+ while status == "creation_pending" and (
127
+ timeout_s is None or elapsed_time < timeout_s
128
+ ):
127
129
  time.sleep(CREATION_REQUESTS_RETRY_INTERVAL)
128
130
  created_obj = get_func(sdk, name)
129
131
  if created_obj is None:
@@ -162,7 +164,8 @@ def create_step(
162
164
  container_config=None,
163
165
  inputs=None,
164
166
  outputs=None,
165
- timeout_s=3 * 60,
167
+ wait_for_completion=True,
168
+ timeout_s=None,
166
169
  ):
167
170
  """Create pipeline step from a function located on a remote repository or locally.
168
171
 
@@ -232,8 +235,11 @@ def create_step(
232
235
  :obj:`dict` with the name of the output as keys and the value of the
233
236
  output as values. Each output should be specified as an instance
234
237
  of :class:`Output` via this parameter `outputs`.
238
+ wait_for_completion (:obj:`bool`, optional): Whether to wait for the step
239
+ to be created. Defaults to ``True``.
235
240
  timeout_s (:obj:`int`): Maximum time (in seconds) to wait for the step to
236
- be created. 3min (180s) by default, and at least 2min (120s).
241
+ be created. Set to None to wait indefinitely. Defaults to None.
242
+ Only applicable if ``wait_for_completion`` is ``True``.
237
243
 
238
244
  Returns:
239
245
  :obj:`dict`: Created step represented as a :obj:`dict` with the following
@@ -313,33 +319,21 @@ def create_step(
313
319
  "Please wait while step is being created. This may take a while...",
314
320
  )
315
321
 
316
- start_time = sdk._get_time()
317
- created_step, response = sdk._post(
318
- url, data=multipartify(data), files=files, get_response=True
319
- )
322
+ sdk._post(url, data=multipartify(data), files=files, allow_redirects=False)
320
323
 
321
- if response.status_code != 206:
322
- parameters = created_step.get("parameters", {})
323
- message = _add_inputs_outputs_in_message(
324
- f'Step "{step_name}" created',
325
- parameters.get("inputs", []),
326
- parameters.get("outputs", []),
327
- )
328
- log_action(sdk, message)
329
- return _remove_id_from_step(created_step)
324
+ return get_step(sdk, step_name, wait_for_completion, timeout_s)
330
325
 
331
- # The step is still building. Keep checking its status until it is ready
332
- created_step = _wait_create_until_ready(
333
- sdk, step_name, get_step, timeout_s, start_time, get_step_logs
334
- )
335
- return _remove_id_from_step(created_step)
336
326
 
337
-
338
- def get_step(sdk: BaseCraftAiSdk, step_name):
327
+ def get_step(sdk: BaseCraftAiSdk, step_name, wait_for_completion=False, timeout_s=None):
339
328
  """Get a single step if it exists.
340
329
 
341
330
  Args:
342
331
  step_name (:obj:`str`): The name of the step to get.
332
+ wait_for_completion (:obj:`bool`, optional): Whether to wait for the step
333
+ to be created. Defaults to ``False``.
334
+ timeout_s (:obj:`int`): Maximum time (in seconds) to wait for the step to
335
+ be created. Set to None to wait indefinitely. Defaults to None.
336
+ Only applicable if ``wait_for_completion`` is ``True``.
343
337
 
344
338
  Returns:
345
339
  :obj:`dict`: ``None`` if the step does not exist; otherwise
@@ -397,19 +391,26 @@ def get_step(sdk: BaseCraftAiSdk, step_name):
397
391
  * ``"origin"`` (:obj:`str`): The origin of the step, can be
398
392
  ``"git_repository"`` or ``"local"``.
399
393
  """
400
- url = f"{sdk.base_environment_api_url}/steps/{step_name}"
401
- try:
402
- step = sdk._get(url)
403
- except SdkException as error:
404
- if error.status_code == 404:
405
- log_action(
406
- sdk,
407
- "If you are waiting for the step to be created, its creation "
408
- "has failed. Please try creating the step again. "
409
- "If this error keeps happening, please contact the support team.",
410
- )
411
- return None
412
- raise error
394
+ if timeout_s is not None and timeout_s <= 0:
395
+ raise ValueError("The timeout must be greater than to 0 or None.")
396
+
397
+ step = None
398
+
399
+ base_url = f"{sdk.base_environment_api_url}/steps/{step_name}"
400
+
401
+ if wait_for_completion:
402
+ step = _wait_create_until_ready(
403
+ sdk,
404
+ step_name,
405
+ lambda sdk, _: sdk._get(
406
+ f"{base_url}?wait_for_completion=true", allow_redirects=False
407
+ ),
408
+ timeout_s,
409
+ sdk._get_time(),
410
+ get_step_logs,
411
+ )
412
+ else:
413
+ step = sdk._get(base_url)
413
414
  return _remove_id_from_step(step)
414
415
 
415
416
 
@@ -130,7 +130,7 @@ class CraftAiSdk(BaseCraftAiSdk):
130
130
  os.environ.get("CRAFT_AI__MULTIPART_PART_SIZE__B", str(38 * 256 * 1024))
131
131
  )
132
132
  _access_token_margin = timedelta(seconds=30)
133
- _version = "0.52.1" # Would be better to share it somewhere
133
+ _version = "0.53.0" # Would be better to share it somewhere
134
134
 
135
135
  def __init__(
136
136
  self,
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "craft-ai-sdk"
3
- version = "0.52.1"
3
+ version = "0.53.0"
4
4
  description = "Craft AI MLOps platform SDK"
5
5
  license = "Apache-2.0"
6
6
  authors = ["Craft AI <contact@craft.ai>"]
File without changes
File without changes