lightning-sdk 0.1.53__py3-none-any.whl → 0.1.54__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.
lightning_sdk/__init__.py CHANGED
@@ -29,5 +29,5 @@ __all__ = [
29
29
  "AIHub",
30
30
  ]
31
31
 
32
- __version__ = "0.1.53"
32
+ __version__ = "0.1.54"
33
33
  _check_version_and_prompt_upgrade(__version__)
@@ -213,6 +213,14 @@ class DeploymentApi:
213
213
  return None
214
214
  raise ex
215
215
 
216
+ def get_deployment_by_id(self, deployment_id: str, teamspace_id: str) -> Optional[V1Deployment]:
217
+ try:
218
+ return self._client.jobs_service_get_deployment(project_id=teamspace_id, id=deployment_id)
219
+ except ApiException as ex:
220
+ if "Reason: Not Found" in str(ex):
221
+ return None
222
+ raise ex
223
+
216
224
  def create_deployment(
217
225
  self,
218
226
  deployment: V1Deployment,
@@ -269,7 +277,7 @@ class DeploymentApi:
269
277
  requires_release |= apply_change(deployment.spec, "entrypoint", entrypoint)
270
278
  requires_release |= apply_change(deployment.spec, "command", command)
271
279
  requires_release |= apply_change(deployment.spec, "env", to_env(env))
272
- requires_release |= apply_change(deployment.spec, "env", to_health_check(health_check))
280
+ requires_release |= apply_change(deployment.spec, "readiness_probe", to_health_check(health_check))
273
281
  requires_release |= apply_change(deployment.spec, "cluster_id", cloud_account)
274
282
  requires_release |= apply_change(deployment.spec, "spot", spot)
275
283
 
@@ -275,7 +275,7 @@ class JobApiV2:
275
275
  return
276
276
 
277
277
  if current_state != Status.Stopping:
278
- update_body = JobsIdBody1(cloudspace_id=current_job.spec.cloudspace_id, state=self.v2_job_state_stop)
278
+ update_body = JobsIdBody1(state=self.v2_job_state_stop)
279
279
  self._client.jobs_service_update_job(body=update_body, project_id=teamspace_id, id=job_id)
280
280
 
281
281
  while True:
@@ -48,7 +48,8 @@ class LitContainerApi:
48
48
  raise ValueError(f"Container {container} does not exist") from None
49
49
 
50
50
  registry_url = _get_registry_url()
51
- repository = f"{registry_url}/lit-container/{teamspace.owner.name}/{teamspace.name}/{container}"
51
+ container_basename = container.split("/")[-1]
52
+ repository = f"{registry_url}/lit-container/{teamspace.owner.name}/{teamspace.name}/{container_basename}"
52
53
  tagged = self._docker_client.api.tag(container, repository, tag)
53
54
  if not tagged:
54
55
  raise ValueError(f"Could not tag container {container} with {repository}:{tag}")
@@ -42,7 +42,7 @@ class Deployment:
42
42
  and switching machine types, etc..
43
43
 
44
44
  Args:
45
- name: The name of the deployment.
45
+ name: The name or the id of the deployment.
46
46
  teamspace: The teamspace in which you want to deploy.
47
47
  org: The name of the organization owning the :param`teamspace` in case it is owned by an org
48
48
  user: The name of the user owning the :param`teamspace` in case it is owned directly by a user instead of an org
@@ -55,7 +55,7 @@ class Deployment:
55
55
 
56
56
  def __init__(
57
57
  self,
58
- name: str, # Only the name is required in case a deployment already exist.
58
+ name: str,
59
59
  teamspace: Optional[Union[str, Teamspace]] = None,
60
60
  org: Optional[Union[str, Organization]] = None,
61
61
  user: Optional[Union[str, User]] = None,
@@ -83,8 +83,14 @@ class Deployment:
83
83
  self._deployment_api = DeploymentApi()
84
84
  self._cloud_account = _get_cluster(client=self._deployment_api._client, project_id=self._teamspace.id)
85
85
  self._is_created = False
86
- deployment = self._deployment_api.get_deployment_by_name(name, self._teamspace.id)
86
+
87
+ if name.startswith("dep_"):
88
+ deployment = self._deployment_api.get_deployment_by_id(name, self._teamspace.id)
89
+ else:
90
+ deployment = self._deployment_api.get_deployment_by_name(name, self._teamspace.id)
91
+
87
92
  if deployment:
93
+ self._name = deployment.name
88
94
  self._is_created = True
89
95
  self._deployment = deployment
90
96
 
@@ -163,6 +169,9 @@ class Deployment:
163
169
  strategy=to_strategy(release_strategy),
164
170
  )
165
171
  )
