lightning-sdk 2025.11.5__py3-none-any.whl → 2025.11.13__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/__version__.py +1 -1
- lightning_sdk/api/utils.py +58 -1
- lightning_sdk/cli/legacy/deploy/serve.py +16 -2
- lightning_sdk/cli/studio/__init__.py +2 -0
- lightning_sdk/cli/studio/cp.py +138 -0
- lightning_sdk/deployment/deployment.py +18 -4
- lightning_sdk/job/job.py +7 -1
- lightning_sdk/lit_container.py +9 -0
- lightning_sdk/machine.py +8 -0
- lightning_sdk/mmt/mmt.py +5 -1
- lightning_sdk/models.py +8 -0
- lightning_sdk/pipeline/pipeline.py +3 -0
- lightning_sdk/serve.py +3 -1
- lightning_sdk/studio.py +2 -0
- lightning_sdk/teamspace.py +15 -0
- {lightning_sdk-2025.11.5.dist-info → lightning_sdk-2025.11.13.dist-info}/METADATA +1 -1
- {lightning_sdk-2025.11.5.dist-info → lightning_sdk-2025.11.13.dist-info}/RECORD +21 -20
- {lightning_sdk-2025.11.5.dist-info → lightning_sdk-2025.11.13.dist-info}/LICENSE +0 -0
- {lightning_sdk-2025.11.5.dist-info → lightning_sdk-2025.11.13.dist-info}/WHEEL +0 -0
- {lightning_sdk-2025.11.5.dist-info → lightning_sdk-2025.11.13.dist-info}/entry_points.txt +0 -0
- {lightning_sdk-2025.11.5.dist-info → lightning_sdk-2025.11.13.dist-info}/top_level.txt +0 -0
lightning_sdk/__version__.py
CHANGED
lightning_sdk/api/utils.py
CHANGED
|
@@ -4,7 +4,8 @@ import math
|
|
|
4
4
|
import os
|
|
5
5
|
import re
|
|
6
6
|
from concurrent.futures import ThreadPoolExecutor
|
|
7
|
-
from
|
|
7
|
+
from enum import Enum
|
|
8
|
+
from functools import lru_cache, partial
|
|
8
9
|
from pathlib import Path
|
|
9
10
|
from typing import Any, Callable, Dict, List, Optional, Tuple, TypedDict, Union
|
|
10
11
|
|
|
@@ -747,3 +748,59 @@ def resolve_path_mappings(
|
|
|
747
748
|
)
|
|
748
749
|
|
|
749
750
|
return path_mappings_list
|
|
751
|
+
|
|
752
|
+
|
|
753
|
+
class AccessibleResource(Enum):
|
|
754
|
+
Studios = "studio"
|
|
755
|
+
Drive = "drive"
|
|
756
|
+
Jobs = "jobs"
|
|
757
|
+
Deployments = "deployments"
|
|
758
|
+
Pipelines = "pipelines"
|
|
759
|
+
Models = "models"
|
|
760
|
+
Containers = "containers"
|
|
761
|
+
Settings = "settings"
|
|
762
|
+
|
|
763
|
+
def __str__(self) -> str:
|
|
764
|
+
"""Return the string representation of the resource type."""
|
|
765
|
+
return self.value
|
|
766
|
+
|
|
767
|
+
def __repr__(self) -> str:
|
|
768
|
+
"""Return the string representation of the resource type."""
|
|
769
|
+
return self.value
|
|
770
|
+
|
|
771
|
+
def __eq__(self, other: object) -> bool:
|
|
772
|
+
"""Return True if the resource type is equal to the other resource type."""
|
|
773
|
+
if isinstance(other, AccessibleResource):
|
|
774
|
+
return self.value == other.value
|
|
775
|
+
return str(other) == self.value
|
|
776
|
+
|
|
777
|
+
def __hash__(self) -> int:
|
|
778
|
+
"""Return the hash of the resource type."""
|
|
779
|
+
return hash(self.value)
|
|
780
|
+
|
|
781
|
+
|
|
782
|
+
@lru_cache
|
|
783
|
+
def allowed_resource_access(resource_type: AccessibleResource, teamspace_id: str) -> bool:
|
|
784
|
+
# TODO: change this to proper API
|
|
785
|
+
from lightning_sdk.api.teamspace_api import TeamspaceApi
|
|
786
|
+
|
|
787
|
+
teamspace_api = TeamspaceApi()
|
|
788
|
+
teamspace = teamspace_api._get_teamspace_by_id(teamspace_id=teamspace_id)
|
|
789
|
+
|
|
790
|
+
# when we find the tab, check if it is enabled
|
|
791
|
+
if teamspace.layout_config:
|
|
792
|
+
for tab in teamspace.layout_config:
|
|
793
|
+
if tab.slug == resource_type:
|
|
794
|
+
return tab.is_enabled
|
|
795
|
+
|
|
796
|
+
# tab isn't found, allow access by default for backwards compatibility
|
|
797
|
+
# TODO: add additional checks here if required
|
|
798
|
+
return True
|
|
799
|
+
|
|
800
|
+
|
|
801
|
+
def raise_access_error_if_not_allowed(resource_type: AccessibleResource, teamspace_id: str) -> None:
|
|
802
|
+
if not allowed_resource_access(resource_type, teamspace_id):
|
|
803
|
+
raise PermissionError(
|
|
804
|
+
f"Access to {resource_type.name} has been disabled for this teamspace. "
|
|
805
|
+
"Contact a teamspace administrator to enable it."
|
|
806
|
+
)
|
|
@@ -12,7 +12,7 @@ from rich.console import Console
|
|
|
12
12
|
from rich.progress import Progress, SpinnerColumn, TextColumn, TimeElapsedColumn
|
|
13
13
|
from rich.prompt import Confirm
|
|
14
14
|
|
|
15
|
-
from lightning_sdk import Machine, Teamspace
|
|
15
|
+
from lightning_sdk import CloudProvider, Machine, Teamspace
|
|
16
16
|
from lightning_sdk.api.lit_container_api import LitContainerApi
|
|
17
17
|
from lightning_sdk.api.utils import _get_registry_url
|
|
18
18
|
from lightning_sdk.cli.legacy.clusters_menu import _ClustersMenu
|
|
@@ -122,6 +122,12 @@ def deploy() -> None:
|
|
|
122
122
|
"If not provided will fall back to the teamspaces default cloud account."
|
|
123
123
|
),
|
|
124
124
|
)
|
|
125
|
+
@click.option(
|
|
126
|
+
"--cloud-provider",
|
|
127
|
+
"--cloud_provider",
|
|
128
|
+
default=None,
|
|
129
|
+
help="The provider to create the studio on. If --cloud-account is specified, this option is prioritized.",
|
|
130
|
+
)
|
|
125
131
|
@click.option("--port", default=8000, help="The port to expose the API on.")
|
|
126
132
|
@click.option("--min_replica", "--min-replica", default=0, help="Number of replicas to start with.")
|
|
127
133
|
@click.option("--max_replica", "--max-replica", default=1, help="Number of replicas to scale up to.")
|
|
@@ -152,6 +158,7 @@ def api(
|
|
|
152
158
|
max_replica: Optional[int],
|
|
153
159
|
replicas: Optional[int],
|
|
154
160
|
no_credentials: Optional[bool],
|
|
161
|
+
cloud_provider: Optional[str],
|
|
155
162
|
) -> None:
|
|
156
163
|
"""Deploy a LitServe model script."""
|
|
157
164
|
return api_impl(
|
|
@@ -172,6 +179,7 @@ def api(
|
|
|
172
179
|
min_replica=min_replica,
|
|
173
180
|
max_replica=max_replica,
|
|
174
181
|
include_credentials=not no_credentials,
|
|
182
|
+
cloud_provider=cloud_provider,
|
|
175
183
|
)
|
|
176
184
|
|
|
177
185
|
|
|
@@ -194,6 +202,7 @@ def api_impl(
|
|
|
194
202
|
max_replica: Optional[int] = 1,
|
|
195
203
|
replicas: Optional[int] = 1,
|
|
196
204
|
include_credentials: Optional[bool] = True,
|
|
205
|
+
cloud_provider: Optional[str] = None,
|
|
197
206
|
) -> None:
|
|
198
207
|
"""Deploy a LitServe model script."""
|
|
199
208
|
console = Console()
|
|
@@ -226,6 +235,7 @@ def api_impl(
|
|
|
226
235
|
return _handle_devbox(name, script_path, console, non_interactive, machine, interruptible, teamspace, org, user)
|
|
227
236
|
|
|
228
237
|
machine = Machine.from_str(machine)
|
|
238
|
+
cloud_provider = CloudProvider.from_str(cloud_provider) if cloud_provider else None
|
|
229
239
|
return _handle_cloud(
|
|
230
240
|
script_path,
|
|
231
241
|
console,
|
|
@@ -243,6 +253,7 @@ def api_impl(
|
|
|
243
253
|
max_replica=max_replica,
|
|
244
254
|
replicas=replicas,
|
|
245
255
|
include_credentials=include_credentials,
|
|
256
|
+
cloud_provider=cloud_provider,
|
|
246
257
|
)
|
|
247
258
|
|
|
248
259
|
|
|
@@ -304,6 +315,7 @@ def _handle_cloud(
|
|
|
304
315
|
max_replica: Optional[int] = 1,
|
|
305
316
|
replicas: Optional[int] = 1,
|
|
306
317
|
include_credentials: Optional[bool] = True,
|
|
318
|
+
cloud_provider: Optional[CloudProvider] = None,
|
|
307
319
|
) -> None:
|
|
308
320
|
if not is_connected():
|
|
309
321
|
console.print("❌ Internet connection required to deploy to the cloud.", style="red")
|
|
@@ -379,7 +391,7 @@ def _handle_cloud(
|
|
|
379
391
|
resolved_teamspace = select_teamspace(teamspace, org, user)
|
|
380
392
|
|
|
381
393
|
lightning_containers_cloud_account = cloud_account
|
|
382
|
-
if not cloud_account:
|
|
394
|
+
if not cloud_account and not cloud_provider:
|
|
383
395
|
clusters_menu = _ClustersMenu()
|
|
384
396
|
lightning_containers_cloud_account = clusters_menu._resolve_cluster(resolved_teamspace)
|
|
385
397
|
cloud_account = resolved_teamspace.default_cloud_account
|
|
@@ -414,6 +426,7 @@ def _handle_cloud(
|
|
|
414
426
|
"include_credentials": include_credentials,
|
|
415
427
|
"cloudspace_id": cloudspace_id,
|
|
416
428
|
"from_onboarding": from_onboarding,
|
|
429
|
+
"cloud_provider": cloud_provider,
|
|
417
430
|
},
|
|
418
431
|
)
|
|
419
432
|
thread.start()
|
|
@@ -446,6 +459,7 @@ def _handle_cloud(
|
|
|
446
459
|
include_credentials=include_credentials,
|
|
447
460
|
cloudspace_id=cloudspace_id,
|
|
448
461
|
from_onboarding=from_onboarding,
|
|
462
|
+
cloud_provider=cloud_provider,
|
|
449
463
|
)
|
|
450
464
|
console.print(f"🚀 Deployment started, access at [i]{deployment_status.get('url')}[/i]")
|
|
451
465
|
if user_status["onboarded"]:
|
|
@@ -6,6 +6,7 @@ import click
|
|
|
6
6
|
def register_commands(group: click.Group) -> None:
|
|
7
7
|
"""Register studio commands with the given group."""
|
|
8
8
|
from lightning_sdk.cli.studio.connect import connect_studio
|
|
9
|
+
from lightning_sdk.cli.studio.cp import cp_studio_file
|
|
9
10
|
from lightning_sdk.cli.studio.create import create_studio
|
|
10
11
|
from lightning_sdk.cli.studio.delete import delete_studio
|
|
11
12
|
from lightning_sdk.cli.studio.list import list_studios
|
|
@@ -22,3 +23,4 @@ def register_commands(group: click.Group) -> None:
|
|
|
22
23
|
group.add_command(stop_studio)
|
|
23
24
|
group.add_command(switch_studio)
|
|
24
25
|
group.add_command(connect_studio)
|
|
26
|
+
group.add_command(cp_studio_file)
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
"""Studio cp command."""
|
|
2
|
+
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
from typing import Optional, TypedDict
|
|
5
|
+
|
|
6
|
+
import click
|
|
7
|
+
from rich.console import Console
|
|
8
|
+
|
|
9
|
+
from lightning_sdk.api.utils import _get_cloud_url
|
|
10
|
+
from lightning_sdk.cli.legacy.exceptions import StudioCliError
|
|
11
|
+
from lightning_sdk.cli.utils.owner_selection import OwnerMenu
|
|
12
|
+
from lightning_sdk.cli.utils.studio_selection import StudiosMenu
|
|
13
|
+
from lightning_sdk.cli.utils.teamspace_selection import TeamspacesMenu
|
|
14
|
+
from lightning_sdk.studio import Studio
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
@click.command("cp")
|
|
18
|
+
@click.argument("source", nargs=1)
|
|
19
|
+
@click.argument("destination", nargs=1)
|
|
20
|
+
def cp_studio_file(source: str, destination: str, teamspace: Optional[str] = None) -> None:
|
|
21
|
+
"""Copy a Studio file.
|
|
22
|
+
|
|
23
|
+
SOURCE: Source file to copy from. For Studio files, use the format lit://<owner>/<my-teamspace>/studios/<my-studio>/<filepath>.
|
|
24
|
+
|
|
25
|
+
DESTINATION: Destination file to copy to. For Studio files, use the format lit://<owner>/<my-teamspace>/studios/<my-studio>/<filepath>.
|
|
26
|
+
|
|
27
|
+
Example:
|
|
28
|
+
lightning studio cp source.txt lit://<owner>/<my-teamspace>/studios/<my-studio>/destination.txt
|
|
29
|
+
|
|
30
|
+
"""
|
|
31
|
+
return cp_impl(source=source, destination=destination)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def cp_impl(source: str, destination: str) -> None:
|
|
35
|
+
if "lit://" in source and "lit://" in destination:
|
|
36
|
+
raise ValueError("Both source and destination cannot be Studio files.")
|
|
37
|
+
elif "lit://" not in source and "lit://" not in destination:
|
|
38
|
+
raise ValueError("Either source or destination must be a Studio file.")
|
|
39
|
+
elif "lit://" in source:
|
|
40
|
+
# Download from Studio to local
|
|
41
|
+
cp_download(studio_file_path=source, local_file_path=destination)
|
|
42
|
+
else:
|
|
43
|
+
# Upload from local to Studio
|
|
44
|
+
cp_upload(local_file_path=source, studio_file_path=destination)
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
class StudioPathResult(TypedDict):
|
|
48
|
+
owner: Optional[str]
|
|
49
|
+
teamspace: Optional[str]
|
|
50
|
+
studio: Optional[str]
|
|
51
|
+
destination: Optional[str]
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def parse_studio_path(studio_path: str) -> StudioPathResult:
|
|
55
|
+
path_string = studio_path.removeprefix("lit://")
|
|
56
|
+
if not path_string:
|
|
57
|
+
raise ValueError("Studio path cannot be empty after prefix")
|
|
58
|
+
|
|
59
|
+
result: StudioPathResult = {"owner": None, "teamspace": None, "studio": None, "destination": None}
|
|
60
|
+
|
|
61
|
+
if "/studios/" in path_string:
|
|
62
|
+
prefix_part, suffix_part = path_string.split("/studios/", 1)
|
|
63
|
+
|
|
64
|
+
# org and teamspace
|
|
65
|
+
if prefix_part:
|
|
66
|
+
org_ts_components = prefix_part.split("/")
|
|
67
|
+
if len(org_ts_components) == 2:
|
|
68
|
+
result["owner"], result["teamspace"] = org_ts_components
|
|
69
|
+
elif len(org_ts_components) == 1:
|
|
70
|
+
result["teamspace"] = org_ts_components[0]
|
|
71
|
+
else:
|
|
72
|
+
raise ValueError(f"Invalid format: '{prefix_part}'")
|
|
73
|
+
|
|
74
|
+
# studio and destination
|
|
75
|
+
path_parts = suffix_part.split("/")
|
|
76
|
+
|
|
77
|
+
else:
|
|
78
|
+
# studio and destination
|
|
79
|
+
path_parts = path_string.split("/")
|
|
80
|
+
|
|
81
|
+
if not path_parts or len(path_parts) < 2:
|
|
82
|
+
raise ValueError("Invalid: Missing studio name.")
|
|
83
|
+
|
|
84
|
+
result["studio"] = path_parts[0]
|
|
85
|
+
result["destination"] = "/".join(path_parts[1:])
|
|
86
|
+
|
|
87
|
+
return result
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
def cp_upload(
|
|
91
|
+
local_file_path: str,
|
|
92
|
+
studio_file_path: str,
|
|
93
|
+
) -> None:
|
|
94
|
+
console = Console()
|
|
95
|
+
if Path(local_file_path).is_dir():
|
|
96
|
+
raise StudioCliError(
|
|
97
|
+
f"The provided path is a folder: {local_file_path}. Use `lightning upload folder` instead."
|
|
98
|
+
)
|
|
99
|
+
if not Path(local_file_path).exists():
|
|
100
|
+
raise FileNotFoundError(f"The provided path does not exist: {local_file_path}.")
|
|
101
|
+
|
|
102
|
+
studio_path_result = parse_studio_path(studio_file_path)
|
|
103
|
+
|
|
104
|
+
selected_studio = resolve_studio(
|
|
105
|
+
studio_path_result["studio"], studio_path_result["teamspace"], studio_path_result["owner"]
|
|
106
|
+
)
|
|
107
|
+
console.print(f"Uploading to {selected_studio.teamspace.name}/{selected_studio.name}")
|
|
108
|
+
|
|
109
|
+
selected_studio.upload_file(local_file_path, studio_file_path)
|
|
110
|
+
|
|
111
|
+
studio_url = (
|
|
112
|
+
_get_cloud_url().replace(":443", "")
|
|
113
|
+
+ "/"
|
|
114
|
+
+ selected_studio.owner.name
|
|
115
|
+
+ "/"
|
|
116
|
+
+ selected_studio.teamspace.name
|
|
117
|
+
+ "/studios/"
|
|
118
|
+
+ selected_studio.name
|
|
119
|
+
)
|
|
120
|
+
console.print(f"See your file at {studio_url}")
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
def cp_download(
|
|
124
|
+
studio_file_path: str,
|
|
125
|
+
local_file_path: str,
|
|
126
|
+
) -> None:
|
|
127
|
+
raise NotImplementedError("Download functionality is not implemented yet.")
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
def resolve_studio(studio_name: Optional[str], teamspace: Optional[str], owner: Optional[str]) -> Studio:
|
|
131
|
+
owner_menu = OwnerMenu()
|
|
132
|
+
resolved_owner = owner_menu(owner=owner)
|
|
133
|
+
|
|
134
|
+
teamspace_menu = TeamspacesMenu(resolved_owner)
|
|
135
|
+
resolved_teamspace = teamspace_menu(teamspace=teamspace)
|
|
136
|
+
|
|
137
|
+
studio_menu = StudiosMenu(resolved_teamspace)
|
|
138
|
+
return studio_menu(studio=studio_name)
|
|
@@ -4,7 +4,7 @@ from typing import Any, Dict, List, Optional, Union
|
|
|
4
4
|
|
|
5
5
|
import requests
|
|
6
6
|
|
|
7
|
-
from lightning_sdk.api import UserApi
|
|
7
|
+
from lightning_sdk.api import CloudAccountApi, UserApi
|
|
8
8
|
from lightning_sdk.api.deployment_api import (
|
|
9
9
|
ApiKeyAuth,
|
|
10
10
|
Auth,
|
|
@@ -28,9 +28,10 @@ from lightning_sdk.api.deployment_api import (
|
|
|
28
28
|
to_spec,
|
|
29
29
|
to_strategy,
|
|
30
30
|
)
|
|
31
|
+
from lightning_sdk.api.utils import AccessibleResource, raise_access_error_if_not_allowed
|
|
31
32
|
from lightning_sdk.lightning_cloud import login
|
|
32
33
|
from lightning_sdk.lightning_cloud.openapi import V1Deployment
|
|
33
|
-
from lightning_sdk.machine import Machine
|
|
34
|
+
from lightning_sdk.machine import CloudProvider, Machine
|
|
34
35
|
from lightning_sdk.organization import Organization
|
|
35
36
|
from lightning_sdk.services.utilities import _get_cluster
|
|
36
37
|
from lightning_sdk.studio import Studio
|
|
@@ -66,6 +67,7 @@ class Deployment(metaclass=TrackCallsMeta):
|
|
|
66
67
|
user: Optional[Union[str, User]] = None,
|
|
67
68
|
) -> None:
|
|
68
69
|
self._request_session = None
|
|
70
|
+
self._cloud_account_api = CloudAccountApi()
|
|
69
71
|
|
|
70
72
|
self._auth = login.Auth()
|
|
71
73
|
self._user = None
|
|
@@ -92,6 +94,8 @@ class Deployment(metaclass=TrackCallsMeta):
|
|
|
92
94
|
if self._teamspace is None:
|
|
93
95
|
raise ValueError("You need to pass a teamspace or an org for your deployment.")
|
|
94
96
|
|
|
97
|
+
raise_access_error_if_not_allowed(AccessibleResource.Deployments, self._teamspace.id)
|
|
98
|
+
|
|
95
99
|
self._deployment_api = DeploymentApi()
|
|
96
100
|
self._cloud_account = _get_cluster(client=self._deployment_api._client, project_id=self._teamspace.id)
|
|
97
101
|
self._is_created = False
|
|
@@ -134,6 +138,7 @@ class Deployment(metaclass=TrackCallsMeta):
|
|
|
134
138
|
from_litserve: Optional[bool] = None,
|
|
135
139
|
max_runtime: Optional[int] = None,
|
|
136
140
|
path_mappings: Optional[Dict[str, str]] = None,
|
|
141
|
+
cloud_provider: Optional[CloudProvider] = None,
|
|
137
142
|
) -> None:
|
|
138
143
|
"""The Lightning AI Deployment.
|
|
139
144
|
|
|
@@ -180,6 +185,7 @@ class Deployment(metaclass=TrackCallsMeta):
|
|
|
180
185
|
only one of the arguments can be provided.
|
|
181
186
|
|
|
182
187
|
"""
|
|
188
|
+
raise_access_error_if_not_allowed(AccessibleResource.Deployments, self._teamspace.id)
|
|
183
189
|
if self._is_created:
|
|
184
190
|
raise RuntimeError("This deployment has already been started.")
|
|
185
191
|
|
|
@@ -199,10 +205,17 @@ class Deployment(metaclass=TrackCallsMeta):
|
|
|
199
205
|
if cloud_account is None:
|
|
200
206
|
cloud_account = _resolve_deprecated_cluster(cloud_account, cluster)
|
|
201
207
|
|
|
202
|
-
if cloud_account is None and self._cloud_account is not None:
|
|
208
|
+
if cloud_account is None and self._cloud_account is not None and cloud_provider is None:
|
|
203
209
|
print(f"No cloud account was provided, defaulting to {self._cloud_account.cluster_id}")
|
|
204
210
|
cloud_account = os.getenv("LIGHTNING_CLUSTER_ID") or self._cloud_account.cluster_id
|
|
205
211
|
|
|
212
|
+
_cloud_account = self._cloud_account_api.resolve_cloud_account(
|
|
213
|
+
self.teamspace.id,
|
|
214
|
+
cloud_account=cloud_account,
|
|
215
|
+
cloud_provider=cloud_provider,
|
|
216
|
+
default_cloud_account=self._teamspace.default_cloud_account,
|
|
217
|
+
)
|
|
218
|
+
|
|
206
219
|
if isinstance(ports, float):
|
|
207
220
|
ports = [ports]
|
|
208
221
|
|
|
@@ -237,7 +250,7 @@ class Deployment(metaclass=TrackCallsMeta):
|
|
|
237
250
|
replicas=replicas,
|
|
238
251
|
cloudspace_id=cloudspace_id,
|
|
239
252
|
spec=to_spec(
|
|
240
|
-
cloud_account=
|
|
253
|
+
cloud_account=_cloud_account,
|
|
241
254
|
command=command,
|
|
242
255
|
entrypoint=entrypoint,
|
|
243
256
|
env=env,
|
|
@@ -289,6 +302,7 @@ class Deployment(metaclass=TrackCallsMeta):
|
|
|
289
302
|
max_runtime: Optional[int] = None,
|
|
290
303
|
path_mappings: Optional[Dict[str, str]] = None,
|
|
291
304
|
) -> None:
|
|
305
|
+
raise_access_error_if_not_allowed(AccessibleResource.Deployments, self._teamspace.id)
|
|
292
306
|
cloud_account = _resolve_deprecated_cluster(cloud_account, cluster)
|
|
293
307
|
|
|
294
308
|
if command is None and commands is not None:
|
lightning_sdk/job/job.py
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
from typing import TYPE_CHECKING, Any, Dict, Optional, Union
|
|
2
2
|
|
|
3
|
+
from lightning_sdk.api.utils import AccessibleResource, raise_access_error_if_not_allowed
|
|
3
4
|
from lightning_sdk.job.base import _BaseJob
|
|
4
5
|
from lightning_sdk.job.v1 import _JobV1
|
|
5
6
|
from lightning_sdk.job.v2 import _JobV2
|
|
6
|
-
from lightning_sdk.utils.resolve import _setup_logger
|
|
7
|
+
from lightning_sdk.utils.resolve import _resolve_teamspace, _setup_logger
|
|
7
8
|
|
|
8
9
|
_logger = _setup_logger(__name__)
|
|
9
10
|
|
|
11
|
+
|
|
10
12
|
if TYPE_CHECKING:
|
|
11
13
|
from lightning_sdk.machine import CloudProvider, Machine
|
|
12
14
|
from lightning_sdk.organization import Organization
|
|
@@ -39,6 +41,10 @@ class Job(_BaseJob):
|
|
|
39
41
|
user: the name of the user owning the :param`teamspace`
|
|
40
42
|
in case it is owned directly by a user instead of an org.
|
|
41
43
|
"""
|
|
44
|
+
teamspace = _resolve_teamspace(teamspace=teamspace, org=org, user=user)
|
|
45
|
+
|
|
46
|
+
raise_access_error_if_not_allowed(AccessibleResource.Jobs, teamspace.id)
|
|
47
|
+
|
|
42
48
|
from lightning_sdk.lightning_cloud.openapi.rest import ApiException
|
|
43
49
|
|
|
44
50
|
if not self._force_v1:
|
lightning_sdk/lit_container.py
CHANGED
|
@@ -4,6 +4,7 @@ from typing import Dict, List, Optional
|
|
|
4
4
|
from rich.console import Console
|
|
5
5
|
|
|
6
6
|
from lightning_sdk.api.lit_container_api import LitContainerApi
|
|
7
|
+
from lightning_sdk.api.utils import AccessibleResource, raise_access_error_if_not_allowed
|
|
7
8
|
from lightning_sdk.utils.resolve import _resolve_teamspace
|
|
8
9
|
|
|
9
10
|
|
|
@@ -31,6 +32,8 @@ class LitContainer:
|
|
|
31
32
|
except Exception:
|
|
32
33
|
console.print(f"[bold red]Could not resolve teamspace: {teamspace}[/bold red]")
|
|
33
34
|
return []
|
|
35
|
+
|
|
36
|
+
raise_access_error_if_not_allowed(AccessibleResource.Containers, teamspace.id)
|
|
34
37
|
project_id = teamspace.id
|
|
35
38
|
repositories = self._api.list_containers(project_id, cloud_account=cloud_account)
|
|
36
39
|
table = []
|
|
@@ -68,6 +71,8 @@ class LitContainer:
|
|
|
68
71
|
teamspace = _resolve_teamspace(teamspace=teamspace, org=org, user=user)
|
|
69
72
|
except Exception as e:
|
|
70
73
|
raise ValueError("Could not resolve teamspace") from e
|
|
74
|
+
|
|
75
|
+
raise_access_error_if_not_allowed(AccessibleResource.Containers, teamspace.id)
|
|
71
76
|
project_id = teamspace.id
|
|
72
77
|
return self._api.delete_container(project_id, container)
|
|
73
78
|
|
|
@@ -99,6 +104,8 @@ class LitContainer:
|
|
|
99
104
|
except Exception as e:
|
|
100
105
|
raise ValueError(f"Could not resolve teamspace: {e}") from e
|
|
101
106
|
|
|
107
|
+
raise_access_error_if_not_allowed(AccessibleResource.Containers, teamspace.id)
|
|
108
|
+
|
|
102
109
|
resp = self._api.upload_container(
|
|
103
110
|
container, teamspace, tag, cloud_account, platform=platform, return_final_dict=return_final_dict
|
|
104
111
|
)
|
|
@@ -134,4 +141,6 @@ class LitContainer:
|
|
|
134
141
|
except Exception as e:
|
|
135
142
|
raise ValueError(f"Could not resolve teamspace: {e}") from e
|
|
136
143
|
|
|
144
|
+
raise_access_error_if_not_allowed(AccessibleResource.Containers, teamspace.id)
|
|
145
|
+
|
|
137
146
|
return self._api.download_container(container, teamspace, tag, cloud_account)
|
lightning_sdk/machine.py
CHANGED
|
@@ -16,6 +16,14 @@ class CloudProvider(Enum):
|
|
|
16
16
|
"""Converts the CloudProvider to a str."""
|
|
17
17
|
return self.value
|
|
18
18
|
|
|
19
|
+
@classmethod
|
|
20
|
+
def from_str(cls, provider: str) -> "CloudProvider":
|
|
21
|
+
"""Converts a string to a CloudProvider enum member."""
|
|
22
|
+
for cp in cls:
|
|
23
|
+
if cp.value.lower() == provider.lower():
|
|
24
|
+
return cp
|
|
25
|
+
raise ValueError(f"Unknown CloudProvider: {provider}")
|
|
26
|
+
|
|
19
27
|
|
|
20
28
|
@dataclass(frozen=True)
|
|
21
29
|
class Machine:
|
lightning_sdk/mmt/mmt.py
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
from typing import TYPE_CHECKING, Any, Dict, Optional, Tuple, Union
|
|
2
2
|
|
|
3
3
|
from lightning_sdk.api.cloud_account_api import CloudAccountApi
|
|
4
|
+
from lightning_sdk.api.utils import AccessibleResource, raise_access_error_if_not_allowed
|
|
4
5
|
from lightning_sdk.mmt.base import MMTMachine, _BaseMMT
|
|
5
6
|
from lightning_sdk.mmt.v1 import _MMTV1
|
|
6
7
|
from lightning_sdk.mmt.v2 import _MMTV2
|
|
7
|
-
from lightning_sdk.utils.resolve import _setup_logger
|
|
8
|
+
from lightning_sdk.utils.resolve import _resolve_teamspace, _setup_logger
|
|
8
9
|
|
|
9
10
|
if TYPE_CHECKING:
|
|
10
11
|
from lightning_sdk.machine import CloudProvider, Machine
|
|
@@ -42,6 +43,9 @@ class MMT(_BaseMMT):
|
|
|
42
43
|
user: the name of the user owning the :param`teamspace`
|
|
43
44
|
in case it is owned directly by a user instead of an org.
|
|
44
45
|
"""
|
|
46
|
+
teamspace = _resolve_teamspace(teamspace=teamspace, org=org, user=user)
|
|
47
|
+
raise_access_error_if_not_allowed(AccessibleResource.Jobs, teamspace_id=teamspace.id)
|
|
48
|
+
|
|
45
49
|
from lightning_sdk.lightning_cloud.openapi.rest import ApiException
|
|
46
50
|
|
|
47
51
|
if not self._force_v1:
|
lightning_sdk/models.py
CHANGED
|
@@ -4,6 +4,7 @@ from pathlib import Path
|
|
|
4
4
|
from typing import TYPE_CHECKING, Any, Dict, List, Optional, Tuple, Union
|
|
5
5
|
|
|
6
6
|
from lightning_sdk.api import OrgApi, TeamspaceApi, UserApi
|
|
7
|
+
from lightning_sdk.api.utils import AccessibleResource, raise_access_error_if_not_allowed
|
|
7
8
|
from lightning_sdk.lightning_cloud.openapi import V1ModelVersionArchive
|
|
8
9
|
from lightning_sdk.lightning_cloud.openapi.models import V1Membership, V1OwnerType
|
|
9
10
|
from lightning_sdk.lightning_cloud.openapi.rest import ApiException
|
|
@@ -121,6 +122,10 @@ def download_model(
|
|
|
121
122
|
"""
|
|
122
123
|
name = _extend_model_name_with_teamspace(name)
|
|
123
124
|
teamspace_owner_name, teamspace_name, model_name, version = _parse_org_teamspace_model_version(name)
|
|
125
|
+
|
|
126
|
+
teamspace = _get_teamspace(name=teamspace_name, organization=teamspace_owner_name)
|
|
127
|
+
raise_access_error_if_not_allowed(AccessibleResource.Models, teamspace.id)
|
|
128
|
+
|
|
124
129
|
api = TeamspaceApi()
|
|
125
130
|
|
|
126
131
|
try:
|
|
@@ -162,6 +167,7 @@ def upload_model(
|
|
|
162
167
|
name = _extend_model_name_with_teamspace(name)
|
|
163
168
|
org_name, teamspace_name, model_name, version = _parse_org_teamspace_model_version(name)
|
|
164
169
|
teamspace = _get_teamspace(name=teamspace_name, organization=org_name)
|
|
170
|
+
raise_access_error_if_not_allowed(AccessibleResource.Models, teamspace.id)
|
|
165
171
|
return teamspace.upload_model(
|
|
166
172
|
path=path,
|
|
167
173
|
name=model_name,
|
|
@@ -185,6 +191,7 @@ def delete_model(
|
|
|
185
191
|
name = _extend_model_name_with_teamspace(name)
|
|
186
192
|
org_name, teamspace_name, model_name, version = _parse_org_teamspace_model_version(name)
|
|
187
193
|
teamspace = _get_teamspace(name=teamspace_name, organization=org_name)
|
|
194
|
+
raise_access_error_if_not_allowed(AccessibleResource.Models, teamspace.id)
|
|
188
195
|
teamspace.delete_model(name=f"{model_name}:{version}" if version else model_name)
|
|
189
196
|
|
|
190
197
|
|
|
@@ -200,4 +207,5 @@ def list_model_versions(
|
|
|
200
207
|
name = _extend_model_name_with_teamspace(name)
|
|
201
208
|
org_name, teamspace_name, model_name, _ = _parse_org_teamspace_model_version(name)
|
|
202
209
|
teamspace = _get_teamspace(name=teamspace_name, organization=org_name)
|
|
210
|
+
raise_access_error_if_not_allowed(AccessibleResource.Models, teamspace.id)
|
|
203
211
|
return teamspace.list_model_versions(name=model_name)
|
|
@@ -3,6 +3,7 @@ from typing import List, Optional, Union
|
|
|
3
3
|
|
|
4
4
|
from lightning_sdk.api.cloud_account_api import CloudAccountApi
|
|
5
5
|
from lightning_sdk.api.pipeline_api import PipelineApi
|
|
6
|
+
from lightning_sdk.api.utils import AccessibleResource, raise_access_error_if_not_allowed
|
|
6
7
|
from lightning_sdk.machine import CloudProvider
|
|
7
8
|
from lightning_sdk.organization import Organization
|
|
8
9
|
from lightning_sdk.pipeline.printer import PipelinePrinter
|
|
@@ -49,6 +50,8 @@ class Pipeline:
|
|
|
49
50
|
if self._teamspace is None:
|
|
50
51
|
raise RuntimeError("Could not resolve teamspace")
|
|
51
52
|
|
|
53
|
+
raise_access_error_if_not_allowed(AccessibleResource.Pipelines, self._teamspace.id)
|
|
54
|
+
|
|
52
55
|
self._pipeline_api = PipelineApi()
|
|
53
56
|
self._cloud_account_api = CloudAccountApi()
|
|
54
57
|
self._cloud_account = self._cloud_account_api.resolve_cloud_account(
|
lightning_sdk/serve.py
CHANGED
|
@@ -7,7 +7,7 @@ from typing import Generator, List, Optional, Union
|
|
|
7
7
|
import docker
|
|
8
8
|
from rich.console import Console
|
|
9
9
|
|
|
10
|
-
from lightning_sdk import Deployment, Machine, Teamspace
|
|
10
|
+
from lightning_sdk import CloudProvider, Deployment, Machine, Teamspace
|
|
11
11
|
from lightning_sdk.api.deployment_api import AutoScaleConfig, DeploymentApi, Env, Secret
|
|
12
12
|
from lightning_sdk.api.lit_container_api import LitContainerApi
|
|
13
13
|
from lightning_sdk.api.utils import _get_cloud_url
|
|
@@ -249,6 +249,7 @@ Check out [blue][link=https://lightning.ai/docs/litserve/features]the docs[/link
|
|
|
249
249
|
include_credentials: Optional[bool] = True,
|
|
250
250
|
cloudspace_id: Optional[str] = None,
|
|
251
251
|
from_onboarding: bool = False,
|
|
252
|
+
cloud_provider: Optional[CloudProvider] = None,
|
|
252
253
|
) -> dict:
|
|
253
254
|
"""Run a deployment on the cloud. If the deployment already exists, it will be updated.
|
|
254
255
|
|
|
@@ -304,6 +305,7 @@ Check out [blue][link=https://lightning.ai/docs/litserve/features]the docs[/link
|
|
|
304
305
|
from_litserve=True,
|
|
305
306
|
from_onboarding=from_onboarding,
|
|
306
307
|
command="",
|
|
308
|
+
cloud_provider=cloud_provider,
|
|
307
309
|
)
|
|
308
310
|
|
|
309
311
|
return {"deployment": deployment, "url": url}
|
lightning_sdk/studio.py
CHANGED
|
@@ -8,6 +8,7 @@ from tqdm.auto import tqdm
|
|
|
8
8
|
|
|
9
9
|
from lightning_sdk.api.cloud_account_api import CloudAccountApi
|
|
10
10
|
from lightning_sdk.api.studio_api import StudioApi
|
|
11
|
+
from lightning_sdk.api.utils import AccessibleResource, raise_access_error_if_not_allowed
|
|
11
12
|
from lightning_sdk.base_studio import BaseStudio
|
|
12
13
|
from lightning_sdk.constants import _LIGHTNING_DEBUG
|
|
13
14
|
from lightning_sdk.lightning_cloud.openapi import V1ClusterType
|
|
@@ -97,6 +98,7 @@ class Studio(metaclass=TrackCallsMeta):
|
|
|
97
98
|
raise ValueError("Couldn't resolve teamspace from the provided name, org, or user")
|
|
98
99
|
|
|
99
100
|
self._teamspace = _teamspace
|
|
101
|
+
raise_access_error_if_not_allowed(AccessibleResource.Studios, self._teamspace.id)
|
|
100
102
|
|
|
101
103
|
self._setup_done = getattr(self._skip_setup, "value", False)
|
|
102
104
|
self._disable_secrets = disable_secrets
|
lightning_sdk/teamspace.py
CHANGED
|
@@ -10,6 +10,7 @@ from tqdm.auto import tqdm
|
|
|
10
10
|
import lightning_sdk
|
|
11
11
|
from lightning_sdk.agents import Agent
|
|
12
12
|
from lightning_sdk.api import CloudAccountApi, TeamspaceApi
|
|
13
|
+
from lightning_sdk.api.utils import AccessibleResource, raise_access_error_if_not_allowed
|
|
13
14
|
from lightning_sdk.lightning_cloud.openapi import V1ClusterType, V1Model, V1ModelVersionArchive, V1ProjectClusterBinding
|
|
14
15
|
from lightning_sdk.machine import CloudProvider, Machine
|
|
15
16
|
from lightning_sdk.models import UploadedModelInfo
|
|
@@ -143,12 +144,17 @@ class Teamspace(metaclass=TrackCallsMeta):
|
|
|
143
144
|
@property
|
|
144
145
|
def studios(self) -> List["Studio"]:
|
|
145
146
|
"""All studios within that teamspace."""
|
|
147
|
+
raise_access_error_if_not_allowed(AccessibleResource.Studios, self.id)
|
|
146
148
|
from lightning_sdk.studio import Studio
|
|
147
149
|
|
|
148
150
|
return self._get_studios(Studio)
|
|
149
151
|
|
|
150
152
|
@property
|
|
151
153
|
def vms(self) -> List["VM"]:
|
|
154
|
+
try:
|
|
155
|
+
raise_access_error_if_not_allowed(AccessibleResource.Studios, self.id)
|
|
156
|
+
except PermissionError as e:
|
|
157
|
+
raise PermissionError(str(e).replace("Studios", "VMs")) from e
|
|
152
158
|
from lightning_sdk.studio import VM
|
|
153
159
|
|
|
154
160
|
return [x for x in self._get_studios(VM) if isinstance(x, VM)]
|
|
@@ -204,6 +210,8 @@ class Teamspace(metaclass=TrackCallsMeta):
|
|
|
204
210
|
from lightning_sdk.job import Job
|
|
205
211
|
from lightning_sdk.plugin import forced_v1
|
|
206
212
|
|
|
213
|
+
raise_access_error_if_not_allowed(AccessibleResource.Jobs, self.id)
|
|
214
|
+
|
|
207
215
|
jobsv1, jobsv2 = self._teamspace_api.list_jobs(teamspace_id=self.id)
|
|
208
216
|
|
|
209
217
|
jobs = []
|
|
@@ -228,6 +236,8 @@ class Teamspace(metaclass=TrackCallsMeta):
|
|
|
228
236
|
from lightning_sdk.mmt import MMT
|
|
229
237
|
from lightning_sdk.plugin import forced_v1
|
|
230
238
|
|
|
239
|
+
raise_access_error_if_not_allowed(AccessibleResource.Jobs, self.id)
|
|
240
|
+
|
|
231
241
|
mmtsv1, mmtsv2 = self._teamspace_api.list_mmts(teamspace_id=self.id)
|
|
232
242
|
|
|
233
243
|
mmts = []
|
|
@@ -351,6 +361,7 @@ class Teamspace(metaclass=TrackCallsMeta):
|
|
|
351
361
|
progress_bar: Whether to show a progress bar for the upload.
|
|
352
362
|
metadata: Metadata to attach to the model. Can be a dictionary.
|
|
353
363
|
"""
|
|
364
|
+
raise_access_error_if_not_allowed(AccessibleResource.Models, self.id)
|
|
354
365
|
if not path:
|
|
355
366
|
raise ValueError("No path provided to upload")
|
|
356
367
|
if not name:
|
|
@@ -430,6 +441,7 @@ class Teamspace(metaclass=TrackCallsMeta):
|
|
|
430
441
|
The absolute path to the downloaded model file or folder.
|
|
431
442
|
|
|
432
443
|
"""
|
|
444
|
+
raise_access_error_if_not_allowed(AccessibleResource.Models, self.id)
|
|
433
445
|
if not name:
|
|
434
446
|
raise ValueError("No name provided for the model")
|
|
435
447
|
if download_dir is None:
|
|
@@ -468,15 +480,18 @@ class Teamspace(metaclass=TrackCallsMeta):
|
|
|
468
480
|
e.g. 'entity/modelname:v1'.
|
|
469
481
|
|
|
470
482
|
"""
|
|
483
|
+
raise_access_error_if_not_allowed(AccessibleResource.Models, self.id)
|
|
471
484
|
name, version = _parse_model_and_version(name)
|
|
472
485
|
self._teamspace_api.delete_model(name=name, version=version, teamspace_id=self.id)
|
|
473
486
|
|
|
474
487
|
def list_models(self) -> List[V1Model]:
|
|
475
488
|
"""List all models in the model store."""
|
|
489
|
+
raise_access_error_if_not_allowed(AccessibleResource.Models, self.id)
|
|
476
490
|
return self._teamspace_api.list_models(teamspace_id=self.id)
|
|
477
491
|
|
|
478
492
|
def list_model_versions(self, name: str) -> List[V1ModelVersionArchive]:
|
|
479
493
|
"""List all versions of a model in the model store."""
|
|
494
|
+
raise_access_error_if_not_allowed(AccessibleResource.Models, self.id)
|
|
480
495
|
if ":" in name:
|
|
481
496
|
raise ValueError(
|
|
482
497
|
"Model name should not contain a version tag. Please provide the model name without a version."
|
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
docs/source/conf.py,sha256=r8yX20eC-4mHhMTd0SbQb5TlSWHhO6wnJ0VJ_FBFpag,13249
|
|
2
2
|
lightning_sdk/__init__.py,sha256=aTu3zCrxj6rhgvc17ditLe71LTGvyU27Fg2GwOR4gUY,1301
|
|
3
|
-
lightning_sdk/__version__.py,sha256=
|
|
3
|
+
lightning_sdk/__version__.py,sha256=hqNBnV5LTBUIhMeuGeJkdLaMqcLZJZ6Gbyid4dzeywE,73
|
|
4
4
|
lightning_sdk/agents.py,sha256=Uqsdu4PgswhpeXZzDSbp3hu30MMOhSlCnp8D56MaS_c,1658
|
|
5
5
|
lightning_sdk/ai_hub.py,sha256=QzCfmX0h2CLn7r0DQyjWg6RnNw26Ey6akiP2Wffl9Ls,7006
|
|
6
6
|
lightning_sdk/base_studio.py,sha256=yMvZ1dDq_avW3iu98CLEo9W9UL54mx4C6FC43IKLWAE,4691
|
|
7
7
|
lightning_sdk/constants.py,sha256=Lr6MRnBieAbuT94w9KnbueuU15qz4N9Kgu1um7yH2nw,839
|
|
8
8
|
lightning_sdk/helpers.py,sha256=WvsetkrXC8n4iQUFKpwQOKo7oaaOxgfWJm6KcMeVaTE,3508
|
|
9
|
-
lightning_sdk/lit_container.py,sha256=
|
|
10
|
-
lightning_sdk/machine.py,sha256=
|
|
11
|
-
lightning_sdk/models.py,sha256=
|
|
9
|
+
lightning_sdk/lit_container.py,sha256=9gAGoilwn6x0PF-FxcRm9wyJG64mqOs7HH76g8ksxsk,5715
|
|
10
|
+
lightning_sdk/machine.py,sha256=ezAu7CnZi7TLJo9yGElRmt9j6RNrRGrBBJdr6giLx40,9918
|
|
11
|
+
lightning_sdk/models.py,sha256=p0JZaInjFbxiUx96ZmfNQfr8VDL8n-ZekusqVmWlYHQ,8356
|
|
12
12
|
lightning_sdk/organization.py,sha256=jizjG4oW_oxkP2Qz4vL5cle4Cg12xB_vf4eT-bnvLP0,1352
|
|
13
13
|
lightning_sdk/owner.py,sha256=k0Hh0BQNxc6Jajzqt6jUgApM0IxHDNPIe_X1ocCI2Rk,1448
|
|
14
14
|
lightning_sdk/plugin.py,sha256=yaQrIx2Tt18R0CoarJQAtB_AwaVa436f-eC5rb9yWe4,15579
|
|
15
15
|
lightning_sdk/sandbox.py,sha256=_NvnWotEXW2rBiVFZZ4krKXxVjuAqfNh04qELSM0-Pg,5786
|
|
16
|
-
lightning_sdk/serve.py,sha256=
|
|
16
|
+
lightning_sdk/serve.py,sha256=XbllHwmOAOHjQJ0AQukwYe3OtspEwhmf5-_HXhL-mpc,11908
|
|
17
17
|
lightning_sdk/status.py,sha256=lLGAuSvXBoXQFEEsEYwdCi0RcSNatUn5OPjJVjDtoM0,386
|
|
18
|
-
lightning_sdk/studio.py,sha256=
|
|
19
|
-
lightning_sdk/teamspace.py,sha256=
|
|
18
|
+
lightning_sdk/studio.py,sha256=LVpyH58HaDcm5mNFrIYueoiERvUzO7Ed535aWTKs7-k,37159
|
|
19
|
+
lightning_sdk/teamspace.py,sha256=pskDJWe3OGKFeXCKr-QZbzgor2AOQwdzgxqlS8Ahj_o,27558
|
|
20
20
|
lightning_sdk/user.py,sha256=TSYh38rxoi7qKOfrK2JYh_Nknya2Kbz2ngDIY85fFOY,1778
|
|
21
21
|
lightning_sdk/api/__init__.py,sha256=xrp_RNECJGQtL5rZHF69WOzEuEIbWSLtjWAJAz4R5K4,500
|
|
22
22
|
lightning_sdk/api/agents_api.py,sha256=G47TbFo9kYqnBMqdw2RW-lfS1VAUBSXDmzs6fpIEMUs,4059
|
|
@@ -34,7 +34,7 @@ lightning_sdk/api/pipeline_api.py,sha256=rJYp_FN7uUjC5xbc6K67l2eRSmVuOkijd5i8Nm5
|
|
|
34
34
|
lightning_sdk/api/studio_api.py,sha256=itQqpC9Be2O69CX7eful3Q2t66NrtMPAizhxUDImpKA,39927
|
|
35
35
|
lightning_sdk/api/teamspace_api.py,sha256=wuwW4YbhloFqI9rS_5mbgsS6Dk3zYONLv9M6OoqyDg8,19980
|
|
36
36
|
lightning_sdk/api/user_api.py,sha256=o9gZmtvqNfj4kdSpo2fyyRuFAP7bM5w7mx0Oj9__Ads,4702
|
|
37
|
-
lightning_sdk/api/utils.py,sha256=
|
|
37
|
+
lightning_sdk/api/utils.py,sha256=FvkpPt3-5IPfPW5QQsWoYlCC2SQXeQ-PB68gtICrWvM,29051
|
|
38
38
|
lightning_sdk/cli/__init__.py,sha256=lksw08t_ZIuHOH47LCIqSVHeZ8cUXI2aJWHYhyujYHM,32
|
|
39
39
|
lightning_sdk/cli/entrypoint.py,sha256=WsHbYB-rGIbXwz_Un6UiuOFdVPwXGTOs7GC5Zh4Y_B4,3467
|
|
40
40
|
lightning_sdk/cli/groups.py,sha256=umtnKZm4xrIEtY-SWrC1KcKzYGvArr08qeP2zGPkyTk,1609
|
|
@@ -73,14 +73,15 @@ lightning_sdk/cli/legacy/upload.py,sha256=fFJct9F_1vLqTMLtSjuv4BN3AbUpeGebwv3ZXH
|
|
|
73
73
|
lightning_sdk/cli/legacy/deploy/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
74
74
|
lightning_sdk/cli/legacy/deploy/_auth.py,sha256=nUe9Lqx154qapHRPdZCWqMICCEPWGjofnikYBdYcBBM,7680
|
|
75
75
|
lightning_sdk/cli/legacy/deploy/devbox.py,sha256=SdOtYdGefzldn-WCa6sz31zysyf2nP5D7O2x1DE9z_E,6839
|
|
76
|
-
lightning_sdk/cli/legacy/deploy/serve.py,sha256=
|
|
76
|
+
lightning_sdk/cli/legacy/deploy/serve.py,sha256=qzuJ6IRYaIEP9P_A6fGX1gRo2FX2i8gJC3vwX4vbFZs,16094
|
|
77
77
|
lightning_sdk/cli/license/__init__.py,sha256=UmtIevklzc_2j4fZlrE9RyONHVs2E1AdZD66nWz0OPY,446
|
|
78
78
|
lightning_sdk/cli/license/get.py,sha256=XkZvsuWwD5OdsAymzNggHJBuNEkZEhz0ZVl7lIWit6g,604
|
|
79
79
|
lightning_sdk/cli/license/list.py,sha256=RUaR271kdHgTbFIagjOagopkOI8vmIHf3guaup0rzs8,1342
|
|
80
80
|
lightning_sdk/cli/license/set.py,sha256=uGjFgq-3jkMF0IstMIIRjKn8GDzg9TIe1OZcRkDTrqg,515
|
|
81
81
|
lightning_sdk/cli/mmt/__init__.py,sha256=CLgr-ZHHLS6Db_JGqpxbn4G2pYrKi4Qn-uhi8e0kFNc,145
|
|
82
|
-
lightning_sdk/cli/studio/__init__.py,sha256=
|
|
82
|
+
lightning_sdk/cli/studio/__init__.py,sha256=wREPAmPJdN4b51r6RRD1o4aE212KN7xI88Z0O6HTzEU,1022
|
|
83
83
|
lightning_sdk/cli/studio/connect.py,sha256=RLi5VumsVlVDlyiGbST7lDuHAntOj_-99KsNr8J3knE,5057
|
|
84
|
+
lightning_sdk/cli/studio/cp.py,sha256=u1GM58i4YO70GqbgnNAIkG-HnIOW5b5y1Mby3SsQKRk,4748
|
|
84
85
|
lightning_sdk/cli/studio/create.py,sha256=eVkuP1qg1aQSe2jyDgbIg-si5xPl8CwDIPcyvkUEFnQ,3179
|
|
85
86
|
lightning_sdk/cli/studio/delete.py,sha256=Gi1KLCrSgjTiyoQe9NRvF4ZpsNyeM07KHnBxfdJg2FE,1483
|
|
86
87
|
lightning_sdk/cli/studio/list.py,sha256=ieLiHRIfAb7E5e_r48BeTC03ib8RY6maeF7nkmrqaek,3301
|
|
@@ -110,10 +111,10 @@ lightning_sdk/cli/vm/start.py,sha256=v0FI482lscAN9S-XEW1IJ_sHiu45xSxCZJMHgPa8zNI
|
|
|
110
111
|
lightning_sdk/cli/vm/stop.py,sha256=rZ-aWCE95n4wPe9edevXI0xq5RL5gxGeG8hCzvCyQCs,671
|
|
111
112
|
lightning_sdk/cli/vm/switch.py,sha256=7jcKbTnqRv6JjOcDDVRDy8OP9xCxJ3ctLqBJViNAxbc,1174
|
|
112
113
|
lightning_sdk/deployment/__init__.py,sha256=TRkd1xGCuYcsPzZwvq-vm_Qwlu3-htp8je-PYMcqjFc,579
|
|
113
|
-
lightning_sdk/deployment/deployment.py,sha256=
|
|
114
|
+
lightning_sdk/deployment/deployment.py,sha256=iI2B9dIAQjknqzIcWNP2MsHr-l0K2E9SW1EJp-H24rs,23526
|
|
114
115
|
lightning_sdk/job/__init__.py,sha256=1MxjQ6rHkyUHCypSW9RuXuVMVH11WiqhIXcU2LCFMwE,64
|
|
115
116
|
lightning_sdk/job/base.py,sha256=4_hdUOqorLaaym10ccoB9TvWZM_btEJkVI5_wE9K0oM,21744
|
|
116
|
-
lightning_sdk/job/job.py,sha256=
|
|
117
|
+
lightning_sdk/job/job.py,sha256=9RTMSf2czZbrrjrGZ-2fOZAWMIGomZMG2UE5D_6pgPs,15825
|
|
117
118
|
lightning_sdk/job/v1.py,sha256=32mzDi4y2zNMYk9ZCMQS1c_yJfbnKrAjwKnJmo6HMCU,9977
|
|
118
119
|
lightning_sdk/job/v2.py,sha256=VAArSIEDH05H3gnALVVPLNRrKm42cxG8No6i9jT_NzY,11710
|
|
119
120
|
lightning_sdk/job/work.py,sha256=aRknNDja-96qQaYw0fNboEGtOZCmvztYEzUPxLNAt8g,2456
|
|
@@ -1240,11 +1241,11 @@ lightning_sdk/llm/llm.py,sha256=pjBs8fbGZjs0tQRKHx-WdfTmeECKAwI_T1ShVBgdyO4,2083
|
|
|
1240
1241
|
lightning_sdk/llm/public_assistants.py,sha256=k0yc41AyrKImnRa8Fv-ow9javnlrRQeP63507p2VybA,1579
|
|
1241
1242
|
lightning_sdk/mmt/__init__.py,sha256=ExMu90-96bGBnyp5h0CErQszUGB1-PcjC4-R8_NYbeY,117
|
|
1242
1243
|
lightning_sdk/mmt/base.py,sha256=fP5bcZewLgUCLTH82CTauKSH6J4994pS8ZuFnzzN9BI,16991
|
|
1243
|
-
lightning_sdk/mmt/mmt.py,sha256=
|
|
1244
|
+
lightning_sdk/mmt/mmt.py,sha256=LDXiPskJoZslEXapKE1WPIeczGAaOTP-RXZ1AgF68zw,15867
|
|
1244
1245
|
lightning_sdk/mmt/v1.py,sha256=PRyqgoHUlzZWsjUv2q8vHT00FxyCSqqVt5p5R9tu36s,9114
|
|
1245
1246
|
lightning_sdk/mmt/v2.py,sha256=iQOXb631M1zk63nJzomG-7fh0BLScZz98ndKjn4NMYo,11169
|
|
1246
1247
|
lightning_sdk/pipeline/__init__.py,sha256=Sja_0NJ8vgh-2ThSVP3WDI9a9qghrWd21LkaQp4Zsp8,378
|
|
1247
|
-
lightning_sdk/pipeline/pipeline.py,sha256=
|
|
1248
|
+
lightning_sdk/pipeline/pipeline.py,sha256=l9yZit7HVj8JyVFRWFGjeU4n6oG6J2f7MNEev650ONw,6346
|
|
1248
1249
|
lightning_sdk/pipeline/printer.py,sha256=fsewFE_nnI-x5KscviYvQbKgNcgMyn-uT0UWlArGn-8,4828
|
|
1249
1250
|
lightning_sdk/pipeline/schedule.py,sha256=J6lfjeuUMqGhX6xo6-qIliyi7KmB4e8BimTKJh7cJXY,20059
|
|
1250
1251
|
lightning_sdk/pipeline/steps.py,sha256=vo7pC4gmcx_xMfWwAIctBk39QCxzmbjvDVwWSnTswI4,14424
|
|
@@ -1262,9 +1263,9 @@ lightning_sdk/utils/logging.py,sha256=WPyOx7KAn8OpRKqoDDlB7MkORtLDryJsj1WVXLYNqy
|
|
|
1262
1263
|
lightning_sdk/utils/names.py,sha256=1EuXbIh7wldkDp1FG10oz9vIOyWrpGWeFFVy-DQBgzA,18162
|
|
1263
1264
|
lightning_sdk/utils/progress.py,sha256=bLWw39fzq29PMWoFXaPIVfoS3Ug245950oWOFJ2ZaiU,12596
|
|
1264
1265
|
lightning_sdk/utils/resolve.py,sha256=ukC-Zn35gNZV-fQ-ZyUgZkRPFb8nwsFh_aN7YcJ0sl8,10613
|
|
1265
|
-
lightning_sdk-2025.11.
|
|
1266
|
-
lightning_sdk-2025.11.
|
|
1267
|
-
lightning_sdk-2025.11.
|
|
1268
|
-
lightning_sdk-2025.11.
|
|
1269
|
-
lightning_sdk-2025.11.
|
|
1270
|
-
lightning_sdk-2025.11.
|
|
1266
|
+
lightning_sdk-2025.11.13.dist-info/LICENSE,sha256=uFIuZwj5z-4TeF2UuacPZ1o17HkvKObT8fY50qN84sg,1064
|
|
1267
|
+
lightning_sdk-2025.11.13.dist-info/METADATA,sha256=drF7S545973JTcSaLYX2usrmASxaJih4AB61RJGwsn8,4131
|
|
1268
|
+
lightning_sdk-2025.11.13.dist-info/WHEEL,sha256=iAkIy5fosb7FzIOwONchHf19Qu7_1wCWyFNR5gu9nU0,91
|
|
1269
|
+
lightning_sdk-2025.11.13.dist-info/entry_points.txt,sha256=OoZa4Fc8NMs6GSN0cdA1J8e6couzAcL82CbM1yo4f_M,122
|
|
1270
|
+
lightning_sdk-2025.11.13.dist-info/top_level.txt,sha256=ps8doKILFXmN7F1mHncShmnQoTxKBRPIcchC8TpoBw4,19
|
|
1271
|
+
lightning_sdk-2025.11.13.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|