lightning-sdk 2025.8.14.post0__py3-none-any.whl → 2025.8.18.post0__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.
Files changed (69) hide show
  1. lightning_sdk/__init__.py +1 -1
  2. lightning_sdk/api/cloud_account_api.py +5 -0
  3. lightning_sdk/cli/__init__.py +1 -0
  4. lightning_sdk/cli/config/__init__.py +14 -0
  5. lightning_sdk/cli/config/get.py +57 -0
  6. lightning_sdk/cli/config/set.py +104 -0
  7. lightning_sdk/cli/config/show.py +9 -0
  8. lightning_sdk/cli/entrypoint.py +60 -41
  9. lightning_sdk/cli/groups.py +35 -0
  10. lightning_sdk/cli/job/__init__.py +7 -0
  11. lightning_sdk/cli/{configure.py → legacy/configure.py} +2 -2
  12. lightning_sdk/cli/{connect.py → legacy/connect.py} +2 -2
  13. lightning_sdk/cli/{create.py → legacy/create.py} +1 -1
  14. lightning_sdk/cli/{delete.py → legacy/delete.py} +3 -3
  15. lightning_sdk/cli/legacy/deploy/__init__.py +0 -0
  16. lightning_sdk/cli/{deploy → legacy/deploy}/_auth.py +1 -1
  17. lightning_sdk/cli/{deploy → legacy/deploy}/devbox.py +8 -2
  18. lightning_sdk/cli/{deploy → legacy/deploy}/serve.py +3 -3
  19. lightning_sdk/cli/{download.py → legacy/download.py} +3 -3
  20. lightning_sdk/cli/legacy/entrypoint.py +110 -0
  21. lightning_sdk/cli/{generate.py → legacy/generate.py} +1 -1
  22. lightning_sdk/cli/{inspection.py → legacy/inspection.py} +1 -1
  23. lightning_sdk/cli/{job_and_mmt_action.py → legacy/job_and_mmt_action.py} +3 -3
  24. lightning_sdk/cli/{jobs_menu.py → legacy/jobs_menu.py} +1 -1
  25. lightning_sdk/cli/{list.py → legacy/list.py} +2 -2
  26. lightning_sdk/cli/{mmts_menu.py → legacy/mmts_menu.py} +1 -1
  27. lightning_sdk/cli/{open.py → legacy/open.py} +2 -2
  28. lightning_sdk/cli/{stop.py → legacy/stop.py} +1 -1
  29. lightning_sdk/cli/{teamspace_menu.py → legacy/teamspace_menu.py} +1 -1
  30. lightning_sdk/cli/{upload.py → legacy/upload.py} +3 -3
  31. lightning_sdk/cli/mmt/__init__.py +7 -0
  32. lightning_sdk/cli/studio/__init__.py +22 -0
  33. lightning_sdk/cli/studio/create.py +68 -0
  34. lightning_sdk/cli/studio/delete.py +44 -0
  35. lightning_sdk/cli/studio/list.py +67 -0
  36. lightning_sdk/cli/studio/ssh.py +112 -0
  37. lightning_sdk/cli/studio/start.py +81 -0
  38. lightning_sdk/cli/studio/stop.py +44 -0
  39. lightning_sdk/cli/studio/switch.py +52 -0
  40. lightning_sdk/cli/utils/__init__.py +7 -0
  41. lightning_sdk/cli/utils/cloud_account_map.py +10 -0
  42. lightning_sdk/cli/utils/resolve.py +28 -0
  43. lightning_sdk/cli/utils/richt_print.py +11 -0
  44. lightning_sdk/lightning_cloud/openapi/api/billing_service_api.py +5 -1
  45. lightning_sdk/lightning_cloud/openapi/api/k8_s_cluster_service_api.py +117 -0
  46. lightning_sdk/lightning_cloud/openapi/models/v1_managed_model.py +29 -3
  47. lightning_sdk/lightning_cloud/openapi/models/v1_notification_type.py +1 -0
  48. lightning_sdk/lightning_cloud/openapi/models/v1_user_features.py +1 -27
  49. lightning_sdk/lightning_cloud/utils/data_connection.py +51 -1
  50. lightning_sdk/studio.py +17 -5
  51. lightning_sdk/teamspace.py +14 -0
  52. lightning_sdk/utils/config.py +158 -0
  53. lightning_sdk/utils/resolve.py +49 -3
  54. {lightning_sdk-2025.8.14.post0.dist-info → lightning_sdk-2025.8.18.post0.dist-info}/METADATA +2 -1
  55. {lightning_sdk-2025.8.14.post0.dist-info → lightning_sdk-2025.8.18.post0.dist-info}/RECORD +69 -47
  56. /lightning_sdk/cli/{deploy → legacy}/__init__.py +0 -0
  57. /lightning_sdk/cli/{ai_hub.py → legacy/ai_hub.py} +0 -0
  58. /lightning_sdk/cli/{clusters_menu.py → legacy/clusters_menu.py} +0 -0
  59. /lightning_sdk/cli/{docker_cli.py → legacy/docker_cli.py} +0 -0
  60. /lightning_sdk/cli/{exceptions.py → legacy/exceptions.py} +0 -0
  61. /lightning_sdk/cli/{run.py → legacy/run.py} +0 -0
  62. /lightning_sdk/cli/{start.py → legacy/start.py} +0 -0
  63. /lightning_sdk/cli/{studios_menu.py → legacy/studios_menu.py} +0 -0
  64. /lightning_sdk/cli/{switch.py → legacy/switch.py} +0 -0
  65. /lightning_sdk/cli/{coloring.py → utils/coloring.py} +0 -0
  66. {lightning_sdk-2025.8.14.post0.dist-info → lightning_sdk-2025.8.18.post0.dist-info}/LICENSE +0 -0
  67. {lightning_sdk-2025.8.14.post0.dist-info → lightning_sdk-2025.8.18.post0.dist-info}/WHEEL +0 -0
  68. {lightning_sdk-2025.8.14.post0.dist-info → lightning_sdk-2025.8.18.post0.dist-info}/entry_points.txt +0 -0
  69. {lightning_sdk-2025.8.14.post0.dist-info → lightning_sdk-2025.8.18.post0.dist-info}/top_level.txt +0 -0