172
+
173
+ # Overrides the name
174
+ self._name = self._deployment._name
166
175
  self._is_created = True
167
176
 
168
177
  def update(
lightning_sdk/job/base.py CHANGED
@@ -275,20 +275,25 @@ class _BaseJob(ABC):
275
275
  Caution: This also deletes all artifacts and snapshots associated with the job.
276
276
  """
277
277
 
278
- def wait(self, interval: float = 5.0) -> None:
278
+ def wait(self, interval: float = 5.0, timeout: Optional[float] = None) -> None:
279
279
  """Waits for the job to be either completed, manually stopped or failed.
280
280
 
281
281
  Args:
282
- interval: the number of seconds to spend in-between status checks.
282
+ interval: The number of seconds to spend in-between status checks.
283
+ timeout: The maximum number of seconds to wait before raising an error. If None, waits forever.
283
284
  """
284
285
  import time
285
286
 
286
287
  from lightning_sdk.status import Status
287
288
 
289
+ start = time.time()
288
290
  while True:
289
291
  if self.status in (Status.Completed, Status.Stopped, Status.Failed):
290
292
  break
291
293
 
294
+ if timeout is not None and time.time() - start > timeout:
295
+ raise TimeoutError("Job didn't finish within the provided timeout.")
296
+
292
297
  time.sleep(interval)
293
298
 
294
299
  @property
lightning_sdk/job/job.py CHANGED
@@ -1,7 +1,5 @@
1
- from functools import lru_cache
2
1
  from typing import TYPE_CHECKING, Any, Dict, Optional, Union
3
2
 
4
- from lightning_sdk.api.user_api import UserApi
5
3
  from lightning_sdk.job.base import _BaseJob
6
4
  from lightning_sdk.job.v1 import _JobV1
7
5
  from lightning_sdk.job.v2 import _JobV2
@@ -18,15 +16,6 @@ if TYPE_CHECKING:
18
16
  from lightning_sdk.user import User
19
17
 
20
18
 
21
- @lru_cache(maxsize=None)
22
- def _has_jobs_v2() -> bool:
23
- api = UserApi()
24
- try:
25
- return api._get_feature_flags().jobs_v2
26
- except Exception:
27
- return False
28
-
29
-
30
19
  class Job(_BaseJob):
31
20
  """Class to submit and manage single-machine jobs on the Lightning AI Platform."""
32
21
 
@@ -52,7 +41,7 @@ class Job(_BaseJob):
52
41
  """
53
42
  from lightning_sdk.lightning_cloud.openapi.rest import ApiException
54
43
 
55
- if _has_jobs_v2() and not self._force_v1:
44
+ if not self._force_v1:
56
45
  # try with v2 and fall back to v1
57
46
  try:
58
47
  job = _JobV2(
lightning_sdk/job/v1.py CHANGED
@@ -126,38 +126,7 @@ class _JobV1(_BaseJob):
126
126
  The submitted job.
127
127
 
128
128
  """
129
- if studio is None:
130
- raise ValueError("Studio is required for submitting jobs")
131
- if image is not None or image_credentials is not None or cloud_account_auth:
132
- raise ValueError("Image is not supported for submitting jobs")
133
-
134
- if artifacts_local is not None or artifacts_remote is not None:
135
- raise ValueError("Specifying how to persist artifacts is not yet supported with jobs")
136
-
137
- if env is not None:
138
- raise ValueError("Environment variables are not supported for submitting jobs")
139
- if command is None:
140
- raise ValueError("Command is required for submitting jobs")
141
-
142
- if entrypoint != "sh -c":
143
- raise ValueError("Specifying the entrypoint is not yet supported with jobs")
144
-
145
- if path_mappings is not None:
146
- raise ValueError("Specifying path mappings is not yet supported with jobs")
147
-
148
- # TODO: add support for empty names (will give an empty string)
149
- _submitted = self._job_api.submit_job(
150
- name=self._name,
151
- command=command,
152
- studio_id=studio._studio.id,
153
- teamspace_id=self._teamspace.id,
154
- cloud_account=cloud_account or "",
155
- machine=machine,
156
- interruptible=interruptible,
157
- )
158
- self._name = _submitted.name
159
- self._job = _submitted
160
- return self
129
+ raise NotImplementedError("Cannot submit new jobs with JobsV1!")
161
130
 
162
131
  def _update_internal_job(self) -> None:
163
132
  try:
lightning_sdk/job/v2.py CHANGED
@@ -140,7 +140,12 @@ class _JobV2(_BaseJob):
140
140
  @property
141
141
  def status(self) -> "Status":
142
142
  """The current status of the job."""
143
- return self._job_api._job_state_to_external(self._latest_job.state)
143
+ try:
144
+ return self._job_api._job_state_to_external(self._latest_job.state)
145
+ except Exception:
146
+ raise RuntimeError(
147
+ f"Job {self._name} does not exist in Teamspace {self.teamspace.name}. Did you delete it?"
148
+ ) from None
144
149
 
145
150
  @property
146
151
  def machine(self) -> Union["Machine", str]:
lightning_sdk/mmt/mmt.py CHANGED
@@ -2,7 +2,6 @@ from functools import lru_cache
2
2
  from typing import TYPE_CHECKING, Any, Dict, Optional, Tuple, Union
3
3
 
4
4
  from lightning_sdk.api.user_api import UserApi
5
- from lightning_sdk.job.job import _has_jobs_v2
6
5
  from lightning_sdk.mmt.base import MMTMachine, _BaseMMT
7
6
  from lightning_sdk.mmt.v1 import _MMTV1
8
7
  from lightning_sdk.mmt.v2 import _MMTV2
@@ -21,16 +20,18 @@ _logger = _setup_logger(__name__)
21
20
 
22
21
  @lru_cache(maxsize=None)
23
22
  def _has_mmt_v2() -> bool:
24
- # users need both mmtv2 and jobsv2 flags in order for mmtv2 to work correctly
25
- if not _has_jobs_v2():
26
- return False
27
-
28
23
  api = UserApi()
29
24
  try:
30
- return api._get_feature_flags().mmt_v2
25
+ feature_flags = api._get_feature_flags()
31
26
  except Exception:
32
27
  return False
33
28
 
29
+ try:
30
+ return feature_flags.mmt_v2
31
+ except AttributeError:
32
+ # Feature flag doesn't exist anymore, so return True
33
+ return True
34
+
34
35
 
35
36
  class MMT(_BaseMMT):
36
37
  """Class to submit and manage multi-machine jobs on the Lightning AI Platform."""
lightning_sdk/plugin.py CHANGED
@@ -432,6 +432,8 @@ def _success_message(resp: Union["Externalv1LightningappInstance", Job], plugin_
432
432
  def forced_v1(cls: Any) -> Generator[Any, None, None]:
433
433
  """Forces to use the v1 version of a class when using a class with multiple backends."""
434
434
  orig_val = getattr(cls, "_force_v1", False)
435
- cls._force_v1 = True
436
- yield cls
437
- cls._force_v1 = orig_val
435
+ try:
436
+ cls._force_v1 = True
437
+ yield cls
438
+ finally:
439
+ cls._force_v1 = orig_val
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: lightning_sdk
3
- Version: 0.1.53
3
+ Version: 0.1.54
4
4
  Summary: SDK to develop using Lightning AI Studios
5
5
  Author-email: Lightning-AI <justus@lightning.ai>
6
6
  License: MIT License
@@ -1,5 +1,5 @@
1
1
  docs/source/conf.py,sha256=r8yX20eC-4mHhMTd0SbQb5TlSWHhO6wnJ0VJ_FBFpag,13249
2
- lightning_sdk/__init__.py,sha256=OspSXvFP3ft-tLCeHCDtd7YyPmS4jKx7hWDf0rVmHIs,970
2
+ lightning_sdk/__init__.py,sha256=u3LjkfJQaHe9jKJXPyYO90NDPaQM7UezZxVhedZtvdA,970
3
3
  lightning_sdk/agents.py,sha256=ly6Ma1j0ZgGPFyvPvMN28JWiB9dATIstFa5XM8pMi6I,1577
4
4
  lightning_sdk/ai_hub.py,sha256=CpbpizTr3yzOCaEth0F1_mMifnR7Vf84quvthQnjzg4,6239
5
5
  lightning_sdk/constants.py,sha256=ztl1PTUBULnqTf3DyKUSJaV_O20hNtUYT6XvAYIrmIk,749
@@ -9,7 +9,7 @@ lightning_sdk/machine.py,sha256=qutfVwQJHC02c2ygB_O5wrFI-Eq9zbfA0E1OPEYcCO0,861
9
9
  lightning_sdk/models.py,sha256=Ssb88nspTKs_bPnZSixsTEi30FaKkmUEEVlf7ElQQ6s,5610
10
10
  lightning_sdk/organization.py,sha256=WCfzdgjtvY1_A07DnxOpp74V2JR2gQwtXbIEcFDnoVU,1232
11
11
  lightning_sdk/owner.py,sha256=t5svD2it4C9pbSpVuG9WJL46CYi37JXNziwnXxhiU5U,1361
12
- lightning_sdk/plugin.py,sha256=nWFL1l6Q9DE8Lr2krD5qRhZljwmYm00R2eR1tYRb20s,14902
12
+ lightning_sdk/plugin.py,sha256=qv0oUuclcimQUcw4wsgNrbwKT-kjsDq65Vn78i3X_4c,14936
13
13
  lightning_sdk/status.py,sha256=lLGAuSvXBoXQFEEsEYwdCi0RcSNatUn5OPjJVjDtoM0,386
14
14
  lightning_sdk/studio.py,sha256=cDdVM70JXUj4tAjGBg6Purrd-_g92HNe_YgnOCxcMdU,19576
15
15
  lightning_sdk/teamspace.py,sha256=j6EghDJvxrYoWT1xMOA4qGAw3ezIpEytqGr-QlFnRXE,13247
@@ -17,9 +17,9 @@ lightning_sdk/user.py,sha256=vdn8pZqkAZO0-LoRsBdg0TckRKtd_H3QF4gpiZcl4iY,1130
17
17
  lightning_sdk/api/__init__.py,sha256=Qn2VVRvir_gO7w4yxGLkZY-R3T7kdiTPKgQ57BhIA9k,413
18
18
  lightning_sdk/api/agents_api.py,sha256=G47TbFo9kYqnBMqdw2RW-lfS1VAUBSXDmzs6fpIEMUs,4059
19
19
  lightning_sdk/api/ai_hub_api.py,sha256=NIFZcwibvicCK-oj9Vfm9ylGyXCFRn8gHIo-nmncKgY,5904
20
- lightning_sdk/api/deployment_api.py,sha256=T480Nej7LqmtkAx8SBkPGQ5JxeyQ-GVIDqUCc7Z1yfk,21448
21
- lightning_sdk/api/job_api.py,sha256=3ohMeDjeOaQAWU2qwbg4v5cDWF3U915hECMODxTdN6M,12541
22
- lightning_sdk/api/lit_container_api.py,sha256=zgmLcX6883nCWPLNMEANYTLB4zXAbMwXvGacHTzN5wI,3371
20
+ lightning_sdk/api/deployment_api.py,sha256=AQh84-N2afeLIXvTgqkZUpOslt_7Tioi6_GUG_J1AWI,21809
21
+ lightning_sdk/api/job_api.py,sha256=KhSZfjNlKtRFpT0yhVFyQ1tOOB16_C2UYWk_AqWrXro,12495
22
+ lightning_sdk/api/lit_container_api.py,sha256=Cc5Whytka06xTzbDvAgnDj3a6ZBiY9vv0WV9I8RbvZY,3434
23
23
  lightning_sdk/api/mmt_api.py,sha256=km27mnZ7CT_TYa3ofjVrPlidjRMJk32pnznHxjVf1OM,7633
24
24
  lightning_sdk/api/org_api.py,sha256=Ze3z_ATVrukobujV5YdC42DKj45Vuwl7X52q_Vr-o3U,803
25
25
  lightning_sdk/api/studio_api.py,sha256=Cfsq8HFc4uUsj8hncnhnD_TLhw0cg-ryclGowj8S6Y0,26374
@@ -45,12 +45,12 @@ lightning_sdk/cli/studios_menu.py,sha256=0kQGqGel8gAbpdJtjOM1a6NEat_TnIqRNprNn8Q
45
45
  lightning_sdk/cli/teamspace_menu.py,sha256=GVTrMAqxxL3INX83alo5wybnrl6rBBKENo01ZNkWPik,3753
46
46
  lightning_sdk/cli/upload.py,sha256=cvirl8lfPiGV4THa5akeRy1KDoPx7Klj7tTrvWePwLc,11501
47
47
  lightning_sdk/deployment/__init__.py,sha256=BLu7_cVLp97TYxe6qe-J1zKUSZXAVcvCjgcA7plV2k4,497
48
- lightning_sdk/deployment/deployment.py,sha256=Dp15pn8rFAfMfaDhKn0v3bphFuvLgkPFs3KSNxW6eyc,15472
48
+ lightning_sdk/deployment/deployment.py,sha256=Fn8iJVimaWB0Ngz53oJ03kBUzVe5_-3oHAbvEqFTf0s,15681
49
49
  lightning_sdk/job/__init__.py,sha256=1MxjQ6rHkyUHCypSW9RuXuVMVH11WiqhIXcU2LCFMwE,64
50
- lightning_sdk/job/base.py,sha256=VFMWFMZXUHxMD18DV3fljJr6gJd8RvT_IvW9OxkKSPo,17423
51
- lightning_sdk/job/job.py,sha256=TyueqMyci4rxmbDhqB3WUlkYsOHRFwl4lQrNv87I5As,13338
52
- lightning_sdk/job/v1.py,sha256=F9XqJTVx2JomxM6jYXqTpE394zTGZVGWv1JtAetj3uY,10378
53
- lightning_sdk/job/v2.py,sha256=7tamPEbgK6JuqsC3BFMi8Z2-wWR7qvnhjvdo0hTbNFw,10078
50
+ lightning_sdk/job/base.py,sha256=TS5KavtfBAFbLbNqqumEizY9edjO1joSmtUdcO5CThQ,17748
51
+ lightning_sdk/job/job.py,sha256=X4MLFZCZOtEhNlHIWZESR5mPrS4z6bhw3rSNXxuIHSA,13065
52
+ lightning_sdk/job/v1.py,sha256=zgdZFnlyhzOBlbwdwx6Ob9YKBrzMnJflzLXy4qyb4So,9070
53
+ lightning_sdk/job/v2.py,sha256=9O31CwIQjwm6qZSEZtFBWbZyBuCSmyFMsHCRbQvJdBU,10283
54
54
  lightning_sdk/job/work.py,sha256=Xm5byWTcOxYI8zZ3Sz6P8HxBTBAJ3S2KucndXA5KePQ,2332
55
55
  lightning_sdk/lightning_cloud/__init__.py,sha256=o91SMAlwr4Ke5ESe8fHjqXcj31_h7rT-MlFoXA-n2EI,173
56
56
  lightning_sdk/lightning_cloud/__version__.py,sha256=lOfmWHtjmiuSG28TbKQqd2B3nwmSGOlKVFwhaj_cRJk,23
@@ -869,7 +869,7 @@ lightning_sdk/lightning_cloud/utils/name_generator.py,sha256=MkciuA10332V0mcE2Px
869
869
  lightning_sdk/lightning_cloud/utils/network.py,sha256=axPgl8rhyPcPjxiztDxyksfxax3VNg2OXL5F5Uc81b4,406
870
870
  lightning_sdk/mmt/__init__.py,sha256=ExMu90-96bGBnyp5h0CErQszUGB1-PcjC4-R8_NYbeY,117
871
871
  lightning_sdk/mmt/base.py,sha256=B3HC-c82bPHprEZh1mhLCPCrCE8BOKqwIhY7xCF9CXg,15152
872
- lightning_sdk/mmt/mmt.py,sha256=Ha0Sp-m4_qBFuxDvASBt5ir_mVonPqcjyDS1QbIl0wQ,13894
872
+ lightning_sdk/mmt/mmt.py,sha256=UbbK6UFEd-S2OPjezCG7cy-7kfMbyLOg3LAzs_Zq2Ds,13872
873
873
  lightning_sdk/mmt/v1.py,sha256=dROOXRWLzG2kUwGtvozB9Vywt_3QK8j4XFHVZFohWUM,9527
874
874
  lightning_sdk/mmt/v2.py,sha256=Em1XBoqViqUMKm-sshzdMcSH5UTtZZwbJcsgqY6-mw0,9625
875
875
  lightning_sdk/services/__init__.py,sha256=gSWUjccEhMI9CIWL_nbrFHUK2S6TM2725mEzrLMfK1Y,225
@@ -880,9 +880,9 @@ lightning_sdk/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSu
880
880
  lightning_sdk/utils/dynamic.py,sha256=glUTO1JC9APtQ6Gr9SO02a3zr56-sPAXM5C3NrTpgyQ,1959
881
881
  lightning_sdk/utils/enum.py,sha256=h2JRzqoBcSlUdanFHmkj_j5DleBHAu1esQYUsdNI-hU,4106
882
882
  lightning_sdk/utils/resolve.py,sha256=idhRk4zg0jBOlySwKwjhsGgRorpsNVHOKOADOxMUYY0,6062
883
- lightning_sdk-0.1.53.dist-info/LICENSE,sha256=uFIuZwj5z-4TeF2UuacPZ1o17HkvKObT8fY50qN84sg,1064
884
- lightning_sdk-0.1.53.dist-info/METADATA,sha256=pjXt-rc8W-jTPmfq_ric7-NBi0t_82uks-e-z2yl3Ss,4013
885
- lightning_sdk-0.1.53.dist-info/WHEEL,sha256=P9jw-gEje8ByB7_hXoICnHtVCrEwMQh-630tKvQWehc,91
886
- lightning_sdk-0.1.53.dist-info/entry_points.txt,sha256=msB9PJWIJ784dX-OP8by51d4IbKYH3Fj1vCuA9oXjHY,68
887
- lightning_sdk-0.1.53.dist-info/top_level.txt,sha256=ps8doKILFXmN7F1mHncShmnQoTxKBRPIcchC8TpoBw4,19
888
- lightning_sdk-0.1.53.dist-info/RECORD,,
883
+ lightning_sdk-0.1.54.dist-info/LICENSE,sha256=uFIuZwj5z-4TeF2UuacPZ1o17HkvKObT8fY50qN84sg,1064
884
+ lightning_sdk-0.1.54.dist-info/METADATA,sha256=H9hzgevLDkHwM5VHEHnGB-7RHuIeNSOUtjp3ie_OhBw,4013
885
+ lightning_sdk-0.1.54.dist-info/WHEEL,sha256=P9jw-gEje8ByB7_hXoICnHtVCrEwMQh-630tKvQWehc,91
886
+ lightning_sdk-0.1.54.dist-info/entry_points.txt,sha256=msB9PJWIJ784dX-OP8by51d4IbKYH3Fj1vCuA9oXjHY,68
887
+ lightning_sdk-0.1.54.dist-info/top_level.txt,sha256=ps8doKILFXmN7F1mHncShmnQoTxKBRPIcchC8TpoBw4,19
888
+ lightning_sdk-0.1.54.dist-info/RECORD,,