lightning-sdk 0.2.24rc1__py3-none-any.whl → 2025.7.10__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- lightning_sdk/__init__.py +1 -1
- lightning_sdk/api/cluster_api.py +15 -0
- lightning_sdk/api/llm_api.py +4 -0
- lightning_sdk/api/pipeline_api.py +15 -7
- lightning_sdk/api/studio_api.py +0 -17
- lightning_sdk/job/base.py +21 -0
- lightning_sdk/lightning_cloud/openapi/models/assistant_id_conversations_body.py +27 -1
- lightning_sdk/lightning_cloud/openapi/models/v1_conversation_response_chunk.py +27 -1
- lightning_sdk/lightning_cloud/openapi/models/v1_user_features.py +53 -79
- lightning_sdk/lightning_cloud/utils/data_connection.py +57 -3
- lightning_sdk/llm/llm.py +29 -8
- lightning_sdk/machine.py +1 -4
- lightning_sdk/pipeline/pipeline.py +1 -15
- {lightning_sdk-0.2.24rc1.dist-info → lightning_sdk-2025.7.10.dist-info}/METADATA +1 -1
- {lightning_sdk-0.2.24rc1.dist-info → lightning_sdk-2025.7.10.dist-info}/RECORD +19 -19
- {lightning_sdk-0.2.24rc1.dist-info → lightning_sdk-2025.7.10.dist-info}/LICENSE +0 -0
- {lightning_sdk-0.2.24rc1.dist-info → lightning_sdk-2025.7.10.dist-info}/WHEEL +0 -0
- {lightning_sdk-0.2.24rc1.dist-info → lightning_sdk-2025.7.10.dist-info}/entry_points.txt +0 -0
- {lightning_sdk-0.2.24rc1.dist-info → lightning_sdk-2025.7.10.dist-info}/top_level.txt +0 -0
lightning_sdk/__init__.py
CHANGED
lightning_sdk/api/cluster_api.py
CHANGED
|
@@ -4,6 +4,7 @@ from lightning_sdk.lightning_cloud.openapi import (
|
|
|
4
4
|
Externalv1Cluster,
|
|
5
5
|
V1CloudProvider,
|
|
6
6
|
V1ClusterType,
|
|
7
|
+
V1ExternalCluster,
|
|
7
8
|
V1ListClusterAcceleratorsResponse,
|
|
8
9
|
)
|
|
9
10
|
from lightning_sdk.lightning_cloud.rest_client import LightningClient
|
|
@@ -28,6 +29,20 @@ class ClusterApi:
|
|
|
28
29
|
raise ValueError(f"Cluster {cluster_id} does not exist")
|
|
29
30
|
return res
|
|
30
31
|
|
|
32
|
+
def list_clusters(self, project_id: str) -> List[V1ExternalCluster]:
|
|
33
|
+
"""Lists the clusters for a given project.
|
|
34
|
+
|
|
35
|
+
Args:
|
|
36
|
+
project_id: The project to list clusters for
|
|
37
|
+
|
|
38
|
+
Returns:
|
|
39
|
+
A list of clusters
|
|
40
|
+
"""
|
|
41
|
+
res = self._client.cluster_service_list_project_clusters(
|
|
42
|
+
project_id=project_id,
|
|
43
|
+
)
|
|
44
|
+
return res.clusters
|
|
45
|
+
|
|
31
46
|
def list_cluster_accelerators(self, cluster_id: str, org_id: str) -> V1ListClusterAcceleratorsResponse:
|
|
32
47
|
"""Lists the accelerators for a given cluster.
|
|
33
48
|
|
lightning_sdk/api/llm_api.py
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import asyncio
|
|
2
2
|
import base64
|
|
3
|
+
import datetime
|
|
3
4
|
import json
|
|
4
5
|
import os
|
|
5
6
|
import threading
|
|
@@ -46,6 +47,8 @@ class LLMApi:
|
|
|
46
47
|
executable=result_data.get("executable"),
|
|
47
48
|
id=result_data.get("id"),
|
|
48
49
|
throughput=result_data.get("throughput"),
|
|
50
|
+
stats=result_data.get("stats"),
|
|
51
|
+
usage=result_data.get("usage"),
|
|
49
52
|
)
|
|
50
53
|
except json.JSONDecodeError:
|
|
51
54
|
warnings.warn("Error decoding JSON:", decoded_line)
|
|
@@ -158,6 +161,7 @@ class LLMApi:
|
|
|
158
161
|
"ephemeral": ephemeral,
|
|
159
162
|
"parent_conversation_id": kwargs.get("parent_conversation_id", ""),
|
|
160
163
|
"parent_message_id": kwargs.get("parent_message_id", ""),
|
|
164
|
+
"sent_at": datetime.datetime.now(datetime.timezone.utc).isoformat(timespec="microseconds"),
|
|
161
165
|
}
|
|
162
166
|
if images:
|
|
163
167
|
for image in images:
|
|
@@ -55,7 +55,7 @@ class PipelineApi:
|
|
|
55
55
|
body = ProjectIdPipelinesBody(
|
|
56
56
|
name=name,
|
|
57
57
|
steps=steps,
|
|
58
|
-
shared_filesystem=self.
|
|
58
|
+
shared_filesystem=self._prepare_shared_filesystem(shared_filesystem, steps, teamspace),
|
|
59
59
|
parent_pipeline_id=parent_pipeline_id or "",
|
|
60
60
|
)
|
|
61
61
|
|
|
@@ -89,7 +89,7 @@ class PipelineApi:
|
|
|
89
89
|
def delete(self, project_id: str, pipeline_id: str) -> V1DeletePipelineResponse:
|
|
90
90
|
return self._client.pipelines_service_delete_pipeline(project_id, pipeline_id)
|
|
91
91
|
|
|
92
|
-
def
|
|
92
|
+
def _prepare_shared_filesystem(
|
|
93
93
|
self, shared_filesystem: Union[bool, V1SharedFilesystem], steps: List["V1PipelineStep"], teamspace: Teamspace
|
|
94
94
|
) -> V1SharedFilesystem:
|
|
95
95
|
if not shared_filesystem:
|
|
@@ -97,14 +97,22 @@ class PipelineApi:
|
|
|
97
97
|
|
|
98
98
|
from lightning_sdk.pipeline.utils import _get_cloud_account
|
|
99
99
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
100
|
+
clusters = self._cluster_api.list_clusters(project_id=teamspace.id)
|
|
101
|
+
|
|
102
|
+
selected_cluster = None
|
|
103
|
+
selected_cluster_id = _get_cloud_account(steps)
|
|
104
|
+
for cluster in clusters:
|
|
105
|
+
if cluster.id == selected_cluster_id:
|
|
106
|
+
selected_cluster = cluster
|
|
107
|
+
break
|
|
108
|
+
|
|
109
|
+
if selected_cluster is None:
|
|
110
|
+
raise ValueError(f"Cloud Account {selected_cluster_id} not found")
|
|
103
111
|
|
|
104
|
-
if
|
|
112
|
+
if selected_cluster.spec.aws_v1:
|
|
105
113
|
return V1SharedFilesystem(enabled=True, s3_folder=True)
|
|
106
114
|
|
|
107
|
-
if
|
|
115
|
+
if selected_cluster.spec.google_cloud_v1:
|
|
108
116
|
return V1SharedFilesystem(enabled=True, gcs_folder=True)
|
|
109
117
|
|
|
110
118
|
raise NotImplementedError("This cluster isn't support yet")
|
lightning_sdk/api/studio_api.py
CHANGED
|
@@ -2,7 +2,6 @@ import json
|
|
|
2
2
|
import os
|
|
3
3
|
import tempfile
|
|
4
4
|
import time
|
|
5
|
-
import warnings
|
|
6
5
|
import zipfile
|
|
7
6
|
from threading import Event, Thread
|
|
8
7
|
from typing import Any, Dict, Generator, Mapping, Optional, Tuple, Union
|
|
@@ -172,14 +171,6 @@ class StudioApi:
|
|
|
172
171
|
self, studio_id: str, teamspace_id: str, machine: Union[Machine, str], interruptible: False
|
|
173
172
|
) -> None:
|
|
174
173
|
"""Start an existing Studio."""
|
|
175
|
-
if _machine_to_compute_name(machine) == _machine_to_compute_name(Machine.CPU_SMALL):
|
|
176
|
-
warnings.warn(
|
|
177
|
-
f"{Machine.CPU_SMALL} is not a valid machine for starting a Studio. "
|
|
178
|
-
"It is reserved for running jobs only. "
|
|
179
|
-
"The Studio will be started with a CPU machine instead."
|
|
180
|
-
)
|
|
181
|
-
machine = Machine.CPU
|
|
182
|
-
|
|
183
174
|
self._client.cloud_space_service_start_cloud_space_instance(
|
|
184
175
|
IdStartBody(
|
|
185
176
|
compute_config=V1UserRequestedComputeConfig(name=_machine_to_compute_name(machine), spot=interruptible)
|
|
@@ -229,14 +220,6 @@ class StudioApi:
|
|
|
229
220
|
self, studio_id: str, teamspace_id: str, machine: Union[Machine, str], interruptible: bool
|
|
230
221
|
) -> None:
|
|
231
222
|
"""Switches given Studio to a new machine type."""
|
|
232
|
-
if _machine_to_compute_name(machine) == _machine_to_compute_name(Machine.CPU_SMALL):
|
|
233
|
-
warnings.warn(
|
|
234
|
-
f"{Machine.CPU_SMALL} is not a valid machine for switching a Studio. "
|
|
235
|
-
"It is reserved for running jobs only. "
|
|
236
|
-
"The Studio will be switched to a CPU machine instead."
|
|
237
|
-
)
|
|
238
|
-
machine = Machine.CPU
|
|
239
|
-
|
|
240
223
|
compute_name = _machine_to_compute_name(machine)
|
|
241
224
|
# TODO: UI sends disk size here, maybe we need to also?
|
|
242
225
|
body = IdCodeconfigBody(compute_config=V1UserRequestedComputeConfig(name=compute_name, spot=interruptible))
|
lightning_sdk/job/base.py
CHANGED
|
@@ -296,6 +296,27 @@ class _BaseJob(ABC):
|
|
|
296
296
|
|
|
297
297
|
time.sleep(interval)
|
|
298
298
|
|
|
299
|
+
async def async_wait(self, interval: float = 5.0, timeout: Optional[float] = None) -> None:
|
|
300
|
+
"""Waits for the job to be either completed, manually stopped or failed.
|
|
301
|
+
|
|
302
|
+
Args:
|
|
303
|
+
interval: The number of seconds to spend in-between status checks.
|
|
304
|
+
timeout: The maximum number of seconds to wait before raising an error. If None, waits forever.
|
|
305
|
+
"""
|
|
306
|
+
import asyncio
|
|
307
|
+
|
|
308
|
+
from lightning_sdk.status import Status
|
|
309
|
+
|
|
310
|
+
start = asyncio.get_event_loop().time()
|
|
311
|
+
while True:
|
|
312
|
+
if self.status in (Status.Completed, Status.Stopped, Status.Failed):
|
|
313
|
+
break
|
|
314
|
+
|
|
315
|
+
if timeout is not None and asyncio.get_event_loop().time() - start > timeout:
|
|
316
|
+
raise TimeoutError("Job didn't finish within the provided timeout.")
|
|
317
|
+
|
|
318
|
+
await asyncio.sleep(interval)
|
|
319
|
+
|
|
299
320
|
@property
|
|
300
321
|
@abstractmethod
|
|
301
322
|
def status(self) -> "Status":
|
|
@@ -53,6 +53,7 @@ class AssistantIdConversationsBody(object):
|
|
|
53
53
|
'parent_conversation_id': 'str',
|
|
54
54
|
'parent_message_id': 'str',
|
|
55
55
|
'reasoning_effort': 'str',
|
|
56
|
+
'sent_at': 'datetime',
|
|
56
57
|
'store': 'bool',
|
|
57
58
|
'stream': 'bool',
|
|
58
59
|
'system_prompt': 'str'
|
|
@@ -71,12 +72,13 @@ class AssistantIdConversationsBody(object):
|
|
|
71
72
|
'parent_conversation_id': 'parentConversationId',
|
|
72
73
|
'parent_message_id': 'parentMessageId',
|
|
73
74
|
'reasoning_effort': 'reasoningEffort',
|
|
75
|
+
'sent_at': 'sentAt',
|
|
74
76
|
'store': 'store',
|
|
75
77
|
'stream': 'stream',
|
|
76
78
|
'system_prompt': 'systemPrompt'
|
|
77
79
|
}
|
|
78
80
|
|
|
79
|
-
def __init__(self, auto_name: 'bool' =None, billing_project_id: 'str' =None, conversation_id: 'str' =None, ephemeral: 'bool' =None, internal_conversation: 'bool' =None, max_tokens: 'str' =None, message: 'V1Message' =None, metadata: 'dict(str, str)' =None, name: 'str' =None, parent_conversation_id: 'str' =None, parent_message_id: 'str' =None, reasoning_effort: 'str' =None, store: 'bool' =None, stream: 'bool' =None, system_prompt: 'str' =None): # noqa: E501
|
|
81
|
+
def __init__(self, auto_name: 'bool' =None, billing_project_id: 'str' =None, conversation_id: 'str' =None, ephemeral: 'bool' =None, internal_conversation: 'bool' =None, max_tokens: 'str' =None, message: 'V1Message' =None, metadata: 'dict(str, str)' =None, name: 'str' =None, parent_conversation_id: 'str' =None, parent_message_id: 'str' =None, reasoning_effort: 'str' =None, sent_at: 'datetime' =None, store: 'bool' =None, stream: 'bool' =None, system_prompt: 'str' =None): # noqa: E501
|
|
80
82
|
"""AssistantIdConversationsBody - a model defined in Swagger""" # noqa: E501
|
|
81
83
|
self._auto_name = None
|
|
82
84
|
self._billing_project_id = None
|
|
@@ -90,6 +92,7 @@ class AssistantIdConversationsBody(object):
|
|
|
90
92
|
self._parent_conversation_id = None
|
|
91
93
|
self._parent_message_id = None
|
|
92
94
|
self._reasoning_effort = None
|
|
95
|
+
self._sent_at = None
|
|
93
96
|
self._store = None
|
|
94
97
|
self._stream = None
|
|
95
98
|
self._system_prompt = None
|
|
@@ -118,6 +121,8 @@ class AssistantIdConversationsBody(object):
|
|
|
118
121
|
self.parent_message_id = parent_message_id
|
|
119
122
|
if reasoning_effort is not None:
|
|
120
123
|
self.reasoning_effort = reasoning_effort
|
|
124
|
+
if sent_at is not None:
|
|
125
|
+
self.sent_at = sent_at
|
|
121
126
|
if store is not None:
|
|
122
127
|
self.store = store
|
|
123
128
|
if stream is not None:
|
|
@@ -377,6 +382,27 @@ class AssistantIdConversationsBody(object):
|
|
|
377
382
|
|
|
378
383
|
self._reasoning_effort = reasoning_effort
|
|
379
384
|
|
|
385
|
+
@property
|
|
386
|
+
def sent_at(self) -> 'datetime':
|
|
387
|
+
"""Gets the sent_at of this AssistantIdConversationsBody. # noqa: E501
|
|
388
|
+
|
|
389
|
+
|
|
390
|
+
:return: The sent_at of this AssistantIdConversationsBody. # noqa: E501
|
|
391
|
+
:rtype: datetime
|
|
392
|
+
"""
|
|
393
|
+
return self._sent_at
|
|
394
|
+
|
|
395
|
+
@sent_at.setter
|
|
396
|
+
def sent_at(self, sent_at: 'datetime'):
|
|
397
|
+
"""Sets the sent_at of this AssistantIdConversationsBody.
|
|
398
|
+
|
|
399
|
+
|
|
400
|
+
:param sent_at: The sent_at of this AssistantIdConversationsBody. # noqa: E501
|
|
401
|
+
:type: datetime
|
|
402
|
+
"""
|
|
403
|
+
|
|
404
|
+
self._sent_at = sent_at
|
|
405
|
+
|
|
380
406
|
@property
|
|
381
407
|
def store(self) -> 'bool':
|
|
382
408
|
"""Gets the store of this AssistantIdConversationsBody. # noqa: E501
|
|
@@ -46,6 +46,7 @@ class V1ConversationResponseChunk(object):
|
|
|
46
46
|
'executable': 'bool',
|
|
47
47
|
'id': 'str',
|
|
48
48
|
'object': 'str',
|
|
49
|
+
'stats': 'dict(str, str)',
|
|
49
50
|
'throughput': 'float',
|
|
50
51
|
'usage': 'V1TokenUsage'
|
|
51
52
|
}
|
|
@@ -56,17 +57,19 @@ class V1ConversationResponseChunk(object):
|
|
|
56
57
|
'executable': 'executable',
|
|
57
58
|
'id': 'id',
|
|
58
59
|
'object': 'object',
|
|
60
|
+
'stats': 'stats',
|
|
59
61
|
'throughput': 'throughput',
|
|
60
62
|
'usage': 'usage'
|
|
61
63
|
}
|
|
62
64
|
|
|
63
|
-
def __init__(self, choices: 'list[V1ResponseChoice]' =None, conversation_id: 'str' =None, executable: 'bool' =None, id: 'str' =None, object: 'str' =None, throughput: 'float' =None, usage: 'V1TokenUsage' =None): # noqa: E501
|
|
65
|
+
def __init__(self, choices: 'list[V1ResponseChoice]' =None, conversation_id: 'str' =None, executable: 'bool' =None, id: 'str' =None, object: 'str' =None, stats: 'dict(str, str)' =None, throughput: 'float' =None, usage: 'V1TokenUsage' =None): # noqa: E501
|
|
64
66
|
"""V1ConversationResponseChunk - a model defined in Swagger""" # noqa: E501
|
|
65
67
|
self._choices = None
|
|
66
68
|
self._conversation_id = None
|
|
67
69
|
self._executable = None
|
|
68
70
|
self._id = None
|
|
69
71
|
self._object = None
|
|
72
|
+
self._stats = None
|
|
70
73
|
self._throughput = None
|
|
71
74
|
self._usage = None
|
|
72
75
|
self.discriminator = None
|
|
@@ -80,6 +83,8 @@ class V1ConversationResponseChunk(object):
|
|
|
80
83
|
self.id = id
|
|
81
84
|
if object is not None:
|
|
82
85
|
self.object = object
|
|
86
|
+
if stats is not None:
|
|
87
|
+
self.stats = stats
|
|
83
88
|
if throughput is not None:
|
|
84
89
|
self.throughput = throughput
|
|
85
90
|
if usage is not None:
|
|
@@ -190,6 +195,27 @@ class V1ConversationResponseChunk(object):
|
|
|
190
195
|
|
|
191
196
|
self._object = object
|
|
192
197
|
|
|
198
|
+
@property
|
|
199
|
+
def stats(self) -> 'dict(str, str)':
|
|
200
|
+
"""Gets the stats of this V1ConversationResponseChunk. # noqa: E501
|
|
201
|
+
|
|
202
|
+
|
|
203
|
+
:return: The stats of this V1ConversationResponseChunk. # noqa: E501
|
|
204
|
+
:rtype: dict(str, str)
|
|
205
|
+
"""
|
|
206
|
+
return self._stats
|
|
207
|
+
|
|
208
|
+
@stats.setter
|
|
209
|
+
def stats(self, stats: 'dict(str, str)'):
|
|
210
|
+
"""Sets the stats of this V1ConversationResponseChunk.
|
|
211
|
+
|
|
212
|
+
|
|
213
|
+
:param stats: The stats of this V1ConversationResponseChunk. # noqa: E501
|
|
214
|
+
:type: dict(str, str)
|
|
215
|
+
"""
|
|
216
|
+
|
|
217
|
+
self._stats = stats
|
|
218
|
+
|
|
193
219
|
@property
|
|
194
220
|
def throughput(self) -> 'float':
|
|
195
221
|
"""Gets the throughput of this V1ConversationResponseChunk. # noqa: E501
|
|
@@ -42,7 +42,6 @@ class V1UserFeatures(object):
|
|
|
42
42
|
"""
|
|
43
43
|
swagger_types = {
|
|
44
44
|
'academic_tier': 'bool',
|
|
45
|
-
'accurate_billing': 'bool',
|
|
46
45
|
'add_data_v2': 'bool',
|
|
47
46
|
'affiliate_links': 'bool',
|
|
48
47
|
'agents_v2': 'bool',
|
|
@@ -59,7 +58,6 @@ class V1UserFeatures(object):
|
|
|
59
58
|
'cloudy_vibe_code': 'bool',
|
|
60
59
|
'code_tab': 'bool',
|
|
61
60
|
'collab_screen_sharing': 'bool',
|
|
62
|
-
'concurrent_gpu_limit': 'bool',
|
|
63
61
|
'control_center_monitoring': 'bool',
|
|
64
62
|
'cost_attribution_settings': 'bool',
|
|
65
63
|
'custom_app_domain': 'bool',
|
|
@@ -76,17 +74,18 @@ class V1UserFeatures(object):
|
|
|
76
74
|
'gcs_fuse': 'bool',
|
|
77
75
|
'instant_capacity_reservation': 'bool',
|
|
78
76
|
'job_artifacts_v2': 'bool',
|
|
77
|
+
'kubernetes_cluster_ui': 'bool',
|
|
79
78
|
'kubernetes_clusters': 'bool',
|
|
80
79
|
'lambda_labs': 'bool',
|
|
81
80
|
'lambda_labs_studios': 'bool',
|
|
82
81
|
'landing_studios': 'bool',
|
|
83
82
|
'lit_logger': 'bool',
|
|
84
|
-
'litcr_byoc_gcp': 'bool',
|
|
85
83
|
'machine_selector_v2': 'bool',
|
|
86
84
|
'marketplace': 'bool',
|
|
87
85
|
'mmt_fault_tolerance': 'bool',
|
|
88
86
|
'mmt_strategy_selector': 'bool',
|
|
89
87
|
'model_api_dashboard': 'bool',
|
|
88
|
+
'model_api_dashboard_clickhouse': 'bool',
|
|
90
89
|
'multicloud_folders': 'bool',
|
|
91
90
|
'multicloud_saas': 'bool',
|
|
92
91
|
'multiple_studio_versions': 'bool',
|
|
@@ -136,7 +135,6 @@ class V1UserFeatures(object):
|
|
|
136
135
|
|
|
137
136
|
attribute_map = {
|
|
138
137
|
'academic_tier': 'academicTier',
|
|
139
|
-
'accurate_billing': 'accurateBilling',
|
|
140
138
|
'add_data_v2': 'addDataV2',
|
|
141
139
|
'affiliate_links': 'affiliateLinks',
|
|
142
140
|
'agents_v2': 'agentsV2',
|
|
@@ -153,7 +151,6 @@ class V1UserFeatures(object):
|
|
|
153
151
|
'cloudy_vibe_code': 'cloudyVibeCode',
|
|
154
152
|
'code_tab': 'codeTab',
|
|
155
153
|
'collab_screen_sharing': 'collabScreenSharing',
|
|
156
|
-
'concurrent_gpu_limit': 'concurrentGpuLimit',
|
|
157
154
|
'control_center_monitoring': 'controlCenterMonitoring',
|
|
158
155
|
'cost_attribution_settings': 'costAttributionSettings',
|
|
159
156
|
'custom_app_domain': 'customAppDomain',
|
|
@@ -170,17 +167,18 @@ class V1UserFeatures(object):
|
|
|
170
167
|
'gcs_fuse': 'gcsFuse',
|
|
171
168
|
'instant_capacity_reservation': 'instantCapacityReservation',
|
|
172
169
|
'job_artifacts_v2': 'jobArtifactsV2',
|
|
170
|
+
'kubernetes_cluster_ui': 'kubernetesClusterUi',
|
|
173
171
|
'kubernetes_clusters': 'kubernetesClusters',
|
|
174
172
|
'lambda_labs': 'lambdaLabs',
|
|
175
173
|
'lambda_labs_studios': 'lambdaLabsStudios',
|
|
176
174
|
'landing_studios': 'landingStudios',
|
|
177
175
|
'lit_logger': 'litLogger',
|
|
178
|
-
'litcr_byoc_gcp': 'litcrByocGcp',
|
|
179
176
|
'machine_selector_v2': 'machineSelectorV2',
|
|
180
177
|
'marketplace': 'marketplace',
|
|
181
178
|
'mmt_fault_tolerance': 'mmtFaultTolerance',
|
|
182
179
|
'mmt_strategy_selector': 'mmtStrategySelector',
|
|
183
180
|
'model_api_dashboard': 'modelApiDashboard',
|
|
181
|
+
'model_api_dashboard_clickhouse': 'modelApiDashboardClickhouse',
|
|
184
182
|
'multicloud_folders': 'multicloudFolders',
|
|
185
183
|
'multicloud_saas': 'multicloudSaas',
|
|
186
184
|
'multiple_studio_versions': 'multipleStudioVersions',
|
|
@@ -228,10 +226,9 @@ class V1UserFeatures(object):
|
|
|
228
226
|
'writable_s3_connections': 'writableS3Connections'
|
|
229
227
|
}
|
|
230
228
|
|
|
231
|
-
def __init__(self, academic_tier: 'bool' =None,
|
|
229
|
+
def __init__(self, academic_tier: 'bool' =None, add_data_v2: 'bool' =None, affiliate_links: 'bool' =None, agents_v2: 'bool' =None, ai_hub_monetization: 'bool' =None, auto_fast_load: 'bool' =None, auto_join_orgs: 'bool' =None, b2c_experience: 'bool' =None, cap_add: 'list[str]' =None, cap_drop: 'list[str]' =None, capacity_reservation_byoc: 'bool' =None, capacity_reservation_dry_run: 'bool' =None, chat_models: 'bool' =None, cloudspace_schedules: 'bool' =None, cloudy_vibe_code: 'bool' =None, code_tab: 'bool' =None, collab_screen_sharing: 'bool' =None, control_center_monitoring: 'bool' =None, cost_attribution_settings: 'bool' =None, custom_app_domain: 'bool' =None, data_connection_flushing_v2: 'bool' =None, datasets: 'bool' =None, default_one_cluster: 'bool' =None, deployment_persistent_disk: 'bool' =None, drive_v2: 'bool' =None, enterprise_compute_admin: 'bool' =None, fair_share: 'bool' =None, featured_studios_admin: 'bool' =None, gcs_connections_optimized: 'bool' =None, gcs_folders: 'bool' =None, gcs_fuse: 'bool' =None, instant_capacity_reservation: 'bool' =None, job_artifacts_v2: 'bool' =None, kubernetes_cluster_ui: 'bool' =None, kubernetes_clusters: 'bool' =None, lambda_labs: 'bool' =None, lambda_labs_studios: 'bool' =None, landing_studios: 'bool' =None, lit_logger: 'bool' =None, machine_selector_v2: 'bool' =None, marketplace: 'bool' =None, mmt_fault_tolerance: 'bool' =None, mmt_strategy_selector: 'bool' =None, model_api_dashboard: 'bool' =None, model_api_dashboard_clickhouse: 'bool' =None, multicloud_folders: 'bool' =None, multicloud_saas: 'bool' =None, multiple_studio_versions: 'bool' =None, nebius: 'bool' =None, nebius_cpu_studios: 'bool' =None, nebius_gpu_studios: 'bool' =None, nerf_fs_nonpaying: 'bool' =None, onboarding_v2: 'bool' =None, org_level_member_permissions: 'bool' =None, org_usage_limits: 'bool' =None, paygo_free_storage_limit_check: 'bool' =None, persistent_disk: 'bool' =None, plugin_distributed: 'bool' =None, plugin_inference: 'bool' =None, plugin_label_studio: 'bool' =None, plugin_langflow: 'bool' =None, plugin_python_profiler: 'bool' =None, plugin_service: 'bool' =None, plugin_sweeps: 'bool' =None, pricing_updates: 'bool' =None, product_generator: 'bool' =None, product_license: 'bool' =None, project_selector: 'bool' =None, publish_pipelines: 'bool' =None, r2_data_connections: 'bool' =None, reserved_machines_tab: 'bool' =None, restartable_jobs: 'bool' =None, runnable_public_studio_page: 'bool' =None, security_docs: 'bool' =None, show_dev_admin: 'bool' =None, single_wallet: 'bool' =None, slurm: 'bool' =None, specialised_studios: 'bool' =None, storage_overuse_deletion: 'bool' =None, studio_config: 'bool' =None, studio_sharing_v2: 'bool' =None, studio_version_visibility: 'bool' =None, trainium2: 'bool' =None, use_internal_data_connection_mounts: 'bool' =None, use_rclone_mounts_only: 'bool' =None, voltage_park: 'bool' =None, voltage_park_studios: 'bool' =None, vultr: 'bool' =None, weka: 'bool' =None, writable_s3_connections: 'bool' =None): # noqa: E501
|
|
232
230
|
"""V1UserFeatures - a model defined in Swagger""" # noqa: E501
|
|
233
231
|
self._academic_tier = None
|
|
234
|
-
self._accurate_billing = None
|
|
235
232
|
self._add_data_v2 = None
|
|
236
233
|
self._affiliate_links = None
|
|
237
234
|
self._agents_v2 = None
|
|
@@ -248,7 +245,6 @@ class V1UserFeatures(object):
|
|
|
248
245
|
self._cloudy_vibe_code = None
|
|
249
246
|
self._code_tab = None
|
|
250
247
|
self._collab_screen_sharing = None
|
|
251
|
-
self._concurrent_gpu_limit = None
|
|
252
248
|
self._control_center_monitoring = None
|
|
253
249
|
self._cost_attribution_settings = None
|
|
254
250
|
self._custom_app_domain = None
|
|
@@ -265,17 +261,18 @@ class V1UserFeatures(object):
|
|
|
265
261
|
self._gcs_fuse = None
|
|
266
262
|
self._instant_capacity_reservation = None
|
|
267
263
|
self._job_artifacts_v2 = None
|
|
264
|
+
self._kubernetes_cluster_ui = None
|
|
268
265
|
self._kubernetes_clusters = None
|
|
269
266
|
self._lambda_labs = None
|
|
270
267
|
self._lambda_labs_studios = None
|
|
271
268
|
self._landing_studios = None
|
|
272
269
|
self._lit_logger = None
|
|
273
|
-
self._litcr_byoc_gcp = None
|
|
274
270
|
self._machine_selector_v2 = None
|
|
275
271
|
self._marketplace = None
|
|
276
272
|
self._mmt_fault_tolerance = None
|
|
277
273
|
self._mmt_strategy_selector = None
|
|
278
274
|
self._model_api_dashboard = None
|
|
275
|
+
self._model_api_dashboard_clickhouse = None
|
|
279
276
|
self._multicloud_folders = None
|
|
280
277
|
self._multicloud_saas = None
|
|
281
278
|
self._multiple_studio_versions = None
|
|
@@ -324,8 +321,6 @@ class V1UserFeatures(object):
|
|
|
324
321
|
self.discriminator = None
|
|
325
322
|
if academic_tier is not None:
|
|
326
323
|
self.academic_tier = academic_tier
|
|
327
|
-
if accurate_billing is not None:
|
|
328
|
-
self.accurate_billing = accurate_billing
|
|
329
324
|
if add_data_v2 is not None:
|
|
330
325
|
self.add_data_v2 = add_data_v2
|
|
331
326
|
if affiliate_links is not None:
|
|
@@ -358,8 +353,6 @@ class V1UserFeatures(object):
|
|
|
358
353
|
self.code_tab = code_tab
|
|
359
354
|
if collab_screen_sharing is not None:
|
|
360
355
|
self.collab_screen_sharing = collab_screen_sharing
|
|
361
|
-
if concurrent_gpu_limit is not None:
|
|
362
|
-
self.concurrent_gpu_limit = concurrent_gpu_limit
|
|
363
356
|
if control_center_monitoring is not None:
|
|
364
357
|
self.control_center_monitoring = control_center_monitoring
|
|
365
358
|
if cost_attribution_settings is not None:
|
|
@@ -392,6 +385,8 @@ class V1UserFeatures(object):
|
|
|
392
385
|
self.instant_capacity_reservation = instant_capacity_reservation
|
|
393
386
|
if job_artifacts_v2 is not None:
|
|
394
387
|
self.job_artifacts_v2 = job_artifacts_v2
|
|
388
|
+
if kubernetes_cluster_ui is not None:
|
|
389
|
+
self.kubernetes_cluster_ui = kubernetes_cluster_ui
|
|
395
390
|
if kubernetes_clusters is not None:
|
|
396
391
|
self.kubernetes_clusters = kubernetes_clusters
|
|
397
392
|
if lambda_labs is not None:
|
|
@@ -402,8 +397,6 @@ class V1UserFeatures(object):
|
|
|
402
397
|
self.landing_studios = landing_studios
|
|
403
398
|
if lit_logger is not None:
|
|
404
399
|
self.lit_logger = lit_logger
|
|
405
|
-
if litcr_byoc_gcp is not None:
|
|
406
|
-
self.litcr_byoc_gcp = litcr_byoc_gcp
|
|
407
400
|
if machine_selector_v2 is not None:
|
|
408
401
|
self.machine_selector_v2 = machine_selector_v2
|
|
409
402
|
if marketplace is not None:
|
|
@@ -414,6 +407,8 @@ class V1UserFeatures(object):
|
|
|
414
407
|
self.mmt_strategy_selector = mmt_strategy_selector
|
|
415
408
|
if model_api_dashboard is not None:
|
|
416
409
|
self.model_api_dashboard = model_api_dashboard
|
|
410
|
+
if model_api_dashboard_clickhouse is not None:
|
|
411
|
+
self.model_api_dashboard_clickhouse = model_api_dashboard_clickhouse
|
|
417
412
|
if multicloud_folders is not None:
|
|
418
413
|
self.multicloud_folders = multicloud_folders
|
|
419
414
|
if multicloud_saas is not None:
|
|
@@ -526,27 +521,6 @@ class V1UserFeatures(object):
|
|
|
526
521
|
|
|
527
522
|
self._academic_tier = academic_tier
|
|
528
523
|
|
|
529
|
-
@property
|
|
530
|
-
def accurate_billing(self) -> 'bool':
|
|
531
|
-
"""Gets the accurate_billing of this V1UserFeatures. # noqa: E501
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
:return: The accurate_billing of this V1UserFeatures. # noqa: E501
|
|
535
|
-
:rtype: bool
|
|
536
|
-
"""
|
|
537
|
-
return self._accurate_billing
|
|
538
|
-
|
|
539
|
-
@accurate_billing.setter
|
|
540
|
-
def accurate_billing(self, accurate_billing: 'bool'):
|
|
541
|
-
"""Sets the accurate_billing of this V1UserFeatures.
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
:param accurate_billing: The accurate_billing of this V1UserFeatures. # noqa: E501
|
|
545
|
-
:type: bool
|
|
546
|
-
"""
|
|
547
|
-
|
|
548
|
-
self._accurate_billing = accurate_billing
|
|
549
|
-
|
|
550
524
|
@property
|
|
551
525
|
def add_data_v2(self) -> 'bool':
|
|
552
526
|
"""Gets the add_data_v2 of this V1UserFeatures. # noqa: E501
|
|
@@ -883,27 +857,6 @@ class V1UserFeatures(object):
|
|
|
883
857
|
|
|
884
858
|
self._collab_screen_sharing = collab_screen_sharing
|
|
885
859
|
|
|
886
|
-
@property
|
|
887
|
-
def concurrent_gpu_limit(self) -> 'bool':
|
|
888
|
-
"""Gets the concurrent_gpu_limit of this V1UserFeatures. # noqa: E501
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
:return: The concurrent_gpu_limit of this V1UserFeatures. # noqa: E501
|
|
892
|
-
:rtype: bool
|
|
893
|
-
"""
|
|
894
|
-
return self._concurrent_gpu_limit
|
|
895
|
-
|
|
896
|
-
@concurrent_gpu_limit.setter
|
|
897
|
-
def concurrent_gpu_limit(self, concurrent_gpu_limit: 'bool'):
|
|
898
|
-
"""Sets the concurrent_gpu_limit of this V1UserFeatures.
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
:param concurrent_gpu_limit: The concurrent_gpu_limit of this V1UserFeatures. # noqa: E501
|
|
902
|
-
:type: bool
|
|
903
|
-
"""
|
|
904
|
-
|
|
905
|
-
self._concurrent_gpu_limit = concurrent_gpu_limit
|
|
906
|
-
|
|
907
860
|
@property
|
|
908
861
|
def control_center_monitoring(self) -> 'bool':
|
|
909
862
|
"""Gets the control_center_monitoring of this V1UserFeatures. # noqa: E501
|
|
@@ -1240,6 +1193,27 @@ class V1UserFeatures(object):
|
|
|
1240
1193
|
|
|
1241
1194
|
self._job_artifacts_v2 = job_artifacts_v2
|
|
1242
1195
|
|
|
1196
|
+
@property
|
|
1197
|
+
def kubernetes_cluster_ui(self) -> 'bool':
|
|
1198
|
+
"""Gets the kubernetes_cluster_ui of this V1UserFeatures. # noqa: E501
|
|
1199
|
+
|
|
1200
|
+
|
|
1201
|
+
:return: The kubernetes_cluster_ui of this V1UserFeatures. # noqa: E501
|
|
1202
|
+
:rtype: bool
|
|
1203
|
+
"""
|
|
1204
|
+
return self._kubernetes_cluster_ui
|
|
1205
|
+
|
|
1206
|
+
@kubernetes_cluster_ui.setter
|
|
1207
|
+
def kubernetes_cluster_ui(self, kubernetes_cluster_ui: 'bool'):
|
|
1208
|
+
"""Sets the kubernetes_cluster_ui of this V1UserFeatures.
|
|
1209
|
+
|
|
1210
|
+
|
|
1211
|
+
:param kubernetes_cluster_ui: The kubernetes_cluster_ui of this V1UserFeatures. # noqa: E501
|
|
1212
|
+
:type: bool
|
|
1213
|
+
"""
|
|
1214
|
+
|
|
1215
|
+
self._kubernetes_cluster_ui = kubernetes_cluster_ui
|
|
1216
|
+
|
|
1243
1217
|
@property
|
|
1244
1218
|
def kubernetes_clusters(self) -> 'bool':
|
|
1245
1219
|
"""Gets the kubernetes_clusters of this V1UserFeatures. # noqa: E501
|
|
@@ -1345,27 +1319,6 @@ class V1UserFeatures(object):
|
|
|
1345
1319
|
|
|
1346
1320
|
self._lit_logger = lit_logger
|
|
1347
1321
|
|
|
1348
|
-
@property
|
|
1349
|
-
def litcr_byoc_gcp(self) -> 'bool':
|
|
1350
|
-
"""Gets the litcr_byoc_gcp of this V1UserFeatures. # noqa: E501
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
:return: The litcr_byoc_gcp of this V1UserFeatures. # noqa: E501
|
|
1354
|
-
:rtype: bool
|
|
1355
|
-
"""
|
|
1356
|
-
return self._litcr_byoc_gcp
|
|
1357
|
-
|
|
1358
|
-
@litcr_byoc_gcp.setter
|
|
1359
|
-
def litcr_byoc_gcp(self, litcr_byoc_gcp: 'bool'):
|
|
1360
|
-
"""Sets the litcr_byoc_gcp of this V1UserFeatures.
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
:param litcr_byoc_gcp: The litcr_byoc_gcp of this V1UserFeatures. # noqa: E501
|
|
1364
|
-
:type: bool
|
|
1365
|
-
"""
|
|
1366
|
-
|
|
1367
|
-
self._litcr_byoc_gcp = litcr_byoc_gcp
|
|
1368
|
-
|
|
1369
1322
|
@property
|
|
1370
1323
|
def machine_selector_v2(self) -> 'bool':
|
|
1371
1324
|
"""Gets the machine_selector_v2 of this V1UserFeatures. # noqa: E501
|
|
@@ -1471,6 +1424,27 @@ class V1UserFeatures(object):
|
|
|
1471
1424
|
|
|
1472
1425
|
self._model_api_dashboard = model_api_dashboard
|
|
1473
1426
|
|
|
1427
|
+
@property
|
|
1428
|
+
def model_api_dashboard_clickhouse(self) -> 'bool':
|
|
1429
|
+
"""Gets the model_api_dashboard_clickhouse of this V1UserFeatures. # noqa: E501
|
|
1430
|
+
|
|
1431
|
+
|
|
1432
|
+
:return: The model_api_dashboard_clickhouse of this V1UserFeatures. # noqa: E501
|
|
1433
|
+
:rtype: bool
|
|
1434
|
+
"""
|
|
1435
|
+
return self._model_api_dashboard_clickhouse
|
|
1436
|
+
|
|
1437
|
+
@model_api_dashboard_clickhouse.setter
|
|
1438
|
+
def model_api_dashboard_clickhouse(self, model_api_dashboard_clickhouse: 'bool'):
|
|
1439
|
+
"""Sets the model_api_dashboard_clickhouse of this V1UserFeatures.
|
|
1440
|
+
|
|
1441
|
+
|
|
1442
|
+
:param model_api_dashboard_clickhouse: The model_api_dashboard_clickhouse of this V1UserFeatures. # noqa: E501
|
|
1443
|
+
:type: bool
|
|
1444
|
+
"""
|
|
1445
|
+
|
|
1446
|
+
self._model_api_dashboard_clickhouse = model_api_dashboard_clickhouse
|
|
1447
|
+
|
|
1474
1448
|
@property
|
|
1475
1449
|
def multicloud_folders(self) -> 'bool':
|
|
1476
1450
|
"""Gets the multicloud_folders of this V1UserFeatures. # noqa: E501
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import os
|
|
2
2
|
from time import sleep, time
|
|
3
3
|
from lightning_sdk.lightning_cloud import rest_client
|
|
4
|
-
from lightning_sdk.lightning_cloud.openapi import Create, V1AwsDataConnection, V1S3FolderDataConnection, V1EfsConfig
|
|
4
|
+
from lightning_sdk.lightning_cloud.openapi import Create, V1AwsDataConnection, V1S3FolderDataConnection, V1EfsConfig, V1GcpDataConnection
|
|
5
5
|
from lightning_sdk.lightning_cloud.openapi.rest import ApiException
|
|
6
6
|
import urllib3
|
|
7
|
-
import os
|
|
8
7
|
|
|
9
8
|
def add_s3_connection(bucket_name: str, region: str = "us-east-1", create_timeout: int = 15) -> None:
|
|
10
9
|
"""Utility to add a data connection."""
|
|
@@ -217,6 +216,62 @@ def add_efs_connection(name: str, filesystem_id: str, region: str = "us-east-1",
|
|
|
217
216
|
|
|
218
217
|
return
|
|
219
218
|
|
|
219
|
+
def add_gcs_connection(connection_name: str, bucket_name: str, create_timeout: int = 15) -> None:
|
|
220
|
+
"""
|
|
221
|
+
Utility function to add a GCS data connection.
|
|
222
|
+
|
|
223
|
+
Parameters:
|
|
224
|
+
1. connection_name (str): The name of the data connection.
|
|
225
|
+
2. bucket_name (str): The name of the bucket to attach.
|
|
226
|
+
3. create_timeout (int): The timeout for the data connectio creation.
|
|
227
|
+
Returns:
|
|
228
|
+
None
|
|
229
|
+
"""
|
|
230
|
+
|
|
231
|
+
client = rest_client.LightningClient(retry=False)
|
|
232
|
+
|
|
233
|
+
project_id = os.getenv("LIGHTNING_CLOUD_PROJECT_ID")
|
|
234
|
+
cluster_id = os.getenv("LIGHTNING_CLUSTER_ID")
|
|
235
|
+
|
|
236
|
+
# Get existing data connections and ensure there is no an existing one with the same name and type
|
|
237
|
+
data_connections = client.data_connection_service_list_data_connections(project_id).data_connections
|
|
238
|
+
|
|
239
|
+
for connection in data_connections:
|
|
240
|
+
existing_connection_name = getattr(connection, 'name', None)
|
|
241
|
+
isGCSConnection = getattr(connection, 'gcp', None) is not None
|
|
242
|
+
|
|
243
|
+
# Same name and type already exists
|
|
244
|
+
if existing_connection_name == connection_name and isGCSConnection:
|
|
245
|
+
return
|
|
246
|
+
|
|
247
|
+
body = Create(
|
|
248
|
+
name=connection_name,
|
|
249
|
+
create_index=True,
|
|
250
|
+
cluster_id=cluster_id,
|
|
251
|
+
access_cluster_ids=[cluster_id],
|
|
252
|
+
gcp=V1GcpDataConnection(
|
|
253
|
+
source=f"gs://{bucket_name}",
|
|
254
|
+
))
|
|
255
|
+
try:
|
|
256
|
+
client.data_connection_service_create_data_connection(body, project_id)
|
|
257
|
+
except (ApiException, urllib3.exceptions.HTTPError) as ex:
|
|
258
|
+
# Note: This function can be called in a distributed way.
|
|
259
|
+
# There is a race condition where one machine might create the entry before another machine
|
|
260
|
+
# and this request would fail with duplicated key
|
|
261
|
+
# In this case, it is fine not to raise
|
|
262
|
+
if isinstance(ex, ApiException) and 'duplicate key value violates unique constraint' in str(ex.body):
|
|
263
|
+
pass
|
|
264
|
+
else:
|
|
265
|
+
raise ex
|
|
266
|
+
|
|
267
|
+
# Wait for the filesystem picks up the newly added GCS data connection
|
|
268
|
+
start = time()
|
|
269
|
+
|
|
270
|
+
while not os.path.isdir(f"/teamspace/gcs_connections/{bucket_name}") and (time() - start) < create_timeout:
|
|
271
|
+
sleep(1)
|
|
272
|
+
|
|
273
|
+
return
|
|
274
|
+
|
|
220
275
|
def delete_data_connection(name: str):
|
|
221
276
|
"""Utility to delete a data connection
|
|
222
277
|
|
|
@@ -249,4 +304,3 @@ def delete_data_connection(name: str):
|
|
|
249
304
|
# for now it's best to actually stop the studio and all other things where the connection
|
|
250
305
|
# is mounted before trying to delete it
|
|
251
306
|
raise e from None
|
|
252
|
-
|
lightning_sdk/llm/llm.py
CHANGED
|
@@ -169,21 +169,33 @@ class LLM:
|
|
|
169
169
|
self._conversations[conversation.name] = conversation.id
|
|
170
170
|
|
|
171
171
|
def _stream_chat_response(
|
|
172
|
-
self,
|
|
172
|
+
self,
|
|
173
|
+
result: Generator[V1ConversationResponseChunk, None, None],
|
|
174
|
+
conversation: Optional[str] = None,
|
|
175
|
+
full_response: bool = False,
|
|
173
176
|
) -> Generator[str, None, None]:
|
|
174
177
|
first_line = next(result, None)
|
|
175
178
|
if first_line:
|
|
176
179
|
if conversation and first_line.conversation_id:
|
|
177
180
|
self._conversations[conversation] = first_line.conversation_id
|
|
178
|
-
|
|
181
|
+
if full_response:
|
|
182
|
+
yield first_line
|
|
183
|
+
else:
|
|
184
|
+
yield first_line.choices[0].delta.content
|
|
179
185
|
|
|
180
186
|
for line in result:
|
|
181
|
-
|
|
187
|
+
if full_response:
|
|
188
|
+
yield line
|
|
189
|
+
else:
|
|
190
|
+
yield line.choices[0].delta.content
|
|
182
191
|
|
|
183
|
-
async def _async_stream_text(self, output: str) -> AsyncGenerator[str, None]:
|
|
192
|
+
async def _async_stream_text(self, output: str, full_response: bool = False) -> AsyncGenerator[str, None]:
|
|
184
193
|
async for chunk in output:
|
|
185
194
|
if chunk.choices and chunk.choices[0].delta:
|
|
186
|
-
|
|
195
|
+
if full_response:
|
|
196
|
+
yield chunk
|
|
197
|
+
else:
|
|
198
|
+
yield chunk.choices[0].delta.content
|
|
187
199
|
|
|
188
200
|
async def _async_chat(
|
|
189
201
|
self,
|
|
@@ -194,6 +206,7 @@ class LLM:
|
|
|
194
206
|
conversation: Optional[str] = None,
|
|
195
207
|
metadata: Optional[Dict[str, str]] = None,
|
|
196
208
|
stream: bool = False,
|
|
209
|
+
full_response: bool = False,
|
|
197
210
|
**kwargs: Any,
|
|
198
211
|
) -> Union[str, AsyncGenerator[str, None]]:
|
|
199
212
|
conversation_id = self._conversations.get(conversation) if conversation else None
|
|
@@ -213,8 +226,10 @@ class LLM:
|
|
|
213
226
|
if not stream:
|
|
214
227
|
if conversation and not conversation_id:
|
|
215
228
|
self._conversations[conversation] = output.conversation_id
|
|
229
|
+
if full_response:
|
|
230
|
+
return output
|
|
216
231
|
return output.choices[0].delta.content
|
|
217
|
-
return self._async_stream_text(output)
|
|
232
|
+
return self._async_stream_text(output, full_response)
|
|
218
233
|
|
|
219
234
|
def chat(
|
|
220
235
|
self,
|
|
@@ -225,8 +240,11 @@ class LLM:
|
|
|
225
240
|
conversation: Optional[str] = None,
|
|
226
241
|
metadata: Optional[Dict[str, str]] = None,
|
|
227
242
|
stream: bool = False,
|
|
243
|
+
full_response: bool = False,
|
|
228
244
|
**kwargs: Any,
|
|
229
|
-
) -> Union[
|
|
245
|
+
) -> Union[
|
|
246
|
+
V1ConversationResponseChunk, Generator[V1ConversationResponseChunk, None, None], str, Generator[str, None, None]
|
|
247
|
+
]:
|
|
230
248
|
if conversation and conversation not in self._conversations:
|
|
231
249
|
self._get_conversations()
|
|
232
250
|
|
|
@@ -248,6 +266,7 @@ class LLM:
|
|
|
248
266
|
conversation,
|
|
249
267
|
metadata,
|
|
250
268
|
stream,
|
|
269
|
+
full_response,
|
|
251
270
|
**kwargs,
|
|
252
271
|
)
|
|
253
272
|
|
|
@@ -267,8 +286,10 @@ class LLM:
|
|
|
267
286
|
if not stream:
|
|
268
287
|
if conversation and not conversation_id:
|
|
269
288
|
self._conversations[conversation] = output.conversation_id
|
|
289
|
+
if full_response:
|
|
290
|
+
return output
|
|
270
291
|
return output.choices[0].delta.content
|
|
271
|
-
return self._stream_chat_response(output, conversation=conversation)
|
|
292
|
+
return self._stream_chat_response(output, conversation=conversation, full_response=full_response)
|
|
272
293
|
|
|
273
294
|
def list_conversations(self) -> List[Dict]:
|
|
274
295
|
self._get_conversations()
|
lightning_sdk/machine.py
CHANGED
|
@@ -5,7 +5,6 @@ from typing import Any, ClassVar, Optional, Tuple
|
|
|
5
5
|
@dataclass(frozen=True)
|
|
6
6
|
class Machine:
|
|
7
7
|
# Default Machines
|
|
8
|
-
CPU_SMALL: ClassVar["Machine"]
|
|
9
8
|
CPU: ClassVar["Machine"]
|
|
10
9
|
DATA_PREP: ClassVar["Machine"]
|
|
11
10
|
DATA_PREP_MAX: ClassVar["Machine"]
|
|
@@ -45,8 +44,7 @@ class Machine:
|
|
|
45
44
|
def is_cpu(self) -> bool:
|
|
46
45
|
"""Whether the machine is a CPU."""
|
|
47
46
|
return (
|
|
48
|
-
self == Machine.
|
|
49
|
-
or self == Machine.CPU
|
|
47
|
+
self == Machine.CPU
|
|
50
48
|
or self == Machine.DATA_PREP
|
|
51
49
|
or self == Machine.DATA_PREP_MAX
|
|
52
50
|
or self == Machine.DATA_PREP_ULTRA
|
|
@@ -67,7 +65,6 @@ class Machine:
|
|
|
67
65
|
return cls(machine, machine)
|
|
68
66
|
|
|
69
67
|
|
|
70
|
-
Machine.CPU_SMALL = Machine(name="CPU_SMALL", instance_type="m3.medium")
|
|
71
68
|
Machine.CPU = Machine(name="CPU", instance_type="cpu-4")
|
|
72
69
|
Machine.DATA_PREP = Machine(name="DATA_PREP", instance_type="data-large")
|
|
73
70
|
Machine.DATA_PREP_MAX = Machine(name="DATA_PREP_MAX", instance_type="data-max")
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
import os
|
|
2
2
|
from typing import TYPE_CHECKING, List, Optional, Union
|
|
3
3
|
|
|
4
|
-
from lightning_sdk.api import UserApi
|
|
5
4
|
from lightning_sdk.api.pipeline_api import PipelineApi
|
|
6
|
-
from lightning_sdk.lightning_cloud.login import Auth
|
|
7
5
|
from lightning_sdk.organization import Organization
|
|
8
6
|
from lightning_sdk.pipeline.printer import PipelinePrinter
|
|
9
7
|
from lightning_sdk.pipeline.steps import DeploymentStep, JobStep, MMTStep, _get_studio
|
|
@@ -12,7 +10,7 @@ from lightning_sdk.services.utilities import _get_cluster
|
|
|
12
10
|
from lightning_sdk.studio import Studio
|
|
13
11
|
from lightning_sdk.teamspace import Teamspace
|
|
14
12
|
from lightning_sdk.user import User
|
|
15
|
-
from lightning_sdk.utils.resolve import
|
|
13
|
+
from lightning_sdk.utils.resolve import _resolve_teamspace
|
|
16
14
|
|
|
17
15
|
if TYPE_CHECKING:
|
|
18
16
|
from lightning_sdk.pipeline.schedule import Schedule
|
|
@@ -40,19 +38,7 @@ class Pipeline:
|
|
|
40
38
|
shared_filesystem: Whether the pipeline should use a shared filesystem across all nodes.
|
|
41
39
|
Note: This forces the pipeline steps to be in the cloud_account and same region
|
|
42
40
|
"""
|
|
43
|
-
self._auth = Auth()
|
|
44
|
-
self._user = None
|
|
45
|
-
|
|
46
|
-
try:
|
|
47
|
-
self._auth.authenticate()
|
|
48
|
-
if user is None:
|
|
49
|
-
self._user = User(name=UserApi()._get_user_by_id(self._auth.user_id).username)
|
|
50
|
-
except ConnectionError as e:
|
|
51
|
-
raise e
|
|
52
|
-
|
|
53
41
|
self._name = name
|
|
54
|
-
self._org = _resolve_org(org)
|
|
55
|
-
self._user = _resolve_user(self._user or user)
|
|
56
42
|
|
|
57
43
|
self._teamspace = _resolve_teamspace(
|
|
58
44
|
teamspace=teamspace,
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
docs/source/conf.py,sha256=r8yX20eC-4mHhMTd0SbQb5TlSWHhO6wnJ0VJ_FBFpag,13249
|
|
2
|
-
lightning_sdk/__init__.py,sha256=
|
|
2
|
+
lightning_sdk/__init__.py,sha256=fG3HKc1WBcAYah6nhvTOh7OxcQrKdc47OVufxrxpbbE,1109
|
|
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
|
|
6
6
|
lightning_sdk/constants.py,sha256=ztl1PTUBULnqTf3DyKUSJaV_O20hNtUYT6XvAYIrmIk,749
|
|
7
7
|
lightning_sdk/helpers.py,sha256=KWMWnORHItIIA3PGn71YPs-7RjzGi8IXa2kQ5Qo4U8M,2459
|
|
8
8
|
lightning_sdk/lit_container.py,sha256=8ys49TXI9MO89jLTA7MwDrKrssTRARAIF9OVmolDLq0,5273
|
|
9
|
-
lightning_sdk/machine.py,sha256=
|
|
9
|
+
lightning_sdk/machine.py,sha256=WNzUUQzThSY34tnHPUXZ_FeG4fDamPAz6LnC4yswqFI,3483
|
|
10
10
|
lightning_sdk/models.py,sha256=tPFiiDQiDsFhfStcVPH5_PcujbBEfKS2IB5FS9NfwZk,7838
|
|
11
11
|
lightning_sdk/organization.py,sha256=WCfzdgjtvY1_A07DnxOpp74V2JR2gQwtXbIEcFDnoVU,1232
|
|
12
12
|
lightning_sdk/owner.py,sha256=t5svD2it4C9pbSpVuG9WJL46CYi37JXNziwnXxhiU5U,1361
|
|
@@ -21,16 +21,16 @@ lightning_sdk/api/__init__.py,sha256=Qn2VVRvir_gO7w4yxGLkZY-R3T7kdiTPKgQ57BhIA9k
|
|
|
21
21
|
lightning_sdk/api/agents_api.py,sha256=G47TbFo9kYqnBMqdw2RW-lfS1VAUBSXDmzs6fpIEMUs,4059
|
|
22
22
|
lightning_sdk/api/ai_hub_api.py,sha256=azqDZ-PzasVAcoQHno7k7OO_xFOHQ4NDozxF8jEh83Y,7864
|
|
23
23
|
lightning_sdk/api/base_studio_api.py,sha256=3R8tucZX2e9yKHBcY2rWFRP4dxqLrC6H75vdBDkH0ck,3617
|
|
24
|
-
lightning_sdk/api/cluster_api.py,sha256=
|
|
24
|
+
lightning_sdk/api/cluster_api.py,sha256=kAZeJbcNYG9rsYE7if5k1HlcND1Z_6cKivZ7lY4S20U,4392
|
|
25
25
|
lightning_sdk/api/deployment_api.py,sha256=KvBwGaG896q7WS1OPMOIjFUh05W2g7S1djS2XJMVieQ,24215
|
|
26
26
|
lightning_sdk/api/job_api.py,sha256=_mMAI_BG_48i-BLwCP_U72zgmM5zYa2KUZ7u66HWkIc,13568
|
|
27
27
|
lightning_sdk/api/license_api.py,sha256=XV3RhefyPQDYjwY9AaBZe4rByZTEAnsvLDxcdm9q0Wo,2438
|
|
28
28
|
lightning_sdk/api/lit_container_api.py,sha256=jCJVwd-3MNjejL9FyvH89pzt-SeG3G8qCJD16iTMJAQ,11454
|
|
29
|
-
lightning_sdk/api/llm_api.py,sha256=
|
|
29
|
+
lightning_sdk/api/llm_api.py,sha256=ngumhZrGk_XRjgN-JXHN2ksXJMwEXfadcg9p6re4Efk,9316
|
|
30
30
|
lightning_sdk/api/mmt_api.py,sha256=-v7ATab-ThAM-HRClS92Ehxuu9MlBfdKWWFCGvVUHiM,8962
|
|
31
31
|
lightning_sdk/api/org_api.py,sha256=Ze3z_ATVrukobujV5YdC42DKj45Vuwl7X52q_Vr-o3U,803
|
|
32
|
-
lightning_sdk/api/pipeline_api.py,sha256=
|
|
33
|
-
lightning_sdk/api/studio_api.py,sha256=
|
|
32
|
+
lightning_sdk/api/pipeline_api.py,sha256=oS0WIBB748SLD7bqkEQ8rnkixrsAML_M01OUunmLFSQ,4470
|
|
33
|
+
lightning_sdk/api/studio_api.py,sha256=J-kp6IoXlQaVz1S4BtaK93VrLAbMOolQYDGJyrkPDRo,30702
|
|
34
34
|
lightning_sdk/api/teamspace_api.py,sha256=CsaaxmaLmTRIRwu37wtQ3quGYql62HJT3BZJ3Q-1d9c,16854
|
|
35
35
|
lightning_sdk/api/user_api.py,sha256=sL7RIjjtmZmvCZWx7BBZslhj1BeNh4Idn-RVcdmf7M0,2598
|
|
36
36
|
lightning_sdk/api/utils.py,sha256=K0Uc6D1KxxjFElqjsuCXg85SYreQi3P7jJ1VzP0MpEQ,23966
|
|
@@ -67,7 +67,7 @@ lightning_sdk/cli/deploy/serve.py,sha256=qqml7oYf4IPcoiL13P2ly247_PQ8IGv-8hM2NBW
|
|
|
67
67
|
lightning_sdk/deployment/__init__.py,sha256=dXsa4psDzFYFklsq3JC-2V_L4FQjGZnQAf-ZiVlqG9c,545
|
|
68
68
|
lightning_sdk/deployment/deployment.py,sha256=kD3P3uonV7Vr33BVnyD-HkxdUuQs0F2nt0GYoWb3Wx4,21057
|
|
69
69
|
lightning_sdk/job/__init__.py,sha256=1MxjQ6rHkyUHCypSW9RuXuVMVH11WiqhIXcU2LCFMwE,64
|
|
70
|
-
lightning_sdk/job/base.py,sha256=
|
|
70
|
+
lightning_sdk/job/base.py,sha256=u6d_Q56zzM_nzKGPvjVqR2MKEYzFawEGoaSsD747ZHQ,18603
|
|
71
71
|
lightning_sdk/job/job.py,sha256=1Xf0ne4wwXpkb_GJgWD8mfueJZoKR8G4lC5T6OXijlw,13075
|
|
72
72
|
lightning_sdk/job/v1.py,sha256=zgdZFnlyhzOBlbwdwx6Ob9YKBrzMnJflzLXy4qyb4So,9070
|
|
73
73
|
lightning_sdk/job/v2.py,sha256=9O31CwIQjwm6qZSEZtFBWbZyBuCSmyFMsHCRbQvJdBU,10283
|
|
@@ -138,7 +138,7 @@ lightning_sdk/lightning_cloud/openapi/models/appinstances_id_body.py,sha256=DfwY
|
|
|
138
138
|
lightning_sdk/lightning_cloud/openapi/models/approveautojoindomain_domain_body.py,sha256=gC2puM75rrgB36ekVmgF9rnzWE4mAp6tpaGUrlhARRU,3771
|
|
139
139
|
lightning_sdk/lightning_cloud/openapi/models/apps_id_body.py,sha256=tjIpEmU6Y8nhLDT0c3JAdywxEjI-NzvgLdEhf2UXWf4,17912
|
|
140
140
|
lightning_sdk/lightning_cloud/openapi/models/apps_id_body1.py,sha256=Ja_1s0PjD1hIjAvyqyp8U4WXKv2GoUGoQ-HHm8hvRbc,8874
|
|
141
|
-
lightning_sdk/lightning_cloud/openapi/models/assistant_id_conversations_body.py,sha256=
|
|
141
|
+
lightning_sdk/lightning_cloud/openapi/models/assistant_id_conversations_body.py,sha256=XRAgtHlFxqIhML1z_4kGNvlrOCQQph3kjm9JWIr-ijQ,16305
|
|
142
142
|
lightning_sdk/lightning_cloud/openapi/models/billing_checkout_body.py,sha256=bMABc4XkRzK-t2RzWg1bd2YZSwZkqYZoUex9iWO1lPI,5379
|
|
143
143
|
lightning_sdk/lightning_cloud/openapi/models/billing_transfer_body.py,sha256=MaovoJiJDzOXNhCskZAN5UNwnFEFP7ONF83DPRgfhgk,4510
|
|
144
144
|
lightning_sdk/lightning_cloud/openapi/models/billing_transfer_body1.py,sha256=6zrWBAHmmKHJgqJtxahcM1mDrO3Z55WxaGK0RY10oOw,5275
|
|
@@ -411,7 +411,7 @@ lightning_sdk/lightning_cloud/openapi/models/v1_compute_config.py,sha256=YGkx66e
|
|
|
411
411
|
lightning_sdk/lightning_cloud/openapi/models/v1_contact_assistant_owner_reason.py,sha256=9J2PuNGXlDXMcsmINbocUYGXVKhRlvqDdRwgtAH_qPU,3121
|
|
412
412
|
lightning_sdk/lightning_cloud/openapi/models/v1_contact_assistant_owner_response.py,sha256=_FXW0hslMncLSPPxDmWEbhePRz-4tFc98KpqMf0M_6s,3076
|
|
413
413
|
lightning_sdk/lightning_cloud/openapi/models/v1_conversation.py,sha256=xINDLIVGuMEXSog0ryP3rQW1y_9PmEIMsL7P7LHzb_M,9220
|
|
414
|
-
lightning_sdk/lightning_cloud/openapi/models/v1_conversation_response_chunk.py,sha256=
|
|
414
|
+
lightning_sdk/lightning_cloud/openapi/models/v1_conversation_response_chunk.py,sha256=7JovH85aN8mwC_gUVdCBDyqUCwwNlsEAqkBGKMTmwMo,9149
|
|
415
415
|
lightning_sdk/lightning_cloud/openapi/models/v1_count_metrics_streams_response.py,sha256=ovqawh81CI7PvAqcElhGYw0-NVwSzwbm4s2PFErdxHA,3751
|
|
416
416
|
lightning_sdk/lightning_cloud/openapi/models/v1_cpu_system_metrics.py,sha256=Mgybx_EGelKpTVzfW9WXp5HiiVMLPoes8vdVq8We1TU,10120
|
|
417
417
|
lightning_sdk/lightning_cloud/openapi/models/v1_create_agent_multipart_upload_response.py,sha256=Ov9pBANdLtAbfz0ed_N-UGBeUwZozYKuqbst0F8u2Cw,3900
|
|
@@ -1027,7 +1027,7 @@ lightning_sdk/lightning_cloud/openapi/models/v1_upstream_open_ai.py,sha256=jt1qQ
|
|
|
1027
1027
|
lightning_sdk/lightning_cloud/openapi/models/v1_usage.py,sha256=ozMzoGD9mfZGYy4J5j50Dps19Y6o8cn-aYW_oRMZMy8,16865
|
|
1028
1028
|
lightning_sdk/lightning_cloud/openapi/models/v1_usage_details.py,sha256=U7qC698Xj5tb3D93ZskG6sDf3lTXE13UTlGeDTvtRU4,14062
|
|
1029
1029
|
lightning_sdk/lightning_cloud/openapi/models/v1_usage_report.py,sha256=k9pDp9UIaOEEWz6bTNWF_KMfcNCOp-F67N-IZ9MO2Rs,8304
|
|
1030
|
-
lightning_sdk/lightning_cloud/openapi/models/v1_user_features.py,sha256=
|
|
1030
|
+
lightning_sdk/lightning_cloud/openapi/models/v1_user_features.py,sha256=Bm5XX7YRf4skZnQVnKSMfaHGGnErXYcXNwhgFMAlMDg,81783
|
|
1031
1031
|
lightning_sdk/lightning_cloud/openapi/models/v1_user_requested_compute_config.py,sha256=0fnZpdhxNRXGNyILHtfm3rVztfHpSF4kXGc5kTt4zls,13960
|
|
1032
1032
|
lightning_sdk/lightning_cloud/openapi/models/v1_user_requested_flow_compute_config.py,sha256=3WpZ-lf7xPwuYyQDMdP7Uc6-dh3vf5TaaUlcMfesfMk,5208
|
|
1033
1033
|
lightning_sdk/lightning_cloud/openapi/models/v1_user_slurm_job_action_response.py,sha256=BdNzXH8Vsf5PHjl9Rd-TVkpAgx1YC9rf8LD0js-ba20,3058
|
|
@@ -1065,12 +1065,12 @@ lightning_sdk/lightning_cloud/source_code/logs_socket_api.py,sha256=fXuRQfnRLNkY
|
|
|
1065
1065
|
lightning_sdk/lightning_cloud/source_code/tar.py,sha256=mSKRWEX1SIAbXFcESNrQAqWSVULv4G0jgcvR_o2KJ5g,5813
|
|
1066
1066
|
lightning_sdk/lightning_cloud/source_code/uploader.py,sha256=CQrWV6JNDiglyRfhc42ht4GWFtgRz_fBxw4tOCERzco,3207
|
|
1067
1067
|
lightning_sdk/lightning_cloud/utils/__init__.py,sha256=kSNKoybELDJHs9WeCf279V5JtzOf1VqfKODlKYr9uRo,115
|
|
1068
|
-
lightning_sdk/lightning_cloud/utils/data_connection.py,sha256=
|
|
1068
|
+
lightning_sdk/lightning_cloud/utils/data_connection.py,sha256=WeC7HWpQL2HxSEuX-7iB0mjoQN_YNr5dgfSkPtCGlds,11448
|
|
1069
1069
|
lightning_sdk/lightning_cloud/utils/dataset.py,sha256=4nUspe8iAaRPgSYpXA2uAQCgydm78kJzhOIx3C9qKls,2011
|
|
1070
1070
|
lightning_sdk/lightning_cloud/utils/name_generator.py,sha256=MkciuA10332V0mcE2PxLIiwWomWE0Fm_gNGK01vwRr4,58046
|
|
1071
1071
|
lightning_sdk/lightning_cloud/utils/network.py,sha256=axPgl8rhyPcPjxiztDxyksfxax3VNg2OXL5F5Uc81b4,406
|
|
1072
1072
|
lightning_sdk/llm/__init__.py,sha256=ErZva0HqN2iPtK_6hI6GN7A_HPGNrHo3wYh7vyFdO3Q,57
|
|
1073
|
-
lightning_sdk/llm/llm.py,sha256=
|
|
1073
|
+
lightning_sdk/llm/llm.py,sha256=M43OQli7cRqTtHUB484-OOdWs-jiwJv8j1LV-jFUolY,13038
|
|
1074
1074
|
lightning_sdk/llm/public_assistants.json,sha256=PFbA1p2J6XFRafuW0zfaz8tu_Ac4iI2hNeh94_PNoUQ,374
|
|
1075
1075
|
lightning_sdk/mmt/__init__.py,sha256=ExMu90-96bGBnyp5h0CErQszUGB1-PcjC4-R8_NYbeY,117
|
|
1076
1076
|
lightning_sdk/mmt/base.py,sha256=B3HC-c82bPHprEZh1mhLCPCrCE8BOKqwIhY7xCF9CXg,15152
|
|
@@ -1078,7 +1078,7 @@ lightning_sdk/mmt/mmt.py,sha256=swdGP1DOM42a_QmmY1vg3--6ZBDiC4zToAzU9Eycv4U,1344
|
|
|
1078
1078
|
lightning_sdk/mmt/v1.py,sha256=TxLtL0ssDoP8eyleDaFyYr4evkOKbLJcckLVIfalOno,8429
|
|
1079
1079
|
lightning_sdk/mmt/v2.py,sha256=Em1XBoqViqUMKm-sshzdMcSH5UTtZZwbJcsgqY6-mw0,9625
|
|
1080
1080
|
lightning_sdk/pipeline/__init__.py,sha256=Sja_0NJ8vgh-2ThSVP3WDI9a9qghrWd21LkaQp4Zsp8,378
|
|
1081
|
-
lightning_sdk/pipeline/pipeline.py,sha256=
|
|
1081
|
+
lightning_sdk/pipeline/pipeline.py,sha256=yF8ebZlhOa0pWxLUpmKqW5oy4VEMT7NFSXpUhdpWbak,5425
|
|
1082
1082
|
lightning_sdk/pipeline/printer.py,sha256=uNi3JD3RjQMVflJxik9o4CDfifROP70aV_vt6mms5zg,4671
|
|
1083
1083
|
lightning_sdk/pipeline/schedule.py,sha256=r8L4M_NH5zoXoCf13jpn2icNIJ3hUgUFZrrq-ArnTWA,147
|
|
1084
1084
|
lightning_sdk/pipeline/steps.py,sha256=5IM7BNiH42Rxq0sJNuwIN64qs-NCa81_XeP8pg_dCL8,12294
|
|
@@ -1092,9 +1092,9 @@ lightning_sdk/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSu
|
|
|
1092
1092
|
lightning_sdk/utils/dynamic.py,sha256=glUTO1JC9APtQ6Gr9SO02a3zr56-sPAXM5C3NrTpgyQ,1959
|
|
1093
1093
|
lightning_sdk/utils/enum.py,sha256=h2JRzqoBcSlUdanFHmkj_j5DleBHAu1esQYUsdNI-hU,4106
|
|
1094
1094
|
lightning_sdk/utils/resolve.py,sha256=6qlBUkOmcFTjhQx_CAGfnvWBbMYp6XrCV_sX_IqplLE,6748
|
|
1095
|
-
lightning_sdk-
|
|
1096
|
-
lightning_sdk-
|
|
1097
|
-
lightning_sdk-
|
|
1098
|
-
lightning_sdk-
|
|
1099
|
-
lightning_sdk-
|
|
1100
|
-
lightning_sdk-
|
|
1095
|
+
lightning_sdk-2025.7.10.dist-info/LICENSE,sha256=uFIuZwj5z-4TeF2UuacPZ1o17HkvKObT8fY50qN84sg,1064
|
|
1096
|
+
lightning_sdk-2025.7.10.dist-info/METADATA,sha256=TH70L4MhS7ZbK7lPcmMB6QftgtEp4tGo5wUlOuwAS78,3995
|
|
1097
|
+
lightning_sdk-2025.7.10.dist-info/WHEEL,sha256=iAkIy5fosb7FzIOwONchHf19Qu7_1wCWyFNR5gu9nU0,91
|
|
1098
|
+
lightning_sdk-2025.7.10.dist-info/entry_points.txt,sha256=msB9PJWIJ784dX-OP8by51d4IbKYH3Fj1vCuA9oXjHY,68
|
|
1099
|
+
lightning_sdk-2025.7.10.dist-info/top_level.txt,sha256=ps8doKILFXmN7F1mHncShmnQoTxKBRPIcchC8TpoBw4,19
|
|
1100
|
+
lightning_sdk-2025.7.10.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|