lightning_sdk/__init__.py CHANGED
@@ -32,6 +32,6 @@ __all__ = [
32
32
  "User",
33
33
  ]
34
34
 
35
- __version__ = "2025.08.14.post0"
35
+ __version__ = "2025.08.18.post0"
36
36
  _check_version_and_prompt_upgrade(__version__)
37
37
  _set_tqdm_envvars_noninteractive()
@@ -181,6 +181,11 @@ class CloudAccountApi:
181
181
  cloud_provider: Optional[Union["CloudProvider", str]],
182
182
  default_cloud_account: Optional[str],
183
183
  ) -> Optional[str]:
184
+ from lightning_sdk.machine import CloudProvider
185
+
186
+ if cloud_provider and not isinstance(cloud_provider, CloudProvider):
187
+ cloud_provider = CloudProvider(cloud_provider)
188
+
184
189
  if cloud_account:
185
190
  if cloud_provider:
186
191
  cloud_account_resp = self.get_cloud_account_non_org(teamspace_id, cloud_account)
@@ -0,0 +1 @@
1
+ """Lightning SDK CLI module."""
@@ -0,0 +1,14 @@
1
+ """Config CLI commands."""
2
+
3
+ import click
4
+
5
+
6
+ def register_commands(group: click.Group) -> None:
7
+ """Register config commands with the given group."""
8
+ from lightning_sdk.cli.config.get import get
9
+ from lightning_sdk.cli.config.set import set_value
10
+ from lightning_sdk.cli.config.show import show
11
+
12
+ group.add_command(get)
13
+ group.add_command(set_value)
14
+ group.add_command(show)
@@ -0,0 +1,57 @@
1
+ import click
2
+
3
+ from lightning_sdk.utils.config import Config, DefaultConfigKeys
4
+
5
+
6
+ @click.group("get")
7
+ def get() -> None:
8
+ """Get configuration values."""
9
+
10
+
11
+ @get.command("user")
12
+ def get_user() -> None:
13
+ """Get the default user name from the config."""
14
+ config = Config()
15
+ user = config.get_value(DefaultConfigKeys.user)
16
+ click.echo(user)
17
+
18
+
19
+ @get.command("org")
20
+ def get_org() -> None:
21
+ """Get the default organization name from the config."""
22
+ config = Config()
23
+ org = config.get_value(DefaultConfigKeys.organization)
24
+ click.echo(org)
25
+
26
+
27
+ @get.command("teamspace")
28
+ def get_teamspace() -> None:
29
+ """Get the default teamspace name from the config."""
30
+ config = Config()
31
+ teamspace_name = config.get_value(DefaultConfigKeys.teamspace_name)
32
+ teamspace_owner = config.get_value(DefaultConfigKeys.teamspace_owner)
33
+ click.echo(f"{teamspace_owner}/{teamspace_name}")
34
+
35
+
36
+ @get.command("studio")
37
+ def get_studio() -> None:
38
+ """Get the default sutdio name from the config."""
39
+ config = Config()
40
+ studio = config.get_value(DefaultConfigKeys.studio)
41
+ click.echo(studio)
42
+
43
+
44
+ @get.command("cloud-account")
45
+ def get_cloud_account() -> None:
46
+ """Get the default cloud account name from the config."""
47
+ config = Config()
48
+ cloud_account = config.get_value(DefaultConfigKeys.cloud_account)
49
+ click.echo(cloud_account)
50
+
51
+
52
+ @get.command("cloud-provider")
53
+ def get_cloud_provider() -> None:
54
+ """Get the default cloud provider name from the config."""
55
+ config = Config()
56
+ cloud_provider = config.get_value(DefaultConfigKeys.cloud_provider)
57
+ click.echo(cloud_provider)
@@ -0,0 +1,104 @@
1
+ import click
2
+
3
+ from lightning_sdk.cli.utils.resolve import resolve_teamspace_owner_name_format
4
+ from lightning_sdk.machine import CloudProvider
5
+ from lightning_sdk.organization import Organization
6
+ from lightning_sdk.studio import Studio
7
+ from lightning_sdk.utils.config import Config, DefaultConfigKeys
8
+ from lightning_sdk.utils.resolve import _resolve_org, _resolve_user
9
+
10
+
11
+ @click.group("set")
12
+ def set_value() -> None:
13
+ """Set configuration values."""
14
+
15
+
16
+ @set_value.command("user")
17
+ @click.argument("user_name")
18
+ def set_user(user_name: str) -> None:
19
+ """Set the default user name in the config."""
20
+ try:
21
+ _resolve_user(user_name)
22
+ except Exception:
23
+ # TODO: make this a generic CLI error
24
+ raise ValueError(f"Could not resolve user: '{user_name}'. Does the user exist?") from None
25
+
26
+ config = Config()
27
+ setattr(config, DefaultConfigKeys.user, user_name)
28
+
29
+
30
+ @set_value.command("org")
31
+ @click.argument("org_name")
32
+ def set_org(org_name: str) -> None:
33
+ """Set the default organization name in the config."""
34
+ try:
35
+ _resolve_org(org_name)
36
+ except Exception:
37
+ # TODO: make this a generic CLI error
38
+ raise ValueError(f"Could not resolve organization: '{org_name}'. Does the organization exist?") from None
39
+
40
+ config = Config()
41
+ setattr(config, DefaultConfigKeys.organization, org_name)
42
+
43
+
44
+ @set_value.command("studio")
45
+ @click.argument("studio_name")
46
+ def set_studio(studio_name: str) -> None:
47
+ """Set the default studio name in the config."""
48
+ try:
49
+ studio = Studio(studio_name)
50
+ except Exception:
51
+ # TODO: make this a generic CLI error
52
+ raise ValueError(f"Could not resolve studio: '{studio_name}'. Does the studio exist?") from None
53
+
54
+ config = Config()
55
+ setattr(config, DefaultConfigKeys.studio, studio.name)
56
+
57
+
58
+ @set_value.command("teamspace")
59
+ @click.argument("teamspace_name")
60
+ def set_teamspace(teamspace_name: str) -> None:
61
+ """Set the default teamspace name in the config."""
62
+ config = Config()
63
+
64
+ teamspace_resolved = resolve_teamspace_owner_name_format(teamspace_name)
65
+
66
+ if teamspace_resolved is None:
67
+ # TODO: make this a generic CLI error
68
+ raise ValueError(
69
+ f"Could not resolve teamspace: '{teamspace_name}'. "
70
+ "Teamspace should be specified as 'owner/name'. Does the teamspace exist?"
71
+ )
72
+
73
+ setattr(config, DefaultConfigKeys.teamspace_name, teamspace_resolved.name)
74
+ setattr(config, DefaultConfigKeys.teamspace_owner, teamspace_resolved.owner.name)
75
+ if isinstance(teamspace_resolved.owner, Organization):
76
+ setattr(config, DefaultConfigKeys.teamspace_owner_type, "organization")
77
+ else:
78
+ setattr(config, DefaultConfigKeys.teamspace_owner_type, "user")
79
+
80
+
81
+ @set_value.command("cloud-account")
82
+ @click.argument("cloud_account_name")
83
+ def set_cloud_account(cloud_account_name: str) -> None:
84
+ """Set the default cloud account name in the config."""
85
+ config = Config()
86
+ setattr(config, DefaultConfigKeys.cloud_account, cloud_account_name)
87
+
88
+
89
+ @set_value.command("cloud-provider")
90
+ @click.argument("cloud_provider_name")
91
+ def set_cloud_provider(cloud_provider_name: str) -> None:
92
+ """Set the default cloud provider name in the config."""
93
+ config = Config()
94
+
95
+ try:
96
+ cloud_provider = CloudProvider(cloud_provider_name)
97
+ except ValueError:
98
+ # TODO: make this a generic CLI error
99
+ raise ValueError(
100
+ f"Could not resolve cloud provider: '{cloud_provider_name}'. "
101
+ f"Supported values are: {', '.join(m.name for m in list(CloudProvider))}"
102
+ ) from None
103
+
104
+ setattr(config, DefaultConfigKeys.cloud_provider, cloud_provider.name)
@@ -0,0 +1,9 @@
1
+ import click
2
+
3
+ from lightning_sdk.utils.config import Config
4
+
5
+
6
+ @click.command("show")
7
+ def show() -> None:
8
+ """Show configuration values."""
9
+ click.echo(Config())
@@ -1,42 +1,34 @@
1
+ """New Lightning CLI entrypoint with organized command groups."""
2
+
3
+ import os
1
4
  import sys
