lightning-sdk 2025.9.29__py3-none-any.whl → 2025.9.30__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
lightning_sdk/__init__.py CHANGED
@@ -9,7 +9,7 @@ from lightning_sdk.mmt import MMT
9
9
  from lightning_sdk.organization import Organization
10
10
  from lightning_sdk.plugin import JobsPlugin, MultiMachineTrainingPlugin, Plugin, SlurmJobsPlugin
11
11
  from lightning_sdk.status import Status
12
- from lightning_sdk.studio import Studio
12
+ from lightning_sdk.studio import VM, Studio
13
13
  from lightning_sdk.teamspace import ConnectionType, FolderLocation, Teamspace
14
14
  from lightning_sdk.user import User
15
15
 
@@ -32,8 +32,9 @@ __all__ = [
32
32
  "Studio",
33
33
  "Teamspace",
34
34
  "User",
35
+ "VM",
35
36
  ]
36
37
 
37
- __version__ = "2025.09.29"
38
+ __version__ = "2025.09.30"
38
39
  _check_version_and_prompt_upgrade(__version__)
39
40
  _set_tqdm_envvars_noninteractive()
@@ -14,7 +14,7 @@ from lightning_sdk.cli.legacy.studios_menu import _StudiosMenu
14
14
  from lightning_sdk.cli.utils.teamspace_selection import TeamspacesMenu
15
15
  from lightning_sdk.models import download_model
16
16
  from lightning_sdk.studio import Studio
17
- from lightning_sdk.utils.resolve import _get_authed_user, skip_studio_init
17
+ from lightning_sdk.utils.resolve import _get_authed_user
18
18
 
19
19
 
20
20
  def _expand_remote_path(path: str) -> str:
@@ -242,7 +242,7 @@ def _resolve_studio(studio: Optional[str]) -> Studio:
242
242
  and (re.match(studio_name, st["name"]) or studio_name in st["name"]),
243
243
  possible_studios,
244
244
  )
245
- if not possible_studios:
245
+ if not len(possible_studios):
246
246
  raise ValueError(
247
247
  f"Could not find Studio like '{studio}', please consider update your filtering pattern."
248
248
  )
@@ -260,8 +260,7 @@ def _resolve_studio(studio: Optional[str]) -> Studio:
260
260
  "Please contact Lightning AI directly to resolve this issue."
261
261
  ) from e
262
262
 
263
- with skip_studio_init():
264
- return Studio(**selected_studio)
263
+ return Studio(**selected_studio)
265
264
 
266
265
 
267
266
  @download.command(name="licenses")
@@ -20,7 +20,7 @@ from lightning_sdk.cli.utils.teamspace_selection import TeamspacesMenu
20
20
  from lightning_sdk.constants import _LIGHTNING_DEBUG
21
21
  from lightning_sdk.models import upload_model as _upload_model
22
22
  from lightning_sdk.studio import Studio
23
- from lightning_sdk.utils.resolve import _get_authed_user, skip_studio_init
23
+ from lightning_sdk.utils.resolve import _get_authed_user
24
24
 
25
25
  _STUDIO_UPLOAD_STATUS_PATH = "~/.lightning/studios/uploads"
26
26
 
@@ -285,8 +285,7 @@ def _resolve_studio(studio: Optional[str]) -> Studio:
285
285
  "Please contact Lightning AI directly to resolve this issue."
286
286
  ) from e
287
287
 
288
- with skip_studio_init():
289
- return Studio(**selected_studio)
288
+ return Studio(**selected_studio)
290
289
 
291
290
 
292
291
  def _print_docker_push(lines: Generator, console: Console, progress: Progress, push_task: rich.progress.TaskID) -> None:
@@ -5,6 +5,7 @@ import click
5
5
 
6
6
  def register_commands(group: click.Group) -> None:
7
7
  """Register studio commands with the given group."""
8
+ from lightning_sdk.cli.studio.connect import connect_studio
8
9
  from lightning_sdk.cli.studio.create import create_studio
9
10
  from lightning_sdk.cli.studio.delete import delete_studio
10
11
  from lightning_sdk.cli.studio.list import list_studios
