lightning-sdk 0.1.43__py3-none-any.whl → 0.1.44__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 +1 -1
- lightning_sdk/api/job_api.py +35 -0
- lightning_sdk/api/utils.py +8 -0
- lightning_sdk/job/base.py +10 -0
- lightning_sdk/job/job.py +17 -4
- lightning_sdk/job/v1.py +5 -0
- lightning_sdk/job/v2.py +18 -0
- lightning_sdk/job/work.py +10 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_membership.py +27 -1
- lightning_sdk/lightning_cloud/openapi/models/v1_multi_machine_job_state.py +1 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_project_membership.py +27 -1
- lightning_sdk/mmt/base.py +10 -0
- lightning_sdk/mmt/mmt.py +16 -1
- lightning_sdk/mmt/v1.py +4 -0
- lightning_sdk/mmt/v2.py +5 -0
- lightning_sdk/plugin.py +28 -23
- {lightning_sdk-0.1.43.dist-info → lightning_sdk-0.1.44.dist-info}/METADATA +1 -1
- {lightning_sdk-0.1.43.dist-info → lightning_sdk-0.1.44.dist-info}/RECORD +22 -22
- {lightning_sdk-0.1.43.dist-info → lightning_sdk-0.1.44.dist-info}/LICENSE +0 -0
- {lightning_sdk-0.1.43.dist-info → lightning_sdk-0.1.44.dist-info}/WHEEL +0 -0
- {lightning_sdk-0.1.43.dist-info → lightning_sdk-0.1.44.dist-info}/entry_points.txt +0 -0
- {lightning_sdk-0.1.43.dist-info → lightning_sdk-0.1.44.dist-info}/top_level.txt +0 -0
lightning_sdk/__init__.py
CHANGED
lightning_sdk/api/job_api.py
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import time
|
|
2
2
|
from typing import TYPE_CHECKING, Dict, List, Optional
|
|
3
|
+
from urllib.request import urlopen
|
|
3
4
|
|
|
4
5
|
from lightning_sdk.api.utils import (
|
|
5
6
|
_COMPUTE_NAME_TO_MACHINE,
|
|
6
7
|
_MACHINE_TO_COMPUTE_NAME,
|
|
7
8
|
_create_app,
|
|
9
|
+
remove_datetime_prefix,
|
|
8
10
|
)
|
|
9
11
|
from lightning_sdk.api.utils import (
|
|
10
12
|
_get_cloud_url as _cloud_url,
|
|
@@ -16,7 +18,10 @@ from lightning_sdk.lightning_cloud.openapi import (
|
|
|
16
18
|
Externalv1Lightningwork,
|
|
17
19
|
JobsIdBody1,
|
|
18
20
|
ProjectIdJobsBody,
|
|
21
|
+
V1CloudSpace,
|
|
19
22
|
V1ComputeConfig,
|
|
23
|
+
V1DownloadJobLogsResponse,
|
|
24
|
+
V1DownloadLightningappInstanceLogsResponse,
|
|
20
25
|
V1EnvVar,
|
|
21
26
|
V1Job,
|
|
22
27
|
V1JobSpec,
|
|
@@ -102,6 +107,12 @@ class JobApiV1:
|
|
|
102
107
|
compute: str = compute_config.instance_type
|
|
103
108
|
return _COMPUTE_NAME_TO_MACHINE[compute]
|
|
104
109
|
|
|
110
|
+
def get_studio_name(self, job: Externalv1LightningappInstance) -> str:
|
|
111
|
+
cs: V1CloudSpace = self._client.cloud_space_service_get_cloud_space(
|
|
112
|
+
project_id=job.project_id, id=job.spec.cloud_space_id
|
|
113
|
+
)
|
|
114
|
+
return cs.name
|
|
115
|
+
|
|
105
116
|
def submit_job(
|
|
106
117
|
self,
|
|
107
118
|
name: str,
|
|
@@ -150,6 +161,16 @@ class JobApiV1:
|
|
|
150
161
|
|
|
151
162
|
return Status.Pending
|
|
152
163
|
|
|
164
|
+
def get_logs_finished(self, job_id: str, work_id: str, teamspace_id: str) -> str:
|
|
165
|
+
resp: (
|
|
166
|
+
V1DownloadLightningappInstanceLogsResponse
|
|
167
|
+
) = self._client.lightningapp_instance_service_download_lightningapp_instance_logs(
|
|
168
|
+
project_id=teamspace_id, id=job_id, work_id=work_id
|
|
169
|
+
)
|
|
170
|
+
|
|
171
|
+
data = urlopen(resp.url).read().decode("utf-8")
|
|
172
|
+
return remove_datetime_prefix(str(data))
|
|
173
|
+
|
|
153
174
|
|
|
154
175
|
class JobApiV2:
|
|
155
176
|
v2_job_state_pending = "pending"
|
|
@@ -247,6 +268,20 @@ class JobApiV2:
|
|
|
247
268
|
def delete_job(self, job_id: str, teamspace_id: str, cloudspace_id: Optional[str]) -> None:
|
|
248
269
|
self._client.jobs_service_delete_job(project_id=teamspace_id, id=job_id, cloudspace_id=cloudspace_id or "")
|
|
249
270
|
|
|
271
|
+
def get_logs_finished(self, job_id: str, teamspace_id: str) -> str:
|
|
272
|
+
resp: V1DownloadJobLogsResponse = self._client.jobs_service_download_job_logs(
|
|
273
|
+
project_id=teamspace_id, id=job_id
|
|
274
|
+
)
|
|
275
|
+
|
|
276
|
+
data = urlopen(resp.url).read().decode("utf-8")
|
|
277
|
+
return remove_datetime_prefix(str(data))
|
|
278
|
+
|
|
279
|
+
def get_studio_name(self, job: V1Job) -> str:
|
|
280
|
+
cs: V1CloudSpace = self._client.cloud_space_service_get_cloud_space(
|
|
281
|
+
project_id=job.project_id, id=job.spec.cloudspace_id
|
|
282
|
+
)
|
|
283
|
+
return cs.name
|
|
284
|
+
|
|
250
285
|
def _job_state_to_external(self, state: str) -> "Status":
|
|
251
286
|
from lightning_sdk.status import Status
|
|
252
287
|
|
lightning_sdk/api/utils.py
CHANGED
|
@@ -2,6 +2,7 @@ import concurrent.futures
|
|
|
2
2
|
import errno
|
|
3
3
|
import math
|
|
4
4
|
import os
|
|
5
|
+
import re
|
|
5
6
|
from concurrent.futures import ThreadPoolExecutor
|
|
6
7
|
from functools import partial
|
|
7
8
|
from pathlib import Path
|
|
@@ -599,3 +600,10 @@ def _create_app(
|
|
|
599
600
|
print(f"Create App: {resp.id=} {teamspace_id=} {studio_id=} {cloud_account=}")
|
|
600
601
|
|
|
601
602
|
return resp
|
|
603
|
+
|
|
604
|
+
|
|
605
|
+
def remove_datetime_prefix(text: str) -> str:
|
|
606
|
+
# Use a regular expression to match the datetime pattern at the start of each line
|
|
607
|
+
# lines looks something like
|
|
608
|
+
# '[2025-01-08T14:15:03.797142418Z] ⚡ ~ echo Hello\n[2025-01-08T14:15:03.803077717Z] Hello\n'
|
|
609
|
+
return re.sub(r"^\[.*?\] ", "", text, flags=re.MULTILINE)
|
lightning_sdk/job/base.py
CHANGED
|
@@ -273,6 +273,16 @@ class _BaseJob(ABC):
|
|
|
273
273
|
"""The teamspace the job is part of."""
|
|
274
274
|
return self._teamspace
|
|
275
275
|
|
|
276
|
+
@property
|
|
277
|
+
@abstractmethod
|
|
278
|
+
def logs(self) -> str:
|
|
279
|
+
"""The logs of the job."""
|
|
280
|
+
|
|
281
|
+
@property
|
|
282
|
+
def link(self) -> str:
|
|
283
|
+
"""A link to view the current job in the UI."""
|
|
284
|
+
return f"https://lightning.ai/{self.teamspace.owner.name}/{self.teamspace.name}/studios/{self._job_api.get_studio_name(self._guaranteed_job)}/app?app_id=jobs&job_name={self.name}"
|
|
285
|
+
|
|
276
286
|
@property
|
|
277
287
|
def _guaranteed_job(self) -> Any:
|
|
278
288
|
"""Guarantees that the job was fetched at some point before returning it.
|
lightning_sdk/job/job.py
CHANGED
|
@@ -5,6 +5,9 @@ from lightning_sdk.api.user_api import UserApi
|
|
|
5
5
|
from lightning_sdk.job.base import _BaseJob
|
|
6
6
|
from lightning_sdk.job.v1 import _JobV1
|
|
7
7
|
from lightning_sdk.job.v2 import _JobV2
|
|
8
|
+
from lightning_sdk.utils.resolve import _setup_logger
|
|
9
|
+
|
|
10
|
+
_logger = _setup_logger(__name__)
|
|
8
11
|
|
|
9
12
|
if TYPE_CHECKING:
|
|
10
13
|
from lightning_sdk.machine import Machine
|
|
@@ -27,6 +30,8 @@ def _has_jobs_v2() -> bool:
|
|
|
27
30
|
class Job(_BaseJob):
|
|
28
31
|
"""Class to submit and manage single-machine jobs on the Lightning AI Platform."""
|
|
29
32
|
|
|
33
|
+
_force_v1: bool = False
|
|
34
|
+
|
|
30
35
|
def __init__(
|
|
31
36
|
self,
|
|
32
37
|
name: str,
|
|
@@ -45,7 +50,7 @@ class Job(_BaseJob):
|
|
|
45
50
|
user: the name of the user owning the :param`teamspace`
|
|
46
51
|
in case it is owned directly by a user instead of an org.
|
|
47
52
|
"""
|
|
48
|
-
internal_job_cls = _JobV2 if _has_jobs_v2() else _JobV1
|
|
53
|
+
internal_job_cls = _JobV2 if _has_jobs_v2() and not self._force_v1 else _JobV1
|
|
49
54
|
|
|
50
55
|
self._internal_job = internal_job_cls(
|
|
51
56
|
name=name,
|
|
@@ -127,6 +132,8 @@ class Job(_BaseJob):
|
|
|
127
132
|
)
|
|
128
133
|
# required for typing with "Job"
|
|
129
134
|
assert isinstance(ret_val, cls)
|
|
135
|
+
|
|
136
|
+
_logger.info(f"Job was successfully launched. View it at {ret_val.link}")
|
|
130
137
|
return ret_val
|
|
131
138
|
|
|
132
139
|
def _submit(
|
|
@@ -239,9 +246,11 @@ class Job(_BaseJob):
|
|
|
239
246
|
return self._internal_job._teamspace
|
|
240
247
|
|
|
241
248
|
@property
|
|
242
|
-
def
|
|
243
|
-
"""The
|
|
244
|
-
|
|
249
|
+
def logs(self) -> str:
|
|
250
|
+
"""The logs of the job."""
|
|
251
|
+
if self.status not in (Status.Failed, Status.Completed, Status.Stopped):
|
|
252
|
+
raise RuntimeError("Getting jobs logs while the job is pending or running is not supported yet!")
|
|
253
|
+
return self._internal_job.logs
|
|
245
254
|
|
|
246
255
|
def __getattr__(self, key: str) -> Any:
|
|
247
256
|
"""Forward the attribute lookup to the internal job implementation."""
|
|
@@ -249,3 +258,7 @@ class Job(_BaseJob):
|
|
|
249
258
|
return getattr(super(), key)
|
|
250
259
|
except AttributeError:
|
|
251
260
|
return getattr(self._internal_job, key)
|
|
261
|
+
|
|
262
|
+
@property
|
|
263
|
+
def link(self) -> str:
|
|
264
|
+
return self._internal_job.link
|
lightning_sdk/job/v1.py
CHANGED
|
@@ -210,6 +210,11 @@ class _JobV1(_BaseJob):
|
|
|
210
210
|
"""The path to the share of the job in the distributed teamspace filesystem."""
|
|
211
211
|
return f"/teamspace/jobs/{self.name}/share"
|
|
212
212
|
|
|
213
|
+
@property
|
|
214
|
+
def logs(self) -> str:
|
|
215
|
+
"""The logs of the job."""
|
|
216
|
+
return self.work.logs
|
|
217
|
+
|
|
213
218
|
# the following and functions are solely to make the Work class function
|
|
214
219
|
@property
|
|
215
220
|
def _id(self) -> str:
|
lightning_sdk/job/v2.py
CHANGED
|
@@ -167,6 +167,24 @@ class _JobV2(_BaseJob):
|
|
|
167
167
|
"""The path to the share of the job within the distributed teamspace filesystem."""
|
|
168
168
|
raise NotImplementedError("Not implemented yet")
|
|
169
169
|
|
|
170
|
+
@property
|
|
171
|
+
def logs(self) -> str:
|
|
172
|
+
from lightning_sdk.status import Status
|
|
173
|
+
|
|
174
|
+
if self.status not in (Status.Failed, Status.Completed, Status.Stopped):
|
|
175
|
+
raise RuntimeError("Getting jobs logs while the job is pending or running is not supported yet!")
|
|
176
|
+
|
|
177
|
+
return self._job_api.get_logs_finished(job_id=self._guaranteed_job.id, teamspace_id=self.teamspace.id)
|
|
178
|
+
|
|
179
|
+
@property
|
|
180
|
+
def link(self) -> str:
|
|
181
|
+
if self._guaranteed_job.spec.image:
|
|
182
|
+
return (
|
|
183
|
+
f"https://lightning.ai/{self.teamspace.owner.name}/{self.teamspace.name}/jobs/{self.name}?app_id=jobs"
|
|
184
|
+
)
|
|
185
|
+
|
|
186
|
+
return super().link
|
|
187
|
+
|
|
170
188
|
def _update_internal_job(self) -> None:
|
|
171
189
|
if getattr(self, "_job", None) is None:
|
|
172
190
|
self._job = self._job_api.get_job_by_name(name=self._name, teamspace_id=self._teamspace.id)
|
lightning_sdk/job/work.py
CHANGED
|
@@ -60,3 +60,13 @@ class Work:
|
|
|
60
60
|
@property
|
|
61
61
|
def status(self) -> "Status":
|
|
62
62
|
return self._job_api.get_status_from_work(self._latest_work)
|
|
63
|
+
|
|
64
|
+
@property
|
|
65
|
+
def logs(self) -> str:
|
|
66
|
+
"""The logs of the work."""
|
|
67
|
+
from lightning_sdk.status import Status
|
|
68
|
+
|
|
69
|
+
if self.status not in (Status.Failed, Status.Completed, Status.Stopped):
|
|
70
|
+
raise RuntimeError("Getting jobs logs while the job is pending or running is not supported yet!")
|
|
71
|
+
|
|
72
|
+
return self._job_api.get_logs_finished(job_id=self._job._id, work_id=self._id, teamspace_id=self._teamspace.id)
|
|
@@ -52,6 +52,7 @@ class V1Membership(object):
|
|
|
52
52
|
'job_count': 'str',
|
|
53
53
|
'membership_count': 'str',
|
|
54
54
|
'name': 'str',
|
|
55
|
+
'next_free_credits_grant_at': 'datetime',
|
|
55
56
|
'owner_id': 'str',
|
|
56
57
|
'owner_type': 'V1OwnerType',
|
|
57
58
|
'project_id': 'str',
|
|
@@ -73,6 +74,7 @@ class V1Membership(object):
|
|
|
73
74
|
'job_count': 'jobCount',
|
|
74
75
|
'membership_count': 'membershipCount',
|
|
75
76
|
'name': 'name',
|
|
77
|
+
'next_free_credits_grant_at': 'nextFreeCreditsGrantAt',
|
|
76
78
|
'owner_id': 'ownerId',
|
|
77
79
|
'owner_type': 'ownerType',
|
|
78
80
|
'project_id': 'projectId',
|
|
@@ -82,7 +84,7 @@ class V1Membership(object):
|
|
|
82
84
|
'user_id': 'userId'
|
|
83
85
|
}
|
|
84
86
|
|
|
85
|
-
def __init__(self, balance: 'float' =None, created_at: 'datetime' =None, creator_id: 'str' =None, datastore_count: 'str' =None, description: 'str' =None, display_name: 'str' =None, free_credits_enabled: 'bool' =None, is_default: 'bool' =None, job_count: 'str' =None, membership_count: 'str' =None, name: 'str' =None, owner_id: 'str' =None, owner_type: 'V1OwnerType' =None, project_id: 'str' =None, quotas: 'V1Quotas' =None, roles: 'list[V1Role]' =None, updated_at: 'datetime' =None, user_id: 'str' =None): # noqa: E501
|
|
87
|
+
def __init__(self, balance: 'float' =None, created_at: 'datetime' =None, creator_id: 'str' =None, datastore_count: 'str' =None, description: 'str' =None, display_name: 'str' =None, free_credits_enabled: 'bool' =None, is_default: 'bool' =None, job_count: 'str' =None, membership_count: 'str' =None, name: 'str' =None, next_free_credits_grant_at: 'datetime' =None, owner_id: 'str' =None, owner_type: 'V1OwnerType' =None, project_id: 'str' =None, quotas: 'V1Quotas' =None, roles: 'list[V1Role]' =None, updated_at: 'datetime' =None, user_id: 'str' =None): # noqa: E501
|
|
86
88
|
"""V1Membership - a model defined in Swagger""" # noqa: E501
|
|
87
89
|
self._balance = None
|
|
88
90
|
self._created_at = None
|
|
@@ -95,6 +97,7 @@ class V1Membership(object):
|
|
|
95
97
|
self._job_count = None
|
|
96
98
|
self._membership_count = None
|
|
97
99
|
self._name = None
|
|
100
|
+
self._next_free_credits_grant_at = None
|
|
98
101
|
self._owner_id = None
|
|
99
102
|
self._owner_type = None
|
|
100
103
|
self._project_id = None
|
|
@@ -125,6 +128,8 @@ class V1Membership(object):
|
|
|
125
128
|
self.membership_count = membership_count
|
|
126
129
|
if name is not None:
|
|
127
130
|
self.name = name
|
|
131
|
+
if next_free_credits_grant_at is not None:
|
|
132
|
+
self.next_free_credits_grant_at = next_free_credits_grant_at
|
|
128
133
|
if owner_id is not None:
|
|
129
134
|
self.owner_id = owner_id
|
|
130
135
|
if owner_type is not None:
|
|
@@ -371,6 +376,27 @@ class V1Membership(object):
|
|
|
371
376
|
|
|
372
377
|
self._name = name
|
|
373
378
|
|
|
379
|
+
@property
|
|
380
|
+
def next_free_credits_grant_at(self) -> 'datetime':
|
|
381
|
+
"""Gets the next_free_credits_grant_at of this V1Membership. # noqa: E501
|
|
382
|
+
|
|
383
|
+
|
|
384
|
+
:return: The next_free_credits_grant_at of this V1Membership. # noqa: E501
|
|
385
|
+
:rtype: datetime
|
|
386
|
+
"""
|
|
387
|
+
return self._next_free_credits_grant_at
|
|
388
|
+
|
|
389
|
+
@next_free_credits_grant_at.setter
|
|
390
|
+
def next_free_credits_grant_at(self, next_free_credits_grant_at: 'datetime'):
|
|
391
|
+
"""Sets the next_free_credits_grant_at of this V1Membership.
|
|
392
|
+
|
|
393
|
+
|
|
394
|
+
:param next_free_credits_grant_at: The next_free_credits_grant_at of this V1Membership. # noqa: E501
|
|
395
|
+
:type: datetime
|
|
396
|
+
"""
|
|
397
|
+
|
|
398
|
+
self._next_free_credits_grant_at = next_free_credits_grant_at
|
|
399
|
+
|
|
374
400
|
@property
|
|
375
401
|
def owner_id(self) -> 'str':
|
|
376
402
|
"""Gets the owner_id of this V1Membership. # noqa: E501
|
|
@@ -38,6 +38,7 @@ class V1MultiMachineJobState(object):
|
|
|
38
38
|
allowed enum values
|
|
39
39
|
"""
|
|
40
40
|
UNSPECIFIED = "MultiMachineJob_STATE_UNSPECIFIED"
|
|
41
|
+
PENDING = "MultiMachineJob_STATE_PENDING"
|
|
41
42
|
RUNNING = "MultiMachineJob_STATE_RUNNING"
|
|
42
43
|
STOPPED = "MultiMachineJob_STATE_STOPPED"
|
|
43
44
|
DELETED = "MultiMachineJob_STATE_DELETED"
|
|
@@ -58,6 +58,7 @@ class V1ProjectMembership(object):
|
|
|
58
58
|
'last_name': 'str',
|
|
59
59
|
'membership_count': 'str',
|
|
60
60
|
'name': 'str',
|
|
61
|
+
'next_free_credits_grant_at': 'datetime',
|
|
61
62
|
'organization': 'str',
|
|
62
63
|
'owner_id': 'str',
|
|
63
64
|
'owner_type': 'V1OwnerType',
|
|
@@ -87,6 +88,7 @@ class V1ProjectMembership(object):
|
|
|
87
88
|
'last_name': 'lastName',
|
|
88
89
|
'membership_count': 'membershipCount',
|
|
89
90
|
'name': 'name',
|
|
91
|
+
'next_free_credits_grant_at': 'nextFreeCreditsGrantAt',
|
|
90
92
|
'organization': 'organization',
|
|
91
93
|
'owner_id': 'ownerId',
|
|
92
94
|
'owner_type': 'ownerType',
|
|
@@ -98,7 +100,7 @@ class V1ProjectMembership(object):
|
|
|
98
100
|
'username': 'username'
|
|
99
101
|
}
|
|
100
102
|
|
|
101
|
-
def __init__(self, avatar_url: 'str' =None, balance: 'float' =None, created_at: 'datetime' =None, creator_id: 'str' =None, datastore_count: 'str' =None, description: 'str' =None, display_name: 'str' =None, email: 'str' =None, first_name: 'str' =None, free_credits_enabled: 'bool' =None, inactive: 'bool' =None, is_default: 'bool' =None, job_count: 'str' =None, job_title: 'str' =None, last_name: 'str' =None, membership_count: 'str' =None, name: 'str' =None, organization: 'str' =None, owner_id: 'str' =None, owner_type: 'V1OwnerType' =None, project_id: 'str' =None, quotas: 'V1Quotas' =None, roles: 'list[V1Role]' =None, updated_at: 'datetime' =None, user_id: 'str' =None, username: 'str' =None): # noqa: E501
|
|
103
|
+
def __init__(self, avatar_url: 'str' =None, balance: 'float' =None, created_at: 'datetime' =None, creator_id: 'str' =None, datastore_count: 'str' =None, description: 'str' =None, display_name: 'str' =None, email: 'str' =None, first_name: 'str' =None, free_credits_enabled: 'bool' =None, inactive: 'bool' =None, is_default: 'bool' =None, job_count: 'str' =None, job_title: 'str' =None, last_name: 'str' =None, membership_count: 'str' =None, name: 'str' =None, next_free_credits_grant_at: 'datetime' =None, organization: 'str' =None, owner_id: 'str' =None, owner_type: 'V1OwnerType' =None, project_id: 'str' =None, quotas: 'V1Quotas' =None, roles: 'list[V1Role]' =None, updated_at: 'datetime' =None, user_id: 'str' =None, username: 'str' =None): # noqa: E501
|
|
102
104
|
"""V1ProjectMembership - a model defined in Swagger""" # noqa: E501
|
|
103
105
|
self._avatar_url = None
|
|
104
106
|
self._balance = None
|
|
@@ -117,6 +119,7 @@ class V1ProjectMembership(object):
|
|
|
117
119
|
self._last_name = None
|
|
118
120
|
self._membership_count = None
|
|
119
121
|
self._name = None
|
|
122
|
+
self._next_free_credits_grant_at = None
|
|
120
123
|
self._organization = None
|
|
121
124
|
self._owner_id = None
|
|
122
125
|
self._owner_type = None
|
|
@@ -161,6 +164,8 @@ class V1ProjectMembership(object):
|
|
|
161
164
|
self.membership_count = membership_count
|
|
162
165
|
if name is not None:
|
|
163
166
|
self.name = name
|
|
167
|
+
if next_free_credits_grant_at is not None:
|
|
168
|
+
self.next_free_credits_grant_at = next_free_credits_grant_at
|
|
164
169
|
if organization is not None:
|
|
165
170
|
self.organization = organization
|
|
166
171
|
if owner_id is not None:
|
|
@@ -537,6 +542,27 @@ class V1ProjectMembership(object):
|
|
|
537
542
|
|
|
538
543
|
self._name = name
|
|
539
544
|
|
|
545
|
+
@property
|
|
546
|
+
def next_free_credits_grant_at(self) -> 'datetime':
|
|
547
|
+
"""Gets the next_free_credits_grant_at of this V1ProjectMembership. # noqa: E501
|
|
548
|
+
|
|
549
|
+
|
|
550
|
+
:return: The next_free_credits_grant_at of this V1ProjectMembership. # noqa: E501
|
|
551
|
+
:rtype: datetime
|
|
552
|
+
"""
|
|
553
|
+
return self._next_free_credits_grant_at
|
|
554
|
+
|
|
555
|
+
@next_free_credits_grant_at.setter
|
|
556
|
+
def next_free_credits_grant_at(self, next_free_credits_grant_at: 'datetime'):
|
|
557
|
+
"""Sets the next_free_credits_grant_at of this V1ProjectMembership.
|
|
558
|
+
|
|
559
|
+
|
|
560
|
+
:param next_free_credits_grant_at: The next_free_credits_grant_at of this V1ProjectMembership. # noqa: E501
|
|
561
|
+
:type: datetime
|
|
562
|
+
"""
|
|
563
|
+
|
|
564
|
+
self._next_free_credits_grant_at = next_free_credits_grant_at
|
|
565
|
+
|
|
540
566
|
@property
|
|
541
567
|
def organization(self) -> 'str':
|
|
542
568
|
"""Gets the organization of this V1ProjectMembership. # noqa: E501
|
lightning_sdk/mmt/base.py
CHANGED
|
@@ -36,6 +36,11 @@ class MMTMachine(Protocol):
|
|
|
36
36
|
"""The status of this job."""
|
|
37
37
|
...
|
|
38
38
|
|
|
39
|
+
@property
|
|
40
|
+
def logs(self) -> str:
|
|
41
|
+
"""The logs of the given machine."""
|
|
42
|
+
...
|
|
43
|
+
|
|
39
44
|
|
|
40
45
|
class _BaseMMT(_BaseJob):
|
|
41
46
|
"""Base interface to all job types."""
|
|
@@ -273,6 +278,11 @@ class _BaseMMT(_BaseJob):
|
|
|
273
278
|
"""The teamspace the job is part of."""
|
|
274
279
|
return self._teamspace
|
|
275
280
|
|
|
281
|
+
@property
|
|
282
|
+
def logs(self) -> str:
|
|
283
|
+
"""Logs of the rank 0 machine."""
|
|
284
|
+
return self.machines[0].logs
|
|
285
|
+
|
|
276
286
|
@abstractmethod
|
|
277
287
|
def _update_internal_job(self) -> None:
|
|
278
288
|
pass
|
lightning_sdk/mmt/mmt.py
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
from contextlib import suppress
|
|
1
2
|
from functools import lru_cache
|
|
2
3
|
from typing import TYPE_CHECKING, Any, Dict, Optional, Tuple, Union
|
|
3
4
|
|
|
@@ -6,6 +7,7 @@ from lightning_sdk.job.job import _has_jobs_v2
|
|
|
6
7
|
from lightning_sdk.mmt.base import MMTMachine, _BaseMMT
|
|
7
8
|
from lightning_sdk.mmt.v1 import _MMTV1
|
|
8
9
|
from lightning_sdk.mmt.v2 import _MMTV2
|
|
10
|
+
from lightning_sdk.utils.resolve import _setup_logger
|
|
9
11
|
|
|
10
12
|
if TYPE_CHECKING:
|
|
11
13
|
from lightning_sdk.machine import Machine
|
|
@@ -15,6 +17,8 @@ if TYPE_CHECKING:
|
|
|
15
17
|
from lightning_sdk.teamspace import Teamspace
|
|
16
18
|
from lightning_sdk.user import User
|
|
17
19
|
|
|
20
|
+
_logger = _setup_logger(__name__)
|
|
21
|
+
|
|
18
22
|
|
|
19
23
|
@lru_cache(maxsize=None)
|
|
20
24
|
def _has_mmt_v2() -> bool:
|
|
@@ -137,8 +141,15 @@ class MMT(_BaseMMT):
|
|
|
137
141
|
artifacts_remote=artifacts_remote,
|
|
138
142
|
cluster=cluster, # deprecated in favor of cloud_account
|
|
139
143
|
)
|
|
140
|
-
# required for typing with "
|
|
144
|
+
# required for typing with "MMT"
|
|
141
145
|
assert isinstance(ret_val, cls)
|
|
146
|
+
|
|
147
|
+
msg = "Multi-Machine Job was successfully launched."
|
|
148
|
+
|
|
149
|
+
with suppress(NotImplementedError):
|
|
150
|
+
msg += f" View it at {ret_val.link}"
|
|
151
|
+
|
|
152
|
+
_logger.info(msg)
|
|
142
153
|
return ret_val
|
|
143
154
|
|
|
144
155
|
def _submit(
|
|
@@ -255,6 +266,10 @@ class MMT(_BaseMMT):
|
|
|
255
266
|
"""The teamspace the job is part of."""
|
|
256
267
|
return self._internal_mmt._teamspace
|
|
257
268
|
|
|
269
|
+
@property
|
|
270
|
+
def link(self) -> str:
|
|
271
|
+
return self._internal_mmt.link
|
|
272
|
+
|
|
258
273
|
def __getattr__(self, key: str) -> Any:
|
|
259
274
|
"""Forward the attribute lookup to the internal job implementation."""
|
|
260
275
|
try:
|
lightning_sdk/mmt/v1.py
CHANGED
|
@@ -172,6 +172,10 @@ class _MMTV1(_BaseMMT):
|
|
|
172
172
|
"""The teamspace the job is part of."""
|
|
173
173
|
return self._teamspace
|
|
174
174
|
|
|
175
|
+
@property
|
|
176
|
+
def link(self) -> str:
|
|
177
|
+
return f"https://lightning.ai/{self.teamspace.owner.name}/{self.teamspace.name}/studios/{self._job_api.get_studio_name(self._guaranteed_job)}/app?app_id=mmt&app_tab=Runs&job_name={self.name}"
|
|
178
|
+
|
|
175
179
|
# the following and functions are solely to make the Work class function
|
|
176
180
|
@property
|
|
177
181
|
def _id(self) -> str:
|
lightning_sdk/mmt/v2.py
CHANGED
|
@@ -186,3 +186,8 @@ class _MMTV2(_BaseMMT):
|
|
|
186
186
|
def teamspace(self) -> "Teamspace":
|
|
187
187
|
"""The teamspace the job is part of."""
|
|
188
188
|
return self._teamspace
|
|
189
|
+
|
|
190
|
+
@property
|
|
191
|
+
def link(self) -> str:
|
|
192
|
+
# TODO: Since we don't have a UI for this yet, we can't have a link
|
|
193
|
+
raise NotImplementedError
|
lightning_sdk/plugin.py
CHANGED
|
@@ -3,7 +3,8 @@ import logging
|
|
|
3
3
|
import os
|
|
4
4
|
import warnings
|
|
5
5
|
from abc import ABC, abstractmethod
|
|
6
|
-
from
|
|
6
|
+
from contextlib import contextmanager
|
|
7
|
+
from typing import TYPE_CHECKING, Any, Generator, Optional, Protocol, Union, runtime_checkable
|
|
7
8
|
|
|
8
9
|
from lightning_sdk.job import Job
|
|
9
10
|
from lightning_sdk.machine import Machine
|
|
@@ -16,6 +17,7 @@ from lightning_sdk.utils.resolve import (
|
|
|
16
17
|
|
|
17
18
|
if TYPE_CHECKING:
|
|
18
19
|
from lightning_sdk.lightning_cloud.openapi import Externalv1LightningappInstance
|
|
20
|
+
from lightning_sdk.mmt import MMT
|
|
19
21
|
|
|
20
22
|
_logger = _setup_logger(__name__)
|
|
21
23
|
|
|
@@ -141,7 +143,7 @@ class JobsPlugin(_Plugin):
|
|
|
141
143
|
|
|
142
144
|
machine = _resolve_deprecated_cloud_compute(machine, cloud_compute)
|
|
143
145
|
|
|
144
|
-
|
|
146
|
+
return Job.run(
|
|
145
147
|
name=name,
|
|
146
148
|
machine=machine,
|
|
147
149
|
command=command,
|
|
@@ -151,10 +153,6 @@ class JobsPlugin(_Plugin):
|
|
|
151
153
|
interruptible=interruptible,
|
|
152
154
|
)
|
|
153
155
|
|
|
154
|
-
_logger.info(_success_message(job, self))
|
|
155
|
-
|
|
156
|
-
return job
|
|
157
|
-
|
|
158
156
|
|
|
159
157
|
class MultiMachineTrainingPlugin(_Plugin):
|
|
160
158
|
"""Plugin handling multi-machine-training jobs."""
|
|
@@ -170,7 +168,7 @@ class MultiMachineTrainingPlugin(_Plugin):
|
|
|
170
168
|
cloud_compute: Optional[Machine] = None,
|
|
171
169
|
num_instances: int = 2,
|
|
172
170
|
interruptible: bool = False,
|
|
173
|
-
) ->
|
|
171
|
+
) -> "MMT":
|
|
174
172
|
"""Launches an asynchronous multi-machine-training.
|
|
175
173
|
|
|
176
174
|
Args:
|
|
@@ -188,20 +186,16 @@ class MultiMachineTrainingPlugin(_Plugin):
|
|
|
188
186
|
|
|
189
187
|
machine = _resolve_deprecated_cloud_compute(machine, cloud_compute)
|
|
190
188
|
|
|
191
|
-
MMT
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
)
|
|
202
|
-
|
|
203
|
-
MMT._force_v1 = False
|
|
204
|
-
return mmt
|
|
189
|
+
with forced_v1(MMT) as v1mmt:
|
|
190
|
+
return v1mmt.run(
|
|
191
|
+
name=name,
|
|
192
|
+
num_machines=num_instances,
|
|
193
|
+
machine=machine,
|
|
194
|
+
command=command,
|
|
195
|
+
studio=self._studio,
|
|
196
|
+
teamspace=self._studio.teamspace,
|
|
197
|
+
interruptible=interruptible,
|
|
198
|
+
)
|
|
205
199
|
|
|
206
200
|
|
|
207
201
|
class MultiMachineDataPrepPlugin(_Plugin):
|
|
@@ -245,7 +239,8 @@ class MultiMachineDataPrepPlugin(_Plugin):
|
|
|
245
239
|
interruptible=interruptible,
|
|
246
240
|
)
|
|
247
241
|
|
|
248
|
-
|
|
242
|
+
with forced_v1(Job) as v1_job:
|
|
243
|
+
return v1_job(resp.name, self._studio.teamspace)
|
|
249
244
|
|
|
250
245
|
|
|
251
246
|
class InferenceServerPlugin(_Plugin):
|
|
@@ -293,7 +288,8 @@ class InferenceServerPlugin(_Plugin):
|
|
|
293
288
|
)
|
|
294
289
|
|
|
295
290
|
_logger.info(_success_message(resp, self))
|
|
296
|
-
|
|
291
|
+
with forced_v1(Job) as v1_job:
|
|
292
|
+
return v1_job(resp.name, self._studio.teamspace)
|
|
297
293
|
|
|
298
294
|
|
|
299
295
|
class SlurmJobsPlugin(_Plugin):
|
|
@@ -430,3 +426,12 @@ def _run_name(plugin_type: str) -> str:
|
|
|
430
426
|
def _success_message(resp: Union["Externalv1LightningappInstance", Job], plugin_instance: _RunnablePlugin) -> str:
|
|
431
427
|
"""Compiles the success message for a given runnable plugin."""
|
|
432
428
|
return f"{plugin_instance._plugin_run_name} {resp.name} was successfully launched. View it at https://lightning.ai/{plugin_instance._studio.owner.name}/{plugin_instance._studio.teamspace.name}/studios/{plugin_instance.studio}/app?app_id={plugin_instance._slug_name}&job_name={resp.name}"
|
|
429
|
+
|
|
430
|
+
|
|
431
|
+
@contextmanager
|
|
432
|
+
def forced_v1(cls: Any) -> Generator[Any, None, None]:
|
|
433
|
+
"""Forces to use the v1 version of a class when using a class with multiple backends."""
|
|
434
|
+
orig_val = getattr(cls, "_force_v1", False)
|
|
435
|
+
cls._force_v1 = True
|
|
436
|
+
yield cls
|
|
437
|
+
cls._force_v1 = orig_val
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
docs/source/conf.py,sha256=r8yX20eC-4mHhMTd0SbQb5TlSWHhO6wnJ0VJ_FBFpag,13249
|
|
2
|
-
lightning_sdk/__init__.py,sha256=
|
|
2
|
+
lightning_sdk/__init__.py,sha256=XJlg9TRR7l1VeCSLkPRsB0dOcFAU6kcMciUwmYdtojQ,925
|
|
3
3
|
lightning_sdk/agents.py,sha256=ly6Ma1j0ZgGPFyvPvMN28JWiB9dATIstFa5XM8pMi6I,1577
|
|
4
4
|
lightning_sdk/ai_hub.py,sha256=kBjtmrzVHPCgqtV_TrSNkuf4oT2DLm8SYRTz4iTQmmY,6624
|
|
5
5
|
lightning_sdk/constants.py,sha256=ztl1PTUBULnqTf3DyKUSJaV_O20hNtUYT6XvAYIrmIk,749
|
|
@@ -8,7 +8,7 @@ lightning_sdk/machine.py,sha256=VdFXStR6ilYBEYuxgGWzcAw2TtW-nEQVsh6hz-2aaEw,750
|
|
|
8
8
|
lightning_sdk/models.py,sha256=d27VAYUcbWKd4kuL_CqwCi3IguyjmKUR9EVWfXWTwmc,5606
|
|
9
9
|
lightning_sdk/organization.py,sha256=WCfzdgjtvY1_A07DnxOpp74V2JR2gQwtXbIEcFDnoVU,1232
|
|
10
10
|
lightning_sdk/owner.py,sha256=t5svD2it4C9pbSpVuG9WJL46CYi37JXNziwnXxhiU5U,1361
|
|
11
|
-
lightning_sdk/plugin.py,sha256=
|
|
11
|
+
lightning_sdk/plugin.py,sha256=nWFL1l6Q9DE8Lr2krD5qRhZljwmYm00R2eR1tYRb20s,14902
|
|
12
12
|
lightning_sdk/status.py,sha256=kLDhN4-zdsGuZM577JMl1BbUIoF61bUOadW89ZAATFA,219
|
|
13
13
|
lightning_sdk/studio.py,sha256=lezGs111RUFejLWgp4Urov5l6uiUmYJjtRK8D8EYFU8,17198
|
|
14
14
|
lightning_sdk/teamspace.py,sha256=dKT-WrYF2xGP1C1bjOY2aYlEpkrvYkz2fXvtYVgogwo,11508
|
|
@@ -17,13 +17,13 @@ lightning_sdk/api/__init__.py,sha256=Qn2VVRvir_gO7w4yxGLkZY-R3T7kdiTPKgQ57BhIA9k
|
|
|
17
17
|
lightning_sdk/api/agents_api.py,sha256=G47TbFo9kYqnBMqdw2RW-lfS1VAUBSXDmzs6fpIEMUs,4059
|
|
18
18
|
lightning_sdk/api/ai_hub_api.py,sha256=CYQLFLA89m3xQ-6Ss3UX4TDK6ZWRwmPGA5DjyJqW3RM,5578
|
|
19
19
|
lightning_sdk/api/deployment_api.py,sha256=T480Nej7LqmtkAx8SBkPGQ5JxeyQ-GVIDqUCc7Z1yfk,21448
|
|
20
|
-
lightning_sdk/api/job_api.py,sha256=
|
|
20
|
+
lightning_sdk/api/job_api.py,sha256=KgXl0uO32Ja0AvxOASh-LihUPGERq2Fwy1rovXnq5Sg,11074
|
|
21
21
|
lightning_sdk/api/mmt_api.py,sha256=texQJqSjbQNpfLLrumpvZ0MauPjmBlJAc8oSk3i46wk,6569
|
|
22
22
|
lightning_sdk/api/org_api.py,sha256=Ze3z_ATVrukobujV5YdC42DKj45Vuwl7X52q_Vr-o3U,803
|
|
23
23
|
lightning_sdk/api/studio_api.py,sha256=Cfsq8HFc4uUsj8hncnhnD_TLhw0cg-ryclGowj8S6Y0,26374
|
|
24
24
|
lightning_sdk/api/teamspace_api.py,sha256=NYhD-Br2NIIn-1Noc8Q94TzWxEwFM1qCkf9RZhOqQu0,10321
|
|
25
25
|
lightning_sdk/api/user_api.py,sha256=sL7RIjjtmZmvCZWx7BBZslhj1BeNh4Idn-RVcdmf7M0,2598
|
|
26
|
-
lightning_sdk/api/utils.py,sha256=
|
|
26
|
+
lightning_sdk/api/utils.py,sha256=GbfTdqW1yV-fjyEwVebsbAdKQQjRmwT_fXUamrcnwAY,22534
|
|
27
27
|
lightning_sdk/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
28
28
|
lightning_sdk/cli/ai_hub.py,sha256=8oy6TogDiWnHuLT3cv33XEW7vPqXPA0dDMds8kX3Z4g,1649
|
|
29
29
|
lightning_sdk/cli/download.py,sha256=nyQN3q1vZ0fg4_cfit8cKaokQ9VUd46l_TNcAQWkLwU,5996
|
|
@@ -37,11 +37,11 @@ lightning_sdk/cli/upload.py,sha256=H9OyipYTYAQ9Mzy2e8jtoaa-B34-uXHbTQTzY2Vmhv4,9
|
|
|
37
37
|
lightning_sdk/deployment/__init__.py,sha256=BLu7_cVLp97TYxe6qe-J1zKUSZXAVcvCjgcA7plV2k4,497
|
|
38
38
|
lightning_sdk/deployment/deployment.py,sha256=Dp15pn8rFAfMfaDhKn0v3bphFuvLgkPFs3KSNxW6eyc,15472
|
|
39
39
|
lightning_sdk/job/__init__.py,sha256=1MxjQ6rHkyUHCypSW9RuXuVMVH11WiqhIXcU2LCFMwE,64
|
|
40
|
-
lightning_sdk/job/base.py,sha256=
|
|
41
|
-
lightning_sdk/job/job.py,sha256=
|
|
42
|
-
lightning_sdk/job/v1.py,sha256=
|
|
43
|
-
lightning_sdk/job/v2.py,sha256=
|
|
44
|
-
lightning_sdk/job/work.py,sha256=
|
|
40
|
+
lightning_sdk/job/base.py,sha256=WHd2jz1qEeQWg2ljphlJMwoEVU6qtSBjnO9hMScLF7E,13383
|
|
41
|
+
lightning_sdk/job/job.py,sha256=8Bch1TCKjf4jxf46tVN64_k_ZIq677kblHLJHQJO8v4,11536
|
|
42
|
+
lightning_sdk/job/v1.py,sha256=Ff1iTvZqa1J90eIex6_xDjwAxJztHtUSTmjihFwq5Vg,9060
|
|
43
|
+
lightning_sdk/job/v2.py,sha256=mLEgSbog3QiLKsk1-9pWNWA_yYuQzvNfkWt8Mt2Y598,8720
|
|
44
|
+
lightning_sdk/job/work.py,sha256=_L1eF9L0dW_BI17Wo0HwgoOkwwd48vFkqBD0uOt_rJk,2043
|
|
45
45
|
lightning_sdk/lightning_cloud/__init__.py,sha256=o91SMAlwr4Ke5ESe8fHjqXcj31_h7rT-MlFoXA-n2EI,173
|
|
46
46
|
lightning_sdk/lightning_cloud/__version__.py,sha256=lOfmWHtjmiuSG28TbKQqd2B3nwmSGOlKVFwhaj_cRJk,23
|
|
47
47
|
lightning_sdk/lightning_cloud/env.py,sha256=XZXpF4sD9jlB8DY0herTy_8XiUJuDVjxy5APjRD2_aU,1379
|
|
@@ -632,7 +632,7 @@ lightning_sdk/lightning_cloud/openapi/models/v1_magic_link_login_response.py,sha
|
|
|
632
632
|
lightning_sdk/lightning_cloud/openapi/models/v1_managed_endpoint.py,sha256=T0IXmXRI5paAN6NxpQQ8873lgTT7bIHYZZmeJEmW4yA,10175
|
|
633
633
|
lightning_sdk/lightning_cloud/openapi/models/v1_managed_model.py,sha256=97KxjHxTsaLWYlTNQeE2yGhF7KbTbmqLb8c39BEy02s,9117
|
|
634
634
|
lightning_sdk/lightning_cloud/openapi/models/v1_managed_model_abilities.py,sha256=1of-AEIimGnUd_0fpS5U8apGFYdsIXogRpFGxed67s0,5892
|
|
635
|
-
lightning_sdk/lightning_cloud/openapi/models/v1_membership.py,sha256=
|
|
635
|
+
lightning_sdk/lightning_cloud/openapi/models/v1_membership.py,sha256=6wqHKmxv3SOj9mTTRAw2g3ljxQyg_HKU18rexmA1KII,17207
|
|
636
636
|
lightning_sdk/lightning_cloud/openapi/models/v1_message.py,sha256=6E1FDyfNM8fMkJi6FZ4U9UBk4k5VhfmCYOHGkc5CyzA,10189
|
|
637
637
|
lightning_sdk/lightning_cloud/openapi/models/v1_message_author.py,sha256=QRC1HofufQOPROrxwtLeaEfE8f1h_ehZ0tdqlYfkgyM,3591
|
|
638
638
|
lightning_sdk/lightning_cloud/openapi/models/v1_message_content.py,sha256=rlYtO8Llal6jISWpQMyOC8zMOvdVWaljXTwlHp_gzdc,4535
|
|
@@ -652,7 +652,7 @@ lightning_sdk/lightning_cloud/openapi/models/v1_multi_machine_job_event.py,sha25
|
|
|
652
652
|
lightning_sdk/lightning_cloud/openapi/models/v1_multi_machine_job_event_type.py,sha256=HMBQuVSxwwbhbDQAAAMF8k99drvllwifjwjqEQrrDaQ,3248
|
|
653
653
|
lightning_sdk/lightning_cloud/openapi/models/v1_multi_machine_job_fault_tolerance.py,sha256=5Q0mZ3FM6yRi81mVCnYcyYh84loK4LVZTIv-2GgAy1I,4863
|
|
654
654
|
lightning_sdk/lightning_cloud/openapi/models/v1_multi_machine_job_fault_tolerance_strategy.py,sha256=FQ8qqDLfpguNtMqEETybXre4IArM32_vFuLrrUOcHb4,3539
|
|
655
|
-
lightning_sdk/lightning_cloud/openapi/models/v1_multi_machine_job_state.py,sha256=
|
|
655
|
+
lightning_sdk/lightning_cloud/openapi/models/v1_multi_machine_job_state.py,sha256=xNpq6pM1UF9r0hPHoEQ124SlCW2sCb_zW628kEa7IVU,3395
|
|
656
656
|
lightning_sdk/lightning_cloud/openapi/models/v1_multi_machine_job_status.py,sha256=yoOMJoszmdfEoUP7mzjl3PTK9dq6JUi8yXrxJljrY-0,9540
|
|
657
657
|
lightning_sdk/lightning_cloud/openapi/models/v1_named_get_logger_metrics.py,sha256=VygKKjSPGIbWT9RxbmJfOSlNR-Fq12yKj8wT_SHd2ZQ,3966
|
|
658
658
|
lightning_sdk/lightning_cloud/openapi/models/v1_network_config.py,sha256=bHDZVIsqgiSi7eBf72RunvrLR-d-4b9S7oDMAZFBvCM,5476
|
|
@@ -682,7 +682,7 @@ lightning_sdk/lightning_cloud/openapi/models/v1_project_artifact.py,sha256=jMg7B
|
|
|
682
682
|
lightning_sdk/lightning_cloud/openapi/models/v1_project_cluster_binding.py,sha256=KLZYf_bkkB1OJenDpZsG02BvomPQqJSP3gMf3ofJ83k,8719
|
|
683
683
|
lightning_sdk/lightning_cloud/openapi/models/v1_project_compute_daily_usage.py,sha256=92qqkHCx9gfZCg7FGVn7TDMQjuHw5E0POtLC7HoQ9pE,6565
|
|
684
684
|
lightning_sdk/lightning_cloud/openapi/models/v1_project_compute_usage.py,sha256=-IJmDR0j5M2S7wfkwz5qO0riW2ZolAzrLnopnBAfckU,12121
|
|
685
|
-
lightning_sdk/lightning_cloud/openapi/models/v1_project_membership.py,sha256=
|
|
685
|
+
lightning_sdk/lightning_cloud/openapi/models/v1_project_membership.py,sha256=pzF0Jm8gNDV1-TerXtPWf1xNM2pRgJnCtDtKNRWcb8o,23595
|
|
686
686
|
lightning_sdk/lightning_cloud/openapi/models/v1_project_membership_invite.py,sha256=V9Djs6edeaKv-X2-GpfAU-EVnx2rlKppGSTLfKzfrP0,9310
|
|
687
687
|
lightning_sdk/lightning_cloud/openapi/models/v1_project_membership_role_binding.py,sha256=pS5454riAOUNeB7B3Y8ChEj9RJQYaroelZuJQs8w2yM,7727
|
|
688
688
|
lightning_sdk/lightning_cloud/openapi/models/v1_project_settings.py,sha256=OugDsaWQPBMBGx4MykBJZO-xacRzzVMV3uGbeyLtQi0,5977
|
|
@@ -834,10 +834,10 @@ lightning_sdk/lightning_cloud/utils/dataset.py,sha256=4nUspe8iAaRPgSYpXA2uAQCgyd
|
|
|
834
834
|
lightning_sdk/lightning_cloud/utils/name_generator.py,sha256=MkciuA10332V0mcE2PxLIiwWomWE0Fm_gNGK01vwRr4,58046
|
|
835
835
|
lightning_sdk/lightning_cloud/utils/network.py,sha256=axPgl8rhyPcPjxiztDxyksfxax3VNg2OXL5F5Uc81b4,406
|
|
836
836
|
lightning_sdk/mmt/__init__.py,sha256=ExMu90-96bGBnyp5h0CErQszUGB1-PcjC4-R8_NYbeY,117
|
|
837
|
-
lightning_sdk/mmt/base.py,sha256=
|
|
838
|
-
lightning_sdk/mmt/mmt.py,sha256=
|
|
839
|
-
lightning_sdk/mmt/v1.py,sha256=
|
|
840
|
-
lightning_sdk/mmt/v2.py,sha256=
|
|
837
|
+
lightning_sdk/mmt/base.py,sha256=V_ysuSjddXksCjkpGy-YVqD9j8b0jA6hkfFz0oW-Jn0,12768
|
|
838
|
+
lightning_sdk/mmt/mmt.py,sha256=Br73TO7TrEdx7VH80CA_gCGDgz3JX4p16R9DdrwQshk,12307
|
|
839
|
+
lightning_sdk/mmt/v1.py,sha256=Ovzwc-mm3PCsyVb8XfvbWUSFGZEI8E5NKayQB1pXvwg,8159
|
|
840
|
+
lightning_sdk/mmt/v2.py,sha256=mUHnBN33UOfD7LX5akGShG7W1q5vGASkVaOTPhHhpDI,8353
|
|
841
841
|
lightning_sdk/services/__init__.py,sha256=gSWUjccEhMI9CIWL_nbrFHUK2S6TM2725mEzrLMfK1Y,225
|
|
842
842
|
lightning_sdk/services/file_endpoint.py,sha256=we5HC_o74J4Y6fSP_31jIizi_I_1FO_Rb2qblspD9eE,7855
|
|
843
843
|
lightning_sdk/services/utilities.py,sha256=IeOx8hc3F8ZevHeKBysh08BXhJliTNzvKp1gwpEfdik,4087
|
|
@@ -846,9 +846,9 @@ lightning_sdk/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSu
|
|
|
846
846
|
lightning_sdk/utils/dynamic.py,sha256=glUTO1JC9APtQ6Gr9SO02a3zr56-sPAXM5C3NrTpgyQ,1959
|
|
847
847
|
lightning_sdk/utils/enum.py,sha256=h2JRzqoBcSlUdanFHmkj_j5DleBHAu1esQYUsdNI-hU,4106
|
|
848
848
|
lightning_sdk/utils/resolve.py,sha256=RWvlOWLHjaHhR0W0zT3mN719cbzhFfYCKBss38zfv3k,5783
|
|
849
|
-
lightning_sdk-0.1.
|
|
850
|
-
lightning_sdk-0.1.
|
|
851
|
-
lightning_sdk-0.1.
|
|
852
|
-
lightning_sdk-0.1.
|
|
853
|
-
lightning_sdk-0.1.
|
|
854
|
-
lightning_sdk-0.1.
|
|
849
|
+
lightning_sdk-0.1.44.dist-info/LICENSE,sha256=uFIuZwj5z-4TeF2UuacPZ1o17HkvKObT8fY50qN84sg,1064
|
|
850
|
+
lightning_sdk-0.1.44.dist-info/METADATA,sha256=FpuwHfzu6vOmo_c85UKIO8Ky54Hm8l0gyUOgV84XC2Y,4031
|
|
851
|
+
lightning_sdk-0.1.44.dist-info/WHEEL,sha256=P9jw-gEje8ByB7_hXoICnHtVCrEwMQh-630tKvQWehc,91
|
|
852
|
+
lightning_sdk-0.1.44.dist-info/entry_points.txt,sha256=msB9PJWIJ784dX-OP8by51d4IbKYH3Fj1vCuA9oXjHY,68
|
|
853
|
+
lightning_sdk-0.1.44.dist-info/top_level.txt,sha256=ps8doKILFXmN7F1mHncShmnQoTxKBRPIcchC8TpoBw4,19
|
|
854
|
+
lightning_sdk-0.1.44.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|