2
5
  import traceback
3
6
  from types import TracebackType
4
7
  from typing import Type
5
8
 
6
9
  import click
7
- from rich.console import Console, Group
10
+ from rich.console import Group
8
11
  from rich.panel import Panel
9
12
  from rich.syntax import Syntax
10
13
  from rich.text import Text
11
14
 
12
15
  from lightning_sdk import __version__
13
16
  from lightning_sdk.api.studio_api import _cloud_url
14
- from lightning_sdk.cli.ai_hub import aihub
15
- from lightning_sdk.cli.coloring import CustomHelpFormatter
16
- from lightning_sdk.cli.configure import configure
17
- from lightning_sdk.cli.connect import connect
18
- from lightning_sdk.cli.create import create
19
- from lightning_sdk.cli.delete import delete
20
- from lightning_sdk.cli.deploy.serve import deploy
21
- from lightning_sdk.cli.docker_cli import dockerize
22
- from lightning_sdk.cli.download import download
23
- from lightning_sdk.cli.generate import generate
24
- from lightning_sdk.cli.inspection import inspect
25
- from lightning_sdk.cli.list import list_cli
26
- from lightning_sdk.cli.open import open
27
- from lightning_sdk.cli.run import run
28
- from lightning_sdk.cli.start import start
29
- from lightning_sdk.cli.stop import stop
30
- from lightning_sdk.cli.switch import switch
31
- from lightning_sdk.cli.upload import upload
17
+
18
+ # Import legacy groups directly from groups.py
19
+ from lightning_sdk.cli.groups import (
20
+ config,
21
+ # job,
22
+ # mmt,
23
+ studio,
24
+ )
25
+ from lightning_sdk.cli.utils import CustomHelpFormatter, rich_to_str
32
26
  from lightning_sdk.constants import _LIGHTNING_DEBUG