@@ -20,3 +21,4 @@ def register_commands(group: click.Group) -> None:
20
21
  group.add_command(start_studio)
21
22
  group.add_command(stop_studio)
22
23
  group.add_command(switch_studio)
24
+ group.add_command(connect_studio)
@@ -0,0 +1,94 @@
1
+ """Studio connect command."""
2
+
3
+ import subprocess
4
+ import sys
5
+ from typing import Optional
6
+
7
+ import click
8
+
9
+ from lightning_sdk.cli.utils.richt_print import studio_name_link
10
+ from lightning_sdk.cli.utils.save_to_config import save_studio_to_config, save_teamspace_to_config
11
+ from lightning_sdk.cli.utils.ssh_connection import download_ssh_keys
12
+ from lightning_sdk.cli.utils.teamspace_selection import TeamspacesMenu
13
+ from lightning_sdk.lightning_cloud.login import Auth
14
+ from lightning_sdk.lightning_cloud.openapi.rest import ApiException
15
+ from lightning_sdk.machine import CloudProvider
16
+ from lightning_sdk.studio import Studio
17
+ from lightning_sdk.utils.names import random_unique_name
18
+
19
+
20
+ @click.command("connect")
21
+ @click.argument("name", required=False)
22
+ @click.option("--teamspace", help="Override default teamspace (format: owner/teamspace)")
23
+ @click.option(
24
+ "--cloud-provider",
25
+ help="The cloud provider to start the studio on. Defaults to teamspace default.",
26
+ type=click.Choice(m.name for m in list(CloudProvider)),
27
+ )
28
+ @click.option(
29
+ "--cloud-account",
30
+ help="The cloud account to create the studio on. Defaults to teamspace default.",
31
+ type=click.STRING,
32
+ )
33
+ @click.option("--gpus", help="The number of GPUs to start the studio on. ", type=click.INT)
34
+ def connect_studio(
35
+ name: Optional[str] = None,
36
+ teamspace: Optional[str] = None,
37
+ cloud_provider: Optional[str] = None,
38
+ cloud_account: Optional[str] = None,
39
+ gpus: Optional[int] = None,
40
+ ) -> None:
41
+ """Connect to a Studio.
42
+
43
+ Example:
44
+ lightning studio connect
45
+ """
46
+ menu = TeamspacesMenu()
47
+
48
+ resolved_teamspace = menu(teamspace)
49
+ save_teamspace_to_config(resolved_teamspace, overwrite=False)
50
+
51
+ if cloud_provider is not None:
52
+ cloud_provider = CloudProvider(cloud_provider)
53
+
54
+ name = name or random_unique_name()
55
+
56
+ try:
57
+ studio = Studio(
58
+ name=name,
59
+ teamspace=resolved_teamspace,
60
+ create_ok=True,
61
+ cloud_provider=cloud_provider,
62
+ cloud_account=cloud_account,
63
+ )
64
+ except (RuntimeError, ValueError, ApiException):
65
+ raise ValueError(f"Could not create Studio: '{name}'") from None
66
+
67
+ click.echo(f"Connecting to Studio '{studio_name_link(studio)}' ...")
68
+
69
+ machine = "CPU"
70
+ Studio.show_progress = True
71
+ if gpus:
72
+ # TODO: handle something like gpus=4:L4
73
+ pass
74
+
75
+ save_studio_to_config(studio)
76
+ studio.start(machine, interruptible=True)
77
+
78
+ ssh_private_key_path = _configure_ssh_internal()
79
+
80
+ try:
81
+ ssh_command = (
82
+ f"ssh -i {ssh_private_key_path} -o UserKnownHostsFile=/dev/null s_{studio._studio.id}@ssh.lightning.ai"
83
+ )
84
+ subprocess.run(ssh_command.split())
85
+ except Exception as ex:
86
+ print(f"Failed to establish SSH connection: {ex}")
87
+ sys.exit(1)
88
+
89
+
90
+ def _configure_ssh_internal() -> str:
91
+ """Internal function to configure SSH without Click decorators."""
92
+ auth = Auth()
93
+ auth.authenticate()
94
+ return download_ssh_keys(auth.api_key, force_download=False)
@@ -1,19 +1,15 @@
1
1
  """Studio SSH command."""
