lightning-sdk 2025.8.26__py3-none-any.whl → 2025.8.28__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/cli/studio/create.py +2 -1
- lightning_sdk/cli/studio/list.py +25 -10
- lightning_sdk/cli/studio/start.py +3 -2
- lightning_sdk/cli/studio/stop.py +2 -1
- lightning_sdk/cli/studio/switch.py +2 -1
- lightning_sdk/cli/utils/richt_print.py +24 -0
- lightning_sdk/studio.py +1 -0
- lightning_sdk/utils/resolve.py +11 -0
- {lightning_sdk-2025.8.26.dist-info → lightning_sdk-2025.8.28.dist-info}/METADATA +1 -1
- {lightning_sdk-2025.8.26.dist-info → lightning_sdk-2025.8.28.dist-info}/RECORD +15 -15
- {lightning_sdk-2025.8.26.dist-info → lightning_sdk-2025.8.28.dist-info}/LICENSE +0 -0
- {lightning_sdk-2025.8.26.dist-info → lightning_sdk-2025.8.28.dist-info}/WHEEL +0 -0
- {lightning_sdk-2025.8.26.dist-info → lightning_sdk-2025.8.28.dist-info}/entry_points.txt +0 -0
- {lightning_sdk-2025.8.26.dist-info → lightning_sdk-2025.8.28.dist-info}/top_level.txt +0 -0
lightning_sdk/__init__.py
CHANGED
|
@@ -4,6 +4,7 @@ from typing import Optional
|
|
|
4
4
|
|
|
5
5
|
import click
|
|
6
6
|
|
|
7
|
+
from lightning_sdk.cli.utils.richt_print import studio_name_link
|
|
7
8
|
from lightning_sdk.cli.utils.save_to_config import save_teamspace_to_config
|
|
8
9
|
from lightning_sdk.cli.utils.teamspace_selection import TeamspacesMenu
|
|
9
10
|
from lightning_sdk.lightning_cloud.openapi.rest import ApiException
|
|
@@ -56,4 +57,4 @@ def create_studio(
|
|
|
56
57
|
raise ValueError(f"Could not create Studio: '{name}'. Does the Studio exist?") from None
|
|
57
58
|
raise ValueError(f"Could not create Studio: '{name}'. Please provide a Studio name") from None
|
|
58
59
|
|
|
59
|
-
click.echo(f"Studio
|
|
60
|
+
click.echo(f"Studio {studio_name_link(studio)} created successfully")
|
lightning_sdk/cli/studio/list.py
CHANGED
|
@@ -6,21 +6,29 @@ import click
|
|
|
6
6
|
from rich.table import Table
|
|
7
7
|
|
|
8
8
|
from lightning_sdk.cli.utils.cloud_account_map import cloud_account_to_display_name
|
|
9
|
-
from lightning_sdk.cli.utils.richt_print import rich_to_str
|
|
9
|
+
from lightning_sdk.cli.utils.richt_print import rich_to_str, studio_name_link
|
|
10
10
|
from lightning_sdk.cli.utils.save_to_config import save_teamspace_to_config
|
|
11
11
|
from lightning_sdk.cli.utils.teamspace_selection import TeamspacesMenu
|
|
12
12
|
from lightning_sdk.studio import Studio
|
|
13
|
+
from lightning_sdk.utils.resolve import _get_authed_user, prevent_refetch_studio
|
|
13
14
|
|
|
14
15
|
|
|
15
16
|
@click.command("list")
|
|
16
17
|
@click.option("--teamspace", help="Override default teamspace (format: owner/teamspace)")
|
|
18
|
+
@click.option(
|
|
19
|
+
"--all",
|
|
20
|
+
is_flag=True,
|
|
21
|
+
flag_value=True,
|
|
22
|
+
default=False,
|
|
23
|
+
help="List all studios, not just the ones belonging to the authed user",
|
|
24
|
+
)
|
|
17
25
|
@click.option(
|
|
18
26
|
"--sort-by",
|
|
19
27
|
default=None,
|
|
20
28
|
type=click.Choice(["name", "teamspace", "status", "machine", "cloud-account"], case_sensitive=False),
|
|
21
29
|
help="the attribute to sort the studios by.",
|
|
22
30
|
)
|
|
23
|
-
def list_studios(teamspace: Optional[str] = None, sort_by: Optional[str] = None) -> None:
|
|
31
|
+
def list_studios(teamspace: Optional[str] = None, all: bool = False, sort_by: Optional[str] = None) -> None: # noqa: A002
|
|
24
32
|
"""List Studios in a teamspace.
|
|
25
33
|
|
|
26
34
|
Example:
|
|
@@ -31,6 +39,8 @@ def list_studios(teamspace: Optional[str] = None, sort_by: Optional[str] = None)
|
|
|
31
39
|
teamspace_resolved = menu(teamspace=teamspace)
|
|
32
40
|
save_teamspace_to_config(teamspace_resolved, overwrite=False)
|
|
33
41
|
|
|
42
|
+
user = _get_authed_user()
|
|
43
|
+
|
|
34
44
|
studios = teamspace_resolved.studios
|
|
35
45
|
|
|
36
46
|
table = Table(
|
|
@@ -42,14 +52,19 @@ def list_studios(teamspace: Optional[str] = None, sort_by: Optional[str] = None)
|
|
|
42
52
|
table.add_column("Machine")
|
|
43
53
|
table.add_column("Cloud account")
|
|
44
54
|
|
|
45
|
-
for studio in sorted(
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
55
|
+
for studio in sorted(
|
|
56
|
+
filter(lambda s: all or s._studio.user_id == user.id, studios), key=_sort_studios_key(sort_by)
|
|
57
|
+
):
|
|
58
|
+
with prevent_refetch_studio(studio):
|
|
59
|
+
table.add_row(
|
|
60
|
+
# cannot convert to ascii here, as the final rich table has to be converted to ascii
|
|
61
|
+
# otherwise the lack of support for linking in some terminals causes formatting issues.
|
|
62
|
+
studio_name_link(studio, to_ascii=False),
|
|
63
|
+
f"{studio.teamspace.owner.name}/{studio.teamspace.name}",
|
|
64
|
+
str(studio.status),
|
|
65
|
+
str(studio.machine) if studio.machine is not None else None, # when None the cell is empty
|
|
66
|
+
str(cloud_account_to_display_name(studio.cloud_account, studio.teamspace.id)),
|
|
67
|
+
)
|
|
53
68
|
|
|
54
69
|
click.echo(rich_to_str(table), color=True)
|
|
55
70
|
|
|
@@ -4,6 +4,7 @@ from typing import Optional
|
|
|
4
4
|
|
|
5
5
|
import click
|
|
6
6
|
|
|
7
|
+
from lightning_sdk.cli.utils.richt_print import studio_name_link
|
|
7
8
|
from lightning_sdk.cli.utils.save_to_config import save_studio_to_config
|
|
8
9
|
from lightning_sdk.cli.utils.studio_selection import StudiosMenu
|
|
9
10
|
from lightning_sdk.cli.utils.teamspace_selection import TeamspacesMenu
|
|
@@ -45,7 +46,7 @@ def start_studio(
|
|
|
45
46
|
name: Optional[str] = None,
|
|
46
47
|
teamspace: Optional[str] = None,
|
|
47
48
|
create: bool = False,
|
|
48
|
-
machine:
|
|
49
|
+
machine: str = "CPU",
|
|
49
50
|
interruptible: bool = False,
|
|
50
51
|
cloud_provider: Optional[str] = None,
|
|
51
52
|
cloud_account: Optional[str] = None,
|
|
@@ -78,4 +79,4 @@ def start_studio(
|
|
|
78
79
|
|
|
79
80
|
Studio.show_progress = True
|
|
80
81
|
studio.start(machine, interruptible=interruptible)
|
|
81
|
-
click.echo(f"Studio
|
|
82
|
+
click.echo(f"Studio {studio_name_link(studio)} started successfully")
|
lightning_sdk/cli/studio/stop.py
CHANGED
|
@@ -4,6 +4,7 @@ from typing import Optional
|
|
|
4
4
|
|
|
5
5
|
import click
|
|
6
6
|
|
|
7
|
+
from lightning_sdk.cli.utils.richt_print import studio_name_link
|
|
7
8
|
from lightning_sdk.cli.utils.save_to_config import save_studio_to_config
|
|
8
9
|
from lightning_sdk.cli.utils.studio_selection import StudiosMenu
|
|
9
10
|
from lightning_sdk.cli.utils.teamspace_selection import TeamspacesMenu
|
|
@@ -37,4 +38,4 @@ def stop_studio(name: Optional[str] = None, teamspace: Optional[str] = None) ->
|
|
|
37
38
|
|
|
38
39
|
save_studio_to_config(studio)
|
|
39
40
|
|
|
40
|
-
click.echo(f"Studio
|
|
41
|
+
click.echo(f"Studio {studio_name_link(studio)} stopped successfully")
|
|
@@ -4,6 +4,7 @@ from typing import Optional
|
|
|
4
4
|
|
|
5
5
|
import click
|
|
6
6
|
|
|
7
|
+
from lightning_sdk.cli.utils.richt_print import studio_name_link
|
|
7
8
|
from lightning_sdk.cli.utils.save_to_config import save_studio_to_config
|
|
8
9
|
from lightning_sdk.cli.utils.studio_selection import StudiosMenu
|
|
9
10
|
from lightning_sdk.cli.utils.teamspace_selection import TeamspacesMenu
|
|
@@ -46,4 +47,4 @@ def switch_studio(
|
|
|
46
47
|
|
|
47
48
|
save_studio_to_config(studio)
|
|
48
49
|
|
|
49
|
-
click.echo(f"Studio
|
|
50
|
+
click.echo(f"Studio {studio_name_link(studio)} switched to machine '{resolved_machine}' successfully")
|
|
@@ -3,9 +3,33 @@ from typing import Any
|
|
|
3
3
|
|
|
4
4
|
from rich.console import Console
|
|
5
5
|
|
|
6
|
+
from lightning_sdk.studio import Studio
|
|
7
|
+
from lightning_sdk.utils.resolve import _get_studio_url
|
|
8
|
+
|
|
6
9
|
|
|
7
10
|
def rich_to_str(*renderables: Any) -> str:
|
|
8
11
|
with open(os.devnull, "w") as f:
|
|
9
12
|
console = Console(file=f, record=True)
|
|
10
13
|
console.print(*renderables)
|
|
11
14
|
return console.export_text(styles=True)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
# not supported on all terminals (e.g. older ones). in that case it's a name without a link
|
|
18
|
+
# see https://gist.github.com/egmontkob/eb114294efbcd5adb1944c9f3cb5feda#hyperlinks-aka-html-like-anchors-in-terminal-emulators
|
|
19
|
+
# for details and
|
|
20
|
+
# https://github.com/Alhadis/OSC8-Adoption/blob/main/README.md for status of OSC8 adoption
|
|
21
|
+
def studio_name_link(studio: Studio, to_ascii: bool = True) -> str:
|
|
22
|
+
"""Hyperlink a studio name.
|
|
23
|
+
|
|
24
|
+
Args:
|
|
25
|
+
studio: the studio whose name to print and link to the studio url
|
|
26
|
+
to_ascii: whether return a plain ascii string with characters for linking converted to ascii as well.
|
|
27
|
+
if False, returns the rich markup directly.
|
|
28
|
+
"""
|
|
29
|
+
url = _get_studio_url(studio)
|
|
30
|
+
|
|
31
|
+
studio_link_markup = f"[link={url}]{studio.name}[/link]"
|
|
32
|
+
if not to_ascii:
|
|
33
|
+
return studio_link_markup
|
|
34
|
+
|
|
35
|
+
return rich_to_str(studio_link_markup).strip("\n")
|
lightning_sdk/studio.py
CHANGED
lightning_sdk/utils/resolve.py
CHANGED
|
@@ -265,6 +265,17 @@ def skip_studio_setup() -> Generator[None, None, None]:
|
|
|
265
265
|
Studio._skip_setup.value = prev_studio_setup_state
|
|
266
266
|
|
|
267
267
|
|
|
268
|
+
@contextmanager
|
|
269
|
+
def prevent_refetch_studio(studio: "Studio") -> Generator[None, None, None]:
|
|
270
|
+
"""Prevent refetching the studio based on current runtime."""
|
|
271
|
+
prev_prevent_refetch_state = getattr(studio, "_prevent_refetch", False)
|
|
272
|
+
studio._prevent_refetch = True
|
|
273
|
+
|
|
274
|
+
yield
|
|
275
|
+
|
|
276
|
+
studio._prevent_refetch = prev_prevent_refetch_state
|
|
277
|
+
|
|
278
|
+
|
|
268
279
|
def _parse_model_and_version(name: str) -> Tuple[str, Optional[str]]:
|
|
269
280
|
"""Parse the model name and version from the given string.
|
|
270
281
|
|
|
@@ -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=m4U-y4445WQpSE8meItjnzJIFiwx7THsNgH8aGqqAU4,1145
|
|
3
3
|
lightning_sdk/agents.py,sha256=ly6Ma1j0ZgGPFyvPvMN28JWiB9dATIstFa5XM8pMi6I,1577
|
|
4
4
|
lightning_sdk/ai_hub.py,sha256=iI1vNhgcz_Ff1c3rN1ogN7dK-r-HXRj6NMtS2cA14UA,6925
|
|
5
5
|
lightning_sdk/base_studio.py,sha256=_Pwwl37R9GRd7t-f2kO5aQXiLNrP4sUtUNht2ZkP8LE,3678
|
|
@@ -14,7 +14,7 @@ lightning_sdk/plugin.py,sha256=f3P5-xZY6x-MX0Fs2z_Q2erSxPSiHZARO0BVkCezHw4,15192
|
|
|
14
14
|
lightning_sdk/sandbox.py,sha256=_NvnWotEXW2rBiVFZZ4krKXxVjuAqfNh04qELSM0-Pg,5786
|
|
15
15
|
lightning_sdk/serve.py,sha256=uW7zLhQ3X90ifetpxzTb8FNxifv5vIs7qZlgfEjVKzk,11794
|
|
16
16
|
lightning_sdk/status.py,sha256=lLGAuSvXBoXQFEEsEYwdCi0RcSNatUn5OPjJVjDtoM0,386
|
|
17
|
-
lightning_sdk/studio.py,sha256=
|
|
17
|
+
lightning_sdk/studio.py,sha256=N6qxQMJXnaXJK8NXeRxdVg-4az63Tp8eMc-RvfhT8_o,30366
|
|
18
18
|
lightning_sdk/teamspace.py,sha256=qYpIYgg3eyWj9vcqdfhQN-YCpS47tOc_xB3de07p4Y8,21630
|
|
19
19
|
lightning_sdk/user.py,sha256=TSYh38rxoi7qKOfrK2JYh_Nknya2Kbz2ngDIY85fFOY,1778
|
|
20
20
|
lightning_sdk/api/__init__.py,sha256=Qn2VVRvir_gO7w4yxGLkZY-R3T7kdiTPKgQ57BhIA9k,413
|
|
@@ -73,18 +73,18 @@ lightning_sdk/cli/legacy/deploy/devbox.py,sha256=SdOtYdGefzldn-WCa6sz31zysyf2nP5
|
|
|
73
73
|
lightning_sdk/cli/legacy/deploy/serve.py,sha256=bxN04mHlArjHtxR_QkCM0S_RPmL3WIPsgnPgFadSXwI,15478
|
|
74
74
|
lightning_sdk/cli/mmt/__init__.py,sha256=CLgr-ZHHLS6Db_JGqpxbn4G2pYrKi4Qn-uhi8e0kFNc,145
|
|
75
75
|
lightning_sdk/cli/studio/__init__.py,sha256=Reb5a0iHJfNMxmnP30DAmYqpJ-YDQoJcgyVrD2cYDNo,823
|
|
76
|
-
lightning_sdk/cli/studio/create.py,sha256=
|
|
76
|
+
lightning_sdk/cli/studio/create.py,sha256=MK0OzRV81QgBSxmkQy6YVBJc1cOzq9FSTL2NG5KGI5A,2071
|
|
77
77
|
lightning_sdk/cli/studio/delete.py,sha256=rzvzNviu9NVeITnCD84PzEEoizrggcq78yaOqrT6U_U,1289
|
|
78
|
-
lightning_sdk/cli/studio/list.py,sha256=
|
|
78
|
+
lightning_sdk/cli/studio/list.py,sha256=FUt1SI-uDBWh-ghPFxQZAoxkVdQspGNhy33nkVhdB_o,3079
|
|
79
79
|
lightning_sdk/cli/studio/ssh.py,sha256=Qlwyl4LISCzFYedhkXArTHqipl_6Yazq7vRcrsc_2ws,3654
|
|
80
|
-
lightning_sdk/cli/studio/start.py,sha256=
|
|
81
|
-
lightning_sdk/cli/studio/stop.py,sha256=
|
|
82
|
-
lightning_sdk/cli/studio/switch.py,sha256=
|
|
80
|
+
lightning_sdk/cli/studio/start.py,sha256=KuJDwwTnWMhhuihF9qNbcIXa_VPzPH_A8zz-Gck1sn0,2695
|
|
81
|
+
lightning_sdk/cli/studio/stop.py,sha256=d-54OzDYYiY5VNlwIK4oryCH8aafJ7RRBG-ARhcFc4o,1235
|
|
82
|
+
lightning_sdk/cli/studio/switch.py,sha256=qhWhLvjk-BbwU8Br3rXPQIMVQLTUTq21f0v2P-R8VfQ,1745
|
|
83
83
|
lightning_sdk/cli/utils/__init__.py,sha256=0gHdWY3bqrIyiFiEh_uSBuxWpOykCjqUc8fPEV0z3no,186
|
|
84
84
|
lightning_sdk/cli/utils/cloud_account_map.py,sha256=7oM7ns4ZJfkxxZhl-GMkxEkkinKbVkskx5dLcyEQiz4,414
|
|
85
85
|
lightning_sdk/cli/utils/coloring.py,sha256=YEb1LiYb6CekVfCRb83-npAmNgd-7c1LzXuNDo4GLSc,2415
|
|
86
86
|
lightning_sdk/cli/utils/resolve.py,sha256=RWQ8MgXEJCdsoY50y8Pa9B-A6NA_SvxOqL5pVKfvSr8,917
|
|
87
|
-
lightning_sdk/cli/utils/richt_print.py,sha256=
|
|
87
|
+
lightning_sdk/cli/utils/richt_print.py,sha256=psSY65nLAQbxK_K0w93Qq9857aUUbm77FLS1sc3Oecg,1262
|
|
88
88
|
lightning_sdk/cli/utils/save_to_config.py,sha256=mMjjfA4Yv1e7MtE03iADTXcTSAuUL0Ws9OZObx6ufo0,1164
|
|
89
89
|
lightning_sdk/cli/utils/studio_selection.py,sha256=tjYTm4sY3NSQaa-6Ob9R0UQ60wIXiTNT2406BUJvJbU,3927
|
|
90
90
|
lightning_sdk/cli/utils/teamspace_selection.py,sha256=ZWo_aZuEuLzBWRgQEykypEM1sE_deDKLDcCyLgFWaaQ,5188
|
|
@@ -1143,10 +1143,10 @@ lightning_sdk/utils/dynamic.py,sha256=glUTO1JC9APtQ6Gr9SO02a3zr56-sPAXM5C3NrTpgy
|
|
|
1143
1143
|
lightning_sdk/utils/enum.py,sha256=h2JRzqoBcSlUdanFHmkj_j5DleBHAu1esQYUsdNI-hU,4106
|
|
1144
1144
|
lightning_sdk/utils/names.py,sha256=1EuXbIh7wldkDp1FG10oz9vIOyWrpGWeFFVy-DQBgzA,18162
|
|
1145
1145
|
lightning_sdk/utils/progress.py,sha256=IXfEcUF-rL5jIw0Hir6eSxN7VBZfR--1O2LaEhGAU70,12698
|
|
1146
|
-
lightning_sdk/utils/resolve.py,sha256=
|
|
1147
|
-
lightning_sdk-2025.8.
|
|
1148
|
-
lightning_sdk-2025.8.
|
|
1149
|
-
lightning_sdk-2025.8.
|
|
1150
|
-
lightning_sdk-2025.8.
|
|
1151
|
-
lightning_sdk-2025.8.
|
|
1152
|
-
lightning_sdk-2025.8.
|
|
1146
|
+
lightning_sdk/utils/resolve.py,sha256=4TyEnIgIrvkSvYk5i5PmcIogD_5Y9pBhiphRLfLMttc,10477
|
|
1147
|
+
lightning_sdk-2025.8.28.dist-info/LICENSE,sha256=uFIuZwj5z-4TeF2UuacPZ1o17HkvKObT8fY50qN84sg,1064
|
|
1148
|
+
lightning_sdk-2025.8.28.dist-info/METADATA,sha256=LLjYF3GZy05IhP4gHBgNfKxuZUMtAB-ujgvYzTEuT9o,4130
|
|
1149
|
+
lightning_sdk-2025.8.28.dist-info/WHEEL,sha256=iAkIy5fosb7FzIOwONchHf19Qu7_1wCWyFNR5gu9nU0,91
|
|
1150
|
+
lightning_sdk-2025.8.28.dist-info/entry_points.txt,sha256=msB9PJWIJ784dX-OP8by51d4IbKYH3Fj1vCuA9oXjHY,68
|
|
1151
|
+
lightning_sdk-2025.8.28.dist-info/top_level.txt,sha256=ps8doKILFXmN7F1mHncShmnQoTxKBRPIcchC8TpoBw4,19
|
|
1152
|
+
lightning_sdk-2025.8.28.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|