33
27
  from lightning_sdk.lightning_cloud.login import Auth
34
28
 
35
29
 
36
30
  def _notify_exception(exception_type: Type[BaseException], value: BaseException, tb: TracebackType) -> None:
37
31
  """CLI won't show tracebacks, just print the exception message."""
38
- console = Console()
39
-
40
32
  message = str(value.args[0]) if value.args else str(value) or "An unknown error occurred"
41
33
 
42
34
  error_text = Text()
@@ -54,7 +46,8 @@ def _notify_exception(exception_type: Type[BaseException], value: BaseException,
54
46
 
55
47
  renderables.append(Text("\n📘 Need help? Run: lightning <command> --help", style="cyan"))
56
48
 
57
- console.print(Panel(Group(*renderables), title="⚡ Lightning CLI Error", border_style="red"))
49
+ text = rich_to_str(Panel(Group(*renderables), title="⚡ Lightning CLI Error", border_style="red"))
50
+ click.echo(text, color=True)
58
51
 
59
52
 
60
53
  @click.group(name="lightning", help="Command line interface (CLI) to interact with/manage Lightning AI Studios.")
@@ -63,7 +56,6 @@ def main_cli() -> None:
63
56
  sys.excepthook = _notify_exception
64
57
 
65
58
 
66
- # colorful help messages
67
59
  main_cli.context_class.formatter_class = CustomHelpFormatter
68
60
 
69
61
 
@@ -86,24 +78,51 @@ def logout() -> None:
86
78
  auth.clear()
87
79
 
88
80
 
89
- # additional commands
90
- main_cli.add_command(aihub)
91
- main_cli.add_command(configure)
92
- main_cli.add_command(connect)
93
- main_cli.add_command(create)
94
- main_cli.add_command(delete)
95
- main_cli.add_command(dockerize)
96
- main_cli.add_command(download)
97
- main_cli.add_command(generate)
98
- main_cli.add_command(inspect)
99
- main_cli.add_command(list_cli)
100
- main_cli.add_command(run)
101
- main_cli.add_command(deploy)
102
- main_cli.add_command(start)
103
- main_cli.add_command(stop)
104
- main_cli.add_command(switch)
105
- main_cli.add_command(upload)
106
- main_cli.add_command(open)
81
+ # Add new command groups
82
+ main_cli.add_command(config)
83
+ # main_cli.add_command(job)
84
+ # main_cli.add_command(mmt)
85
+ main_cli.add_command(studio)
86
+ if os.environ.get("LIGHTNING_EXPERIMENTAL_CLI_ONLY", "0") != "1":
87
+ #### LEGACY COMMANDS ####
88
+ # these commands are currently supported for backwards compatibility, but will potentially be removed in the future.
89
+ # they've grown pretty wild and provide a very inconsistent UX.
90
+ from lightning_sdk.cli.legacy.ai_hub import aihub
91
+ from lightning_sdk.cli.legacy.configure import configure
92
+ from lightning_sdk.cli.legacy.connect import connect
93
+ from lightning_sdk.cli.legacy.create import create
94
+ from lightning_sdk.cli.legacy.delete import delete
95
+ from lightning_sdk.cli.legacy.deploy.serve import deploy
96
+ from lightning_sdk.cli.legacy.docker_cli import dockerize
97
+ from lightning_sdk.cli.legacy.download import download
98
+ from lightning_sdk.cli.legacy.generate import generate
99
+ from lightning_sdk.cli.legacy.inspection import inspect
100
+ from lightning_sdk.cli.legacy.list import list_cli
101
+ from lightning_sdk.cli.legacy.open import open as open_cmd
102
+ from lightning_sdk.cli.legacy.run import run
103
+ from lightning_sdk.cli.legacy.start import start
104
+ from lightning_sdk.cli.legacy.stop import stop
105
+ from lightning_sdk.cli.legacy.switch import switch
106
+ from lightning_sdk.cli.legacy.upload import upload
107
+
108
+ # Add old command groups
109
+ main_cli.add_command(aihub)
110
+ main_cli.add_command(configure)
111
+ main_cli.add_command(connect)
112
+ main_cli.add_command(create)
113
+ main_cli.add_command(delete)
114
+ main_cli.add_command(deploy)
115
+ main_cli.add_command(dockerize)
116
+ main_cli.add_command(download)
117
+ main_cli.add_command(generate)
118
+ main_cli.add_command(inspect)
119
+ main_cli.add_command(list_cli)
120
+ main_cli.add_command(open_cmd)
121
+ main_cli.add_command(run)
122
+ main_cli.add_command(start)
123
+ main_cli.add_command(stop)
124
+ main_cli.add_command(switch)
125
+ main_cli.add_command(upload)
107
126
 
108
127
 
109
128
  if __name__ == "__main__":
@@ -0,0 +1,35 @@
1
+ """CLI groups for organizing Lightning SDK commands."""
2
+
3
+ import click
4
+
5
+ from lightning_sdk.cli.config import register_commands as register_config_commands
6
+ from lightning_sdk.cli.job import register_commands as register_job_commands
7
+ from lightning_sdk.cli.mmt import register_commands as register_mmt_commands
8
+ from lightning_sdk.cli.studio import register_commands as register_studio_commands
9
+
10
+
11
+ @click.group(name="studio")
12
+ def studio() -> None:
13
+ """Manage Lightning AI Studios."""
14
+
15
+
16
+ @click.group(name="job")
17
+ def job() -> None:
18
+ """Manage Lightning AI Jobs."""
19
+
20
+
21
+ @click.group(name="mmt")
22
+ def mmt() -> None:
23
+ """Manage Lightning AI Multi-Machine Training (MMT)."""
24
+
25
+
26
+ @click.group(name="config")
27
+ def config() -> None:
28
+ """Manage Lightning SDK and CLIconfiguration."""
29
+
30
+
31
+ # Register config commands with the main config group
32
+ register_job_commands(job)
33
+ register_mmt_commands(mmt)
34
+ register_studio_commands(studio)
35
+ register_config_commands(config)
@@ -0,0 +1,7 @@
1
+ """Job CLI commands."""
2
+
3
+ import click
4
+
5
+
6
+ def register_commands(group: click.Group) -> None:
7
+ """Register job commands with the given group."""
@@ -7,8 +7,8 @@ from typing import Optional, Union
7
7
  import click
8
8
  from rich.console import Console
9
9
 
10
- from lightning_sdk.cli.generate import _generate_ssh_config
11
- from lightning_sdk.cli.studios_menu import _StudiosMenu
10
+ from lightning_sdk.cli.legacy.generate import _generate_ssh_config
11
+ from lightning_sdk.cli.legacy.studios_menu import _StudiosMenu
12
12
  from lightning_sdk.lightning_cloud.login import Auth
13
13
 
14
14
 
@@ -4,8 +4,8 @@ from typing import Optional
4
4
 
5
5
  import click
6
6
 
7
- from lightning_sdk.cli.configure import _configure_ssh_internal
8
- from lightning_sdk.cli.studios_menu import _StudiosMenu
7
+ from lightning_sdk.cli.legacy.configure import _configure_ssh_internal
8
+ from lightning_sdk.cli.legacy.studios_menu import _StudiosMenu
9
9
 
10
10
 
11
11
  @click.group(name="connect")
@@ -8,7 +8,7 @@ from rich.console import Console
8
8
 
9
9
  from lightning_sdk import Machine, Studio
10
10
  from lightning_sdk.api.cloud_account_api import CloudAccountApi
11
- from lightning_sdk.cli.teamspace_menu import _TeamspacesMenu
11
+ from lightning_sdk.cli.legacy.teamspace_menu import _TeamspacesMenu
12
12
  from lightning_sdk.machine import CloudProvider
13
13
  from lightning_sdk.utils.resolve import _resolve_deprecated_provider
14
14
 
@@ -3,9 +3,9 @@ from typing import Optional
3
3
  import click
4
4
  from rich.console import Console
5
5
 
6
- from lightning_sdk.cli.exceptions import StudioCliError
7
- from lightning_sdk.cli.job_and_mmt_action import _JobAndMMTAction
8
- from lightning_sdk.cli.teamspace_menu import _TeamspacesMenu
6
+ from lightning_sdk.cli.legacy.exceptions import StudioCliError
7
+ from lightning_sdk.cli.legacy.job_and_mmt_action import _JobAndMMTAction
8
+ from lightning_sdk.cli.legacy.teamspace_menu import _TeamspacesMenu
9
9
  from lightning_sdk.lightning_cloud.openapi.rest import ApiException
10
10
  from lightning_sdk.lit_container import LitContainer
11
11
  from lightning_sdk.studio import Studio
File without changes
@@ -10,7 +10,7 @@ from rich.prompt import Confirm
10
10
 
11
11
  from lightning_sdk import Teamspace
12
12
  from lightning_sdk.api import UserApi
13
- from lightning_sdk.cli.teamspace_menu import _TeamspacesMenu
13
+ from lightning_sdk.cli.legacy.teamspace_menu import _TeamspacesMenu
14
14
  from lightning_sdk.lightning_cloud import env
15
15
  from lightning_sdk.lightning_cloud.login import Auth, AuthServer
16
16
  from lightning_sdk.lightning_cloud.openapi import V1CloudSpace
@@ -12,8 +12,14 @@ from rich.prompt import Confirm
12
12
  from rich.syntax import Syntax
13
13
 
14
14
  from lightning_sdk import Machine
15
- from lightning_sdk.cli.deploy._auth import _AuthMode, _Onboarding, authenticate, poll_verified_status, select_teamspace
16
- from lightning_sdk.cli.upload import (
15
+ from lightning_sdk.cli.legacy.deploy._auth import (
16
+ _AuthMode,
17
+ _Onboarding,
18
+ authenticate,
19
+ poll_verified_status,
20
+ select_teamspace,
21
+ )
22
+ from lightning_sdk.cli.legacy.upload import (
17
23
  _dump_current_upload_state,
18
24
  _resolve_previous_upload_state,
19
25
  _single_file_upload,
@@ -15,15 +15,15 @@ from rich.prompt import Confirm
15
15
  from lightning_sdk import 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
- from lightning_sdk.cli.clusters_menu import _ClustersMenu
19
- from lightning_sdk.cli.deploy._auth import (
18
+ from lightning_sdk.cli.legacy.clusters_menu import _ClustersMenu
19
+ from lightning_sdk.cli.legacy.deploy._auth import (
20
20
  _AuthMode,
21
21
  _Onboarding,
22
22
  authenticate,
23
23
  poll_verified_status,
24
24
  select_teamspace,
25
25
  )
26
- from lightning_sdk.cli.deploy.devbox import _handle_devbox
26
+ from lightning_sdk.cli.legacy.deploy.devbox import _handle_devbox
27
27
  from lightning_sdk.serve import _LitServeDeployer
28
28
 
29
29
  _MACHINE_VALUES = tuple(
@@ -9,9 +9,9 @@ from rich.console import Console
9
9
 
10
10
  from lightning_sdk.api.license_api import LicenseApi
11
11
  from lightning_sdk.api.lit_container_api import LitContainerApi
12
- from lightning_sdk.cli.exceptions import StudioCliError
13
- from lightning_sdk.cli.studios_menu import _StudiosMenu
14
- from lightning_sdk.cli.teamspace_menu import _TeamspacesMenu
12
+ from lightning_sdk.cli.legacy.exceptions import StudioCliError
13
+ from lightning_sdk.cli.legacy.studios_menu import _StudiosMenu
14
+ from lightning_sdk.cli.legacy.teamspace_menu import _TeamspacesMenu
15
15
  from lightning_sdk.models import download_model
16
16
  from lightning_sdk.studio import Studio
17
17
  from lightning_sdk.utils.resolve import _get_authed_user, skip_studio_init
@@ -0,0 +1,110 @@
1
+ import sys
2
+ import traceback
3
+ from types import TracebackType
4
+ from typing import Type
5
+
6
+ import click
7
+ from rich.console import Console, Group
8
+ from rich.panel import Panel
9
+ from rich.syntax import Syntax
10
+ from rich.text import Text
11
+
12
+ from lightning_sdk import __version__
13
+ from lightning_sdk.api.studio_api import _cloud_url
14
+ from lightning_sdk.cli.legacy.ai_hub import aihub
15
+ from lightning_sdk.cli.legacy.coloring import CustomHelpFormatter
16
+ from lightning_sdk.cli.legacy.configure import configure
17
+ from lightning_sdk.cli.legacy.connect import connect
18
+ from lightning_sdk.cli.legacy.create import create
19
+ from lightning_sdk.cli.legacy.delete import delete
20
+ from lightning_sdk.cli.legacy.deploy.serve import deploy
21
+ from lightning_sdk.cli.legacy.docker_cli import dockerize
22
+ from lightning_sdk.cli.legacy.download import download
23
+ from lightning_sdk.cli.legacy.generate import generate
24
+ from lightning_sdk.cli.legacy.inspection import inspect
25
+ from lightning_sdk.cli.legacy.list import list_cli
26
+ from lightning_sdk.cli.legacy.open import open
27
+ from lightning_sdk.cli.legacy.run import run
28
+ from lightning_sdk.cli.legacy.start import start
29
+ from lightning_sdk.cli.legacy.stop import stop
30
+ from lightning_sdk.cli.legacy.switch import switch
31
+ from lightning_sdk.cli.legacy.upload import upload
32
+ from lightning_sdk.constants import _LIGHTNING_DEBUG
33
+ from lightning_sdk.lightning_cloud.login import Auth
34
+
35
+
36
+ def _notify_exception(exception_type: Type[BaseException], value: BaseException, tb: TracebackType) -> None:
37
+ """CLI won't show tracebacks, just print the exception message."""
38
+ console = Console()
39
+
40
+ message = str(value.args[0]) if value.args else str(value) or "An unknown error occurred"
41
+
42
+ error_text = Text()
43
+ error_text.append(f"{exception_type.__name__}: ", style="bold red")
44
+ error_text.append(message, style="white")
45
+
46
+ renderables = [error_text]
47
+
48
+ if _LIGHTNING_DEBUG:
49
+ tb_text = "".join(traceback.format_exception(exception_type, value, tb))
50
+ renderables.append(Text("\n\nFull traceback:\n", style="bold yellow"))
51
+ renderables.append(Syntax(tb_text, "python", theme="monokai", line_numbers=False, word_wrap=True))
52
+ else:
53
+ renderables.append(Text("\n\n🐞 To view the full traceback, set: LIGHTNING_DEBUG=1"))
54
+
55
+ renderables.append(Text("\n📘 Need help? Run: lightning <command> --help", style="cyan"))
56
+
57
+ console.print(Panel(Group(*renderables), title="⚡ Lightning CLI Error", border_style="red"))
58
+
59
+
60
+ @click.group(name="lightning", help="Command line interface (CLI) to interact with/manage Lightning AI Studios.")
61
+ @click.version_option(__version__, message="Lightning CLI version %(version)s")
62
+ def main_cli() -> None:
63
+ sys.excepthook = _notify_exception
64
+
65
+
66
+ # colorful help messages
67
+ main_cli.context_class.formatter_class = CustomHelpFormatter
68
+
69
+
70
+ @main_cli.command
71
+ def login() -> None:
72
+ """Login to Lightning AI Studios."""
73
+ auth = Auth()
74
+ auth.clear()
75
+
76
+ try:
77
+ auth.authenticate()
78
+ except ConnectionError:
79
+ raise RuntimeError(f"Unable to connect to {_cloud_url()}. Please check your internet connection.") from None
80
+
81
+
82
+ @main_cli.command
83
+ def logout() -> None:
84
+ """Logout from Lightning AI Studios."""
85
+ auth = Auth()
86
+ auth.clear()
87
+
88
+
89
+ # additional commands
90
+ main_cli.add_command(aihub)
91
+ main_cli.add_command(configure)
92
+ main_cli.add_command(connect)
93
+ main_cli.add_command(create)
94
+ main_cli.add_command(delete)
95
+ main_cli.add_command(dockerize)
96
+ main_cli.add_command(download)
97
+ main_cli.add_command(generate)
98
+ main_cli.add_command(inspect)
99
+ main_cli.add_command(list_cli)
100
+ main_cli.add_command(run)
101
+ main_cli.add_command(deploy)
102
+ main_cli.add_command(start)
103
+ main_cli.add_command(stop)
104
+ main_cli.add_command(switch)
105
+ main_cli.add_command(upload)
106
+ main_cli.add_command(open)
107
+
108
+
109
+ if __name__ == "__main__":
110
+ main_cli()
@@ -3,7 +3,7 @@ from typing import Optional
3
3
  import click
4
4
  from rich.console import Console
5
5
 
6
- from lightning_sdk.cli.studios_menu import _StudiosMenu
6
+ from lightning_sdk.cli.legacy.studios_menu import _StudiosMenu
7
7
 
8
8
 
9
9
  @click.group(name="generate")
@@ -3,7 +3,7 @@ from typing import Optional
3
3
  import click
4
4
  from rich.console import Console
5
5
 
6
- from lightning_sdk.cli.job_and_mmt_action import _JobAndMMTAction
6
+ from lightning_sdk.cli.legacy.job_and_mmt_action import _JobAndMMTAction
7
7
 
8
8
 
9
9
  @click.group(name="inspect")
@@ -1,8 +1,8 @@
1
1
  from typing import Optional
2
2
 
3
- from lightning_sdk.cli.jobs_menu import _JobsMenu
4
- from lightning_sdk.cli.mmts_menu import _MMTsMenu
5
- from lightning_sdk.cli.teamspace_menu import _TeamspacesMenu
3
+ from lightning_sdk.cli.legacy.jobs_menu import _JobsMenu
4
+ from lightning_sdk.cli.legacy.mmts_menu import _MMTsMenu
5
+ from lightning_sdk.cli.legacy.teamspace_menu import _TeamspacesMenu
6
6
  from lightning_sdk.job import Job
7
7
  from lightning_sdk.mmt import MMT
8
8
 
@@ -3,7 +3,7 @@ from typing import Dict, List, Optional
3
3
  from rich.console import Console
4
4
  from simple_term_menu import TerminalMenu
5
5
 
6
- from lightning_sdk.cli.exceptions import StudioCliError
6
+ from lightning_sdk.cli.legacy.exceptions import StudioCliError
7
7
  from lightning_sdk.job import Job
8
8
  from lightning_sdk.teamspace import Teamspace
9
9