2
2
 
3
- import os
4
- import platform
5
3
  import subprocess
6
- import uuid
7
- from pathlib import Path
8
4
  from typing import List, Optional
9
5
 
10
6
  import click
11
7
 
12
8
  from lightning_sdk.cli.utils.save_to_config import save_studio_to_config
9
+ from lightning_sdk.cli.utils.ssh_connection import download_ssh_keys
13
10
  from lightning_sdk.cli.utils.studio_selection import StudiosMenu
14
11
  from lightning_sdk.cli.utils.teamspace_selection import TeamspacesMenu
15
12
  from lightning_sdk.lightning_cloud.login import Auth
16
- from lightning_sdk.utils.config import _DEFAULT_CONFIG_FILE_PATH
17
13
 
18
14
 
19
15
  @click.command("ssh")
@@ -45,7 +41,7 @@ def ssh_studio(name: Optional[str] = None, teamspace: Optional[str] = None, opti
45
41
  def ssh_impl(name: Optional[str], teamspace: Optional[str], option: Optional[List[str]], vm: bool) -> None:
46
42
  auth = Auth()
47
43
  auth.authenticate()
48
- ssh_private_key_path = _download_ssh_keys(auth.api_key, force_download=False)
44
+ ssh_private_key_path = download_ssh_keys(auth.api_key, force_download=False)
49
45
 
50
46
  menu = TeamspacesMenu()
51
47
  resolved_teamspace = menu(teamspace=teamspace)
@@ -63,53 +59,9 @@ def ssh_impl(name: Optional[str], teamspace: Optional[str], option: Optional[Lis
63
59
  subprocess.run(ssh_command.split())
64
60
  except Exception:
65
61
  # redownload the keys to be sure they are up to date
66
- _download_ssh_keys(auth.api_key, force_download=True)
62
+ download_ssh_keys(auth.api_key, force_download=True)
67
63
  try:
68
64
  subprocess.run(ssh_command.split())
69
65
  except Exception:
70
66
  # TODO: make this a generic CLI error
71
67
  raise RuntimeError("Failed to establish SSH connection") from None
72
-
73
-
74
- def _download_ssh_keys(
75
- api_key: str,
76
- force_download: bool = False,
77
- ssh_key_name: str = "lightning_rsa",
78
- ) -> None:
79
- """Download the SSH key for a User."""
80
- ssh_private_key_path = os.path.join(os.path.expanduser(os.path.dirname(_DEFAULT_CONFIG_FILE_PATH)), ssh_key_name)
81
-
82
- os.makedirs(os.path.dirname(ssh_private_key_path), exist_ok=True)
83
-
84
- if not os.path.isfile(ssh_private_key_path) or force_download:
85
- key_id = str(uuid.uuid4())
86
- _download_file(
87
- f"https://lightning.ai/setup/ssh-gen?t={api_key}&id={key_id}&machineName={platform.node()}",
88
- ssh_private_key_path,
89
- overwrite=True,
90
- chmod=0o600,
91
- )
92
- _download_file(
93
- f"https://lightning.ai/setup/ssh-public?t={api_key}&id={key_id}",
94
- ssh_private_key_path + ".pub",
95
- overwrite=True,
96
- )
97
-
98
- return ssh_private_key_path
99
-
100
-
101
- def _download_file(url: str, local_path: Path, overwrite: bool = True, chmod: Optional[int] = None) -> None:
102
- """Download a file from a URL."""
103
- import requests
104
-
105
- if os.path.isfile(local_path) and not overwrite:
106
- raise FileExistsError(f"The file {local_path} already exists and overwrite is set to False.")
107
-
108
- response = requests.get(url, stream=True)
109
- response.raise_for_status()
110
-
111
- with open(local_path, "wb") as file:
112
- for chunk in response.iter_content(chunk_size=8192):
113
- file.write(chunk)
114
- if chmod is not None:
115
- os.chmod(local_path, 0o600)
@@ -0,0 +1,51 @@
1
+ import os
2
+ import platform
3
+ import uuid
4
+ from pathlib import Path
5
+ from typing import Optional
6
+
7
+ from lightning_sdk.utils.config import _DEFAULT_CONFIG_FILE_PATH
8
+
9
+
10
+ def download_ssh_keys(
11
+ api_key: str | None,
12
+ force_download: bool = False,
13
+ ssh_key_name: str = "lightning_rsa",
14
+ ) -> str:
15
+ """Download the SSH key for a User."""
16
+ ssh_private_key_path = os.path.join(os.path.expanduser(os.path.dirname(_DEFAULT_CONFIG_FILE_PATH)), ssh_key_name)
17
+
18
+ os.makedirs(os.path.dirname(ssh_private_key_path), exist_ok=True)
19
+
20
+ if not os.path.isfile(ssh_private_key_path) or force_download:
21
+ key_id = str(uuid.uuid4())
22
+ download_file(
23
+ f"https://lightning.ai/setup/ssh-gen?t={api_key}&id={key_id}&machineName={platform.node()}",
24
+ Path(ssh_private_key_path),
25
+ overwrite=True,
26
+ chmod=0o600,
27
+ )
28
+ download_file(
29
+ f"https://lightning.ai/setup/ssh-public?t={api_key}&id={key_id}",
30
+ Path(ssh_private_key_path + ".pub"),
31
+ overwrite=True,
32
+ )
33
+
34
+ return ssh_private_key_path
35
+
36
+
37
+ def download_file(url: str, local_path: Path, overwrite: bool = True, chmod: Optional[int] = None) -> None:
38
+ """Download a file from a URL."""
39
+ import requests
40
+
41
+ if os.path.isfile(local_path) and not overwrite:
42
+ raise FileExistsError(f"The file {local_path} already exists and overwrite is set to False.")
43
+
44
+ response = requests.get(url, stream=True)
45
+ response.raise_for_status()
46
+
47
+ with open(local_path, "wb") as file:
48
+ for chunk in response.iter_content(chunk_size=8192):
49
+ file.write(chunk)
50
+ if chmod is not None:
51
+ os.chmod(local_path, 0o600)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: lightning_sdk
3
- Version: 2025.9.29
3
+ Version: 2025.9.30
4
4
  Summary: SDK to develop using Lightning AI Studios
5
5
  Author-email: Lightning-AI <justus@lightning.ai>
6
6
  License: MIT License
@@ -1,5 +1,5 @@
1
1
  docs/source/conf.py,sha256=r8yX20eC-4mHhMTd0SbQb5TlSWHhO6wnJ0VJ_FBFpag,13249
2
- lightning_sdk/__init__.py,sha256=HBcv4oavnBLmLhOoGKn7B71XVE1xFmSPUw0GM-UjU4w,1221
2
+ lightning_sdk/__init__.py,sha256=1ZQWzgRpFgZg43Tyx8qq56e3b0ELkQ-sE12C9T7wg_o,1235
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
@@ -50,7 +50,7 @@ lightning_sdk/cli/legacy/connect.py,sha256=0qJ0yvykoPBkmCvvEbWKppt7wlUmRq3LNNGEs
50
50
  lightning_sdk/cli/legacy/create.py,sha256=ftp7cP8dqtO3h35mZUkpUjFW1tHwKxPQoUOPsabcy0M,3682
51
51
  lightning_sdk/cli/legacy/delete.py,sha256=IC04CNqJFIEfgl6Tlt4uEl3t81yZCb8VYLRwy3B8xiA,3816
52
52
  lightning_sdk/cli/legacy/docker_cli.py,sha256=EozLC4qnvHhgukmnu35itfI5n7v-abCpwKPkPy3eOV4,997
53
- lightning_sdk/cli/legacy/download.py,sha256=7ZOkqnAIEww12LM_cDO8hBhVbMYkChl82-vXHixcNwg,11357
53
+ lightning_sdk/cli/legacy/download.py,sha256=_Yaw1slwjE7ygDomjEJliXLTE-Gfj1d3zkH3daYVASk,11311
54
54
  lightning_sdk/cli/legacy/entrypoint.py,sha256=dk_BKvNzQMYREdAGTTdHF8nZWp_EuvCii-WOz4YFwrk,3784
55
55
  lightning_sdk/cli/legacy/exceptions.py,sha256=QUF3OMAMZwBikvlusimSHSBjb6ywvHpfAumJBEaodSw,169
56
56
  lightning_sdk/cli/legacy/generate.py,sha256=3tLaqALiuWG3AEIQtNHChMNpaJJU9zV5VYGshiEmKug,1582
@@ -66,17 +66,18 @@ lightning_sdk/cli/legacy/stop.py,sha256=jSiuxIunDnL3A3DQ1m8GZx01Qt4Zx5vIA3u7U81C
66
66
  lightning_sdk/cli/legacy/studios_menu.py,sha256=TA9rO6_fFHGMz0Nt4rJ6iV80X5pZE4xShrSiyXoU-oQ,4129
67
67
  lightning_sdk/cli/legacy/switch.py,sha256=G3y9BmP-0d_OKJub5fMZ0ddnGZkOFBtregMkx_KWxcw,1945
68
68
  lightning_sdk/cli/legacy/teamspace_menu.py,sha256=u5_lyB1aCD8KJIsOuxi0bvPi75McU5EbluMLyD_NBUw,4104
69
- lightning_sdk/cli/legacy/upload.py,sha256=7FTUnA4CvE7FaNTmNKhjmr-7Ly72QGvDQVqvp1EeQpY,13773
69
+ lightning_sdk/cli/legacy/upload.py,sha256=fFJct9F_1vLqTMLtSjuv4BN3AbUpeGebwv3ZXH0NiqI,13722
70
70
  lightning_sdk/cli/legacy/deploy/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
71
71
  lightning_sdk/cli/legacy/deploy/_auth.py,sha256=wpwhkF2tmURlhEBaZ3QgOnHQELy3XLPt2d4LWb7JosY,7700
72
72
  lightning_sdk/cli/legacy/deploy/devbox.py,sha256=SdOtYdGefzldn-WCa6sz31zysyf2nP5D7O2x1DE9z_E,6839
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
- lightning_sdk/cli/studio/__init__.py,sha256=Reb5a0iHJfNMxmnP30DAmYqpJ-YDQoJcgyVrD2cYDNo,823
75
+ lightning_sdk/cli/studio/__init__.py,sha256=jqUuEniYlf3fwJni-MGLII3oprpsBSQEFqzBJwPIxMk,925
76
+ lightning_sdk/cli/studio/connect.py,sha256=iHZiY0VvlBO4t7-tE3R5kkDsCQo6BSQ0CztOK9_uOKI,3038
76
77
  lightning_sdk/cli/studio/create.py,sha256=kTxLtvTFjo-SgkdzOIngdXu_6yYLHwVbkfMhHjpIFkI,2505
77
78
  lightning_sdk/cli/studio/delete.py,sha256=Gi1KLCrSgjTiyoQe9NRvF4ZpsNyeM07KHnBxfdJg2FE,1483
78
79
  lightning_sdk/cli/studio/list.py,sha256=ieLiHRIfAb7E5e_r48BeTC03ib8RY6maeF7nkmrqaek,3301
79
- lightning_sdk/cli/studio/ssh.py,sha256=5CRw62p9rUb4BIL1WZP-Ehzcgfq_hVkY5ixTurxUKKo,3866
80
+ lightning_sdk/cli/studio/ssh.py,sha256=ly7FyaVYTfjQiB8T1iKJ_OoeEZTZCYhzVkgIEavYUoY,2299
80
81
  lightning_sdk/cli/studio/start.py,sha256=GHfV_1I1XwV8UHOWBP2WVfd1B2BHyw1lQ9HMv6Eomes,3236
81
82
  lightning_sdk/cli/studio/stop.py,sha256=hVXIyrv68rvrwIQgyEPUKt3Th8S1iipOVflopPnoVOY,1398
82
83
  lightning_sdk/cli/studio/switch.py,sha256=x6F1biDtfR0dk1t7X3NSkmfj5jkzGJe6-nvj3SonQlQ,2069
@@ -87,6 +88,7 @@ lightning_sdk/cli/utils/owner_selection.py,sha256=PbKbFoGblxi60lF_kZxnlqxjCmI9r9
87
88
  lightning_sdk/cli/utils/resolve.py,sha256=RWQ8MgXEJCdsoY50y8Pa9B-A6NA_SvxOqL5pVKfvSr8,917
88
89
  lightning_sdk/cli/utils/richt_print.py,sha256=psSY65nLAQbxK_K0w93Qq9857aUUbm77FLS1sc3Oecg,1262
89
90
  lightning_sdk/cli/utils/save_to_config.py,sha256=mMjjfA4Yv1e7MtE03iADTXcTSAuUL0Ws9OZObx6ufo0,1164
91
+ lightning_sdk/cli/utils/ssh_connection.py,sha256=REB4rRsDrYrjACBK1PWlmcehLEututqjCLeGTHca1Lk,1677
90
92
  lightning_sdk/cli/utils/studio_selection.py,sha256=z0SMd82sOt_mfTiQZgVY27MxLkMAjM__SWhlOlfXJT0,4347
91
93
  lightning_sdk/cli/utils/teamspace_selection.py,sha256=n-FFfWLTV63SxoK6Fi2VQikBIfKYqMNTew9b9v-1UQk,4945
92
94
  lightning_sdk/cli/vm/__init__.py,sha256=tAJpluJVDOF3fUQyRwko5ZYIpqglczMyRv9Kz4OVaIk,711
@@ -1205,9 +1207,9 @@ lightning_sdk/utils/enum.py,sha256=h2JRzqoBcSlUdanFHmkj_j5DleBHAu1esQYUsdNI-hU,4
1205
1207
  lightning_sdk/utils/names.py,sha256=1EuXbIh7wldkDp1FG10oz9vIOyWrpGWeFFVy-DQBgzA,18162
1206
1208
  lightning_sdk/utils/progress.py,sha256=IXfEcUF-rL5jIw0Hir6eSxN7VBZfR--1O2LaEhGAU70,12698
1207
1209
  lightning_sdk/utils/resolve.py,sha256=4TyEnIgIrvkSvYk5i5PmcIogD_5Y9pBhiphRLfLMttc,10477
1208
- lightning_sdk-2025.9.29.dist-info/LICENSE,sha256=uFIuZwj5z-4TeF2UuacPZ1o17HkvKObT8fY50qN84sg,1064
1209
- lightning_sdk-2025.9.29.dist-info/METADATA,sha256=CYT1gpwGdPiXJFMDKm0cmhiilbuIEgxvrFT0ndOwhuc,4130
1210
- lightning_sdk-2025.9.29.dist-info/WHEEL,sha256=iAkIy5fosb7FzIOwONchHf19Qu7_1wCWyFNR5gu9nU0,91
1211
- lightning_sdk-2025.9.29.dist-info/entry_points.txt,sha256=OoZa4Fc8NMs6GSN0cdA1J8e6couzAcL82CbM1yo4f_M,122
1212
- lightning_sdk-2025.9.29.dist-info/top_level.txt,sha256=ps8doKILFXmN7F1mHncShmnQoTxKBRPIcchC8TpoBw4,19
1213
- lightning_sdk-2025.9.29.dist-info/RECORD,,
1210
+ lightning_sdk-2025.9.30.dist-info/LICENSE,sha256=uFIuZwj5z-4TeF2UuacPZ1o17HkvKObT8fY50qN84sg,1064
1211
+ lightning_sdk-2025.9.30.dist-info/METADATA,sha256=Ju9urPSHGtE4gfSRZGGJqjYVK7MA-EjocNrUfLKtr8A,4130
1212
+ lightning_sdk-2025.9.30.dist-info/WHEEL,sha256=iAkIy5fosb7FzIOwONchHf19Qu7_1wCWyFNR5gu9nU0,91
1213
+ lightning_sdk-2025.9.30.dist-info/entry_points.txt,sha256=OoZa4Fc8NMs6GSN0cdA1J8e6couzAcL82CbM1yo4f_M,122
1214
+ lightning_sdk-2025.9.30.dist-info/top_level.txt,sha256=ps8doKILFXmN7F1mHncShmnQoTxKBRPIcchC8TpoBw4,19
1215
+ lightning_sdk-2025.9.30.dist-info/RECORD,,