lightning-sdk 2025.8.6rc2__py3-none-any.whl → 2025.8.8__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- lightning_sdk/__init__.py +1 -1
- lightning_sdk/cli/clusters_menu.py +9 -6
- lightning_sdk/cli/deploy/serve.py +17 -6
- lightning_sdk/cli/download.py +2 -2
- lightning_sdk/cli/list.py +2 -3
- lightning_sdk/lightning_cloud/openapi/__init__.py +3 -0
- lightning_sdk/lightning_cloud/openapi/api/assistants_service_api.py +110 -1
- lightning_sdk/lightning_cloud/openapi/api/schedules_service_api.py +347 -0
- lightning_sdk/lightning_cloud/openapi/configuration.py +3 -19
- lightning_sdk/lightning_cloud/openapi/models/__init__.py +3 -0
- lightning_sdk/lightning_cloud/openapi/models/cluster_id_metrics_body.py +27 -1
- lightning_sdk/lightning_cloud/openapi/models/v1_cluster_metrics.py +877 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_list_schedule_runs_response.py +123 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_node_metrics.py +53 -1
- lightning_sdk/lightning_cloud/openapi/models/v1_schedule_run.py +357 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_user_features.py +27 -1
- lightning_sdk/llm/llm.py +15 -10
- lightning_sdk/llm/public_assistants.py +40 -7
- {lightning_sdk-2025.8.6rc2.dist-info → lightning_sdk-2025.8.8.dist-info}/METADATA +1 -1
- {lightning_sdk-2025.8.6rc2.dist-info → lightning_sdk-2025.8.8.dist-info}/RECORD +24 -21
- {lightning_sdk-2025.8.6rc2.dist-info → lightning_sdk-2025.8.8.dist-info}/LICENSE +0 -0
- {lightning_sdk-2025.8.6rc2.dist-info → lightning_sdk-2025.8.8.dist-info}/WHEEL +0 -0
- {lightning_sdk-2025.8.6rc2.dist-info → lightning_sdk-2025.8.8.dist-info}/entry_points.txt +0 -0
- {lightning_sdk-2025.8.6rc2.dist-info → lightning_sdk-2025.8.8.dist-info}/top_level.txt +0 -0
lightning_sdk/__init__.py
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import sys
|
|
2
|
-
from typing import List
|
|
2
|
+
from typing import List, Optional
|
|
3
3
|
|
|
4
4
|
from rich.console import Console
|
|
5
5
|
from simple_term_menu import TerminalMenu
|
|
6
6
|
|
|
7
7
|
from lightning_sdk import Teamspace
|
|
8
8
|
from lightning_sdk.api.cloud_account_api import CloudAccountApi
|
|
9
|
-
from lightning_sdk.lightning_cloud.openapi import
|
|
9
|
+
from lightning_sdk.lightning_cloud.openapi import V1ClusterType, V1ProjectClusterBinding
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
class _ClustersMenu:
|
|
@@ -22,18 +22,21 @@ class _ClustersMenu:
|
|
|
22
22
|
|
|
23
23
|
return TerminalMenu(cluster_ids, title=title, clear_menu_on_exit=True)
|
|
24
24
|
|
|
25
|
-
def _resolve_cluster(self, teamspace: Teamspace) ->
|
|
25
|
+
def _resolve_cluster(self, teamspace: Teamspace) -> Optional[str]:
|
|
26
26
|
selected_cluster_id = None
|
|
27
27
|
console = Console()
|
|
28
28
|
try:
|
|
29
|
-
selected_cluster_id = self._get_cluster_from_interactive_menu(
|
|
29
|
+
selected_cluster_id = teamspace.default_cloud_account or self._get_cluster_from_interactive_menu(
|
|
30
30
|
possible_clusters=teamspace.cloud_account_objs
|
|
31
31
|
)
|
|
32
|
+
|
|
32
33
|
cloud_account_api = CloudAccountApi()
|
|
33
34
|
|
|
34
|
-
|
|
35
|
-
|
|
35
|
+
resolved_cluster_obj = cloud_account_api.get_cloud_account(
|
|
36
|
+
cloud_account_id=selected_cluster_id, org_id=teamspace.owner.id, teamspace_id=teamspace.id
|
|
36
37
|
)
|
|
38
|
+
|
|
39
|
+
return None if resolved_cluster_obj.spec.cluster_type == V1ClusterType.GLOBAL else resolved_cluster_obj.id
|
|
37
40
|
except KeyboardInterrupt:
|
|
38
41
|
console.print("Operation cancelled by user")
|
|
39
42
|
sys.exit(0)
|
|
@@ -15,6 +15,7 @@ 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
|
|
18
19
|
from lightning_sdk.cli.deploy._auth import (
|
|
19
20
|
_AuthMode,
|
|
20
21
|
_Onboarding,
|
|
@@ -377,18 +378,24 @@ def _handle_cloud(
|
|
|
377
378
|
else:
|
|
378
379
|
resolved_teamspace = select_teamspace(teamspace, org, user)
|
|
379
380
|
|
|
381
|
+
lightning_containers_cloud_account = cloud_account
|
|
382
|
+
if not cloud_account:
|
|
383
|
+
clusters_menu = _ClustersMenu()
|
|
384
|
+
lightning_containers_cloud_account = clusters_menu._resolve_cluster(resolved_teamspace)
|
|
385
|
+
cloud_account = resolved_teamspace.default_cloud_account
|
|
386
|
+
|
|
380
387
|
# list containers to create the project if it doesn't exist
|
|
381
388
|
lit_cr = LitContainerApi()
|
|
382
|
-
lit_cr.list_containers(resolved_teamspace.id, cloud_account=
|
|
389
|
+
lit_cr.list_containers(resolved_teamspace.id, cloud_account=lightning_containers_cloud_account)
|
|
383
390
|
|
|
384
391
|
registry_url = _get_registry_url()
|
|
385
392
|
container_basename = repository.split("/")[-1]
|
|
386
393
|
image = (
|
|
387
|
-
f"{registry_url}/lit-container
|
|
388
|
-
f"{
|
|
394
|
+
f"{registry_url}/lit-container"
|
|
395
|
+
+ (f"-{lightning_containers_cloud_account}" if lightning_containers_cloud_account is not None else "")
|
|
396
|
+
+ f"/{resolved_teamspace.owner.name}/{resolved_teamspace.name}/{container_basename}"
|
|
389
397
|
)
|
|
390
398
|
|
|
391
|
-
cloud_account = cloud_account or resolved_teamspace.default_cloud_account
|
|
392
399
|
if from_onboarding:
|
|
393
400
|
thread = Thread(
|
|
394
401
|
target=ls_deployer.run_on_cloud,
|
|
@@ -411,13 +418,17 @@ def _handle_cloud(
|
|
|
411
418
|
)
|
|
412
419
|
thread.start()
|
|
413
420
|
console.print("🚀 Deployment started")
|
|
414
|
-
if not _upload_container(
|
|
421
|
+
if not _upload_container(
|
|
422
|
+
console, ls_deployer, repository, tag, resolved_teamspace, lit_cr, lightning_containers_cloud_account
|
|
423
|
+
):
|
|
415
424
|
thread.join()
|
|
416
425
|
return
|
|
417
426
|
thread.join()
|
|
418
427
|
return
|
|
419
428
|
|
|
420
|
-
if not _upload_container(
|
|
429
|
+
if not _upload_container(
|
|
430
|
+
console, ls_deployer, repository, tag, resolved_teamspace, lit_cr, lightning_containers_cloud_account
|
|
431
|
+
):
|
|
421
432
|
return
|
|
422
433
|
|
|
423
434
|
deployment_status = ls_deployer.run_on_cloud(
|
lightning_sdk/cli/download.py
CHANGED
|
@@ -136,7 +136,7 @@ def folder(
|
|
|
136
136
|
"--studio",
|
|
137
137
|
default=None,
|
|
138
138
|
help=(
|
|
139
|
-
"The name of the studio to
|
|
139
|
+
"The name of the studio to download from. "
|
|
140
140
|
"Will show a menu with user's owned studios for selection if not specified. "
|
|
141
141
|
"If provided, should be in the form of <TEAMSPACE-NAME>/<STUDIO-NAME> where the names are case-sensitive. "
|
|
142
142
|
"The teamspace and studio names can be regular expressions to match, "
|
|
@@ -256,7 +256,7 @@ def _resolve_studio(studio: Optional[str]) -> Studio:
|
|
|
256
256
|
# give user friendlier error message
|
|
257
257
|
except Exception as e:
|
|
258
258
|
raise StudioCliError(
|
|
259
|
-
f"Could not find the given Studio {studio} to
|
|
259
|
+
f"Could not find the given Studio {studio} to download files from. "
|
|
260
260
|
"Please contact Lightning AI directly to resolve this issue."
|
|
261
261
|
) from e
|
|
262
262
|
|
lightning_sdk/cli/list.py
CHANGED
|
@@ -9,7 +9,7 @@ from typing_extensions import Literal
|
|
|
9
9
|
from lightning_sdk import Job, Machine, Studio, Teamspace
|
|
10
10
|
from lightning_sdk.cli.clusters_menu import _ClustersMenu
|
|
11
11
|
from lightning_sdk.cli.teamspace_menu import _TeamspacesMenu
|
|
12
|
-
from lightning_sdk.lightning_cloud.openapi import
|
|
12
|
+
from lightning_sdk.lightning_cloud.openapi import V1MultiMachineJob
|
|
13
13
|
from lightning_sdk.lit_container import LitContainer
|
|
14
14
|
from lightning_sdk.utils.resolve import _get_authed_user
|
|
15
15
|
|
|
@@ -247,8 +247,7 @@ def containers(teamspace: Optional[str] = None, cloud_account: Optional[str] = N
|
|
|
247
247
|
resolved_teamspace = menu._resolve_teamspace(teamspace=teamspace)
|
|
248
248
|
|
|
249
249
|
if not cloud_account:
|
|
250
|
-
|
|
251
|
-
cloud_account = "" if cloud_account_obj.spec.cluster_type == V1ClusterType.GLOBAL else cloud_account_obj.id
|
|
250
|
+
cloud_account = clusters_menu._resolve_cluster(resolved_teamspace)
|
|
252
251
|
|
|
253
252
|
result = api.list_containers(
|
|
254
253
|
teamspace=resolved_teamspace.name, org=resolved_teamspace.owner.name, cloud_account=cloud_account
|
|
@@ -326,6 +326,7 @@ from lightning_sdk.lightning_cloud.openapi.models.v1_cluster_availability import
|
|
|
326
326
|
from lightning_sdk.lightning_cloud.openapi.models.v1_cluster_capacity_reservation import V1ClusterCapacityReservation
|
|
327
327
|
from lightning_sdk.lightning_cloud.openapi.models.v1_cluster_deletion_options import V1ClusterDeletionOptions
|
|
328
328
|
from lightning_sdk.lightning_cloud.openapi.models.v1_cluster_encryption_key import V1ClusterEncryptionKey
|
|
329
|
+
from lightning_sdk.lightning_cloud.openapi.models.v1_cluster_metrics import V1ClusterMetrics
|
|
329
330
|
from lightning_sdk.lightning_cloud.openapi.models.v1_cluster_names import V1ClusterNames
|
|
330
331
|
from lightning_sdk.lightning_cloud.openapi.models.v1_cluster_proxy import V1ClusterProxy
|
|
331
332
|
from lightning_sdk.lightning_cloud.openapi.models.v1_cluster_resource_tag import V1ClusterResourceTag
|
|
@@ -730,6 +731,7 @@ from lightning_sdk.lightning_cloud.openapi.models.v1_list_published_managed_endp
|
|
|
730
731
|
from lightning_sdk.lightning_cloud.openapi.models.v1_list_quests_response import V1ListQuestsResponse
|
|
731
732
|
from lightning_sdk.lightning_cloud.openapi.models.v1_list_slurm_cluster_users_response import V1ListSLURMClusterUsersResponse
|
|
732
733
|
from lightning_sdk.lightning_cloud.openapi.models.v1_list_ssh_public_keys_response import V1ListSSHPublicKeysResponse
|
|
734
|
+
from lightning_sdk.lightning_cloud.openapi.models.v1_list_schedule_runs_response import V1ListScheduleRunsResponse
|
|
733
735
|
from lightning_sdk.lightning_cloud.openapi.models.v1_list_schedules_response import V1ListSchedulesResponse
|
|
734
736
|
from lightning_sdk.lightning_cloud.openapi.models.v1_list_secrets_response import V1ListSecretsResponse
|
|
735
737
|
from lightning_sdk.lightning_cloud.openapi.models.v1_list_studio_jobs_response import V1ListStudioJobsResponse
|
|
@@ -884,6 +886,7 @@ from lightning_sdk.lightning_cloud.openapi.models.v1_ssh_public_key import V1SSH
|
|
|
884
886
|
from lightning_sdk.lightning_cloud.openapi.models.v1_schedule import V1Schedule
|
|
885
887
|
from lightning_sdk.lightning_cloud.openapi.models.v1_schedule_action_type import V1ScheduleActionType
|
|
886
888
|
from lightning_sdk.lightning_cloud.openapi.models.v1_schedule_resource_type import V1ScheduleResourceType
|
|
889
|
+
from lightning_sdk.lightning_cloud.openapi.models.v1_schedule_run import V1ScheduleRun
|
|
887
890
|
from lightning_sdk.lightning_cloud.openapi.models.v1_search_job_logs_response import V1SearchJobLogsResponse
|
|
888
891
|
from lightning_sdk.lightning_cloud.openapi.models.v1_search_user import V1SearchUser
|
|
889
892
|
from lightning_sdk.lightning_cloud.openapi.models.v1_search_users_response import V1SearchUsersResponse
|
|
@@ -965,6 +965,7 @@ class AssistantsServiceApi(object):
|
|
|
965
965
|
:param str user_name:
|
|
966
966
|
:param str org_name:
|
|
967
967
|
:param str model_provider:
|
|
968
|
+
:param str model_display_name:
|
|
968
969
|
:return: V1Assistant
|
|
969
970
|
If the method is called asynchronously,
|
|
970
971
|
returns the request thread.
|
|
@@ -989,12 +990,13 @@ class AssistantsServiceApi(object):
|
|
|
989
990
|
:param str user_name:
|
|
990
991
|
:param str org_name:
|
|
991
992
|
:param str model_provider:
|
|
993
|
+
:param str model_display_name:
|
|
992
994
|
:return: V1Assistant
|
|
993
995
|
If the method is called asynchronously,
|
|
994
996
|
returns the request thread.
|
|
995
997
|
"""
|
|
996
998
|
|
|
997
|
-
all_params = ['model_name', 'user_name', 'org_name', 'model_provider'] # noqa: E501
|
|
999
|
+
all_params = ['model_name', 'user_name', 'org_name', 'model_provider', 'model_display_name'] # noqa: E501
|
|
998
1000
|
all_params.append('async_req')
|
|
999
1001
|
all_params.append('_return_http_data_only')
|
|
1000
1002
|
all_params.append('_preload_content')
|
|
@@ -1027,6 +1029,8 @@ class AssistantsServiceApi(object):
|
|
|
1027
1029
|
query_params.append(('orgName', params['org_name'])) # noqa: E501
|
|
1028
1030
|
if 'model_provider' in params:
|
|
1029
1031
|
query_params.append(('modelProvider', params['model_provider'])) # noqa: E501
|
|
1032
|
+
if 'model_display_name' in params:
|
|
1033
|
+
query_params.append(('modelDisplayName', params['model_display_name'])) # noqa: E501
|
|
1030
1034
|
|
|
1031
1035
|
header_params = {}
|
|
1032
1036
|
|
|
@@ -1057,6 +1061,111 @@ class AssistantsServiceApi(object):
|
|
|
1057
1061
|
_request_timeout=params.get('_request_timeout'),
|
|
1058
1062
|
collection_formats=collection_formats)
|
|
1059
1063
|
|
|
1064
|
+
def assistants_service_get_managed_model_assistant2(self, **kwargs) -> 'V1Assistant': # noqa: E501
|
|
1065
|
+
"""Each managed model has a dedicated assistant for direct interaction. By using user_name, org_name, or model_provider as query parameters, this endpoint retrieves that specific assistant only—excluding any other assistants that may use the same model. # noqa: E501
|
|
1066
|
+
|
|
1067
|
+
This method makes a synchronous HTTP request by default. To make an
|
|
1068
|
+
asynchronous HTTP request, please pass async_req=True
|
|
1069
|
+
>>> thread = api.assistants_service_get_managed_model_assistant2(async_req=True)
|
|
1070
|
+
>>> result = thread.get()
|
|
1071
|
+
|
|
1072
|
+
:param async_req bool
|
|
1073
|
+
:param str user_name:
|
|
1074
|
+
:param str org_name:
|
|
1075
|
+
:param str model_provider:
|
|
1076
|
+
:param str model_name:
|
|
1077
|
+
:param str model_display_name:
|
|
1078
|
+
:return: V1Assistant
|
|
1079
|
+
If the method is called asynchronously,
|
|
1080
|
+
returns the request thread.
|
|
1081
|
+
"""
|
|
1082
|
+
kwargs['_return_http_data_only'] = True
|
|
1083
|
+
if kwargs.get('async_req'):
|
|
1084
|
+
return self.assistants_service_get_managed_model_assistant2_with_http_info(**kwargs) # noqa: E501
|
|
1085
|
+
else:
|
|
1086
|
+
(data) = self.assistants_service_get_managed_model_assistant2_with_http_info(**kwargs) # noqa: E501
|
|
1087
|
+
return data
|
|
1088
|
+
|
|
1089
|
+
def assistants_service_get_managed_model_assistant2_with_http_info(self, **kwargs) -> 'V1Assistant': # noqa: E501
|
|
1090
|
+
"""Each managed model has a dedicated assistant for direct interaction. By using user_name, org_name, or model_provider as query parameters, this endpoint retrieves that specific assistant only—excluding any other assistants that may use the same model. # noqa: E501
|
|
1091
|
+
|
|
1092
|
+
This method makes a synchronous HTTP request by default. To make an
|
|
1093
|
+
asynchronous HTTP request, please pass async_req=True
|
|
1094
|
+
>>> thread = api.assistants_service_get_managed_model_assistant2_with_http_info(async_req=True)
|
|
1095
|
+
>>> result = thread.get()
|
|
1096
|
+
|
|
1097
|
+
:param async_req bool
|
|
1098
|
+
:param str user_name:
|
|
1099
|
+
:param str org_name:
|
|
1100
|
+
:param str model_provider:
|
|
1101
|
+
:param str model_name:
|
|
1102
|
+
:param str model_display_name:
|
|
1103
|
+
:return: V1Assistant
|
|
1104
|
+
If the method is called asynchronously,
|
|
1105
|
+
returns the request thread.
|
|
1106
|
+
"""
|
|
1107
|
+
|
|
1108
|
+
all_params = ['user_name', 'org_name', 'model_provider', 'model_name', 'model_display_name'] # noqa: E501
|
|
1109
|
+
all_params.append('async_req')
|
|
1110
|
+
all_params.append('_return_http_data_only')
|
|
1111
|
+
all_params.append('_preload_content')
|
|
1112
|
+
all_params.append('_request_timeout')
|
|
1113
|
+
|
|
1114
|
+
params = locals()
|
|
1115
|
+
for key, val in six.iteritems(params['kwargs']):
|
|
1116
|
+
if key not in all_params:
|
|
1117
|
+
raise TypeError(
|
|
1118
|
+
"Got an unexpected keyword argument '%s'"
|
|
1119
|
+
" to method assistants_service_get_managed_model_assistant2" % key
|
|
1120
|
+
)
|
|
1121
|
+
params[key] = val
|
|
1122
|
+
del params['kwargs']
|
|
1123
|
+
|
|
1124
|
+
collection_formats = {}
|
|
1125
|
+
|
|
1126
|
+
path_params = {}
|
|
1127
|
+
|
|
1128
|
+
query_params = []
|
|
1129
|
+
if 'user_name' in params:
|
|
1130
|
+
query_params.append(('userName', params['user_name'])) # noqa: E501
|
|
1131
|
+
if 'org_name' in params:
|
|
1132
|
+
query_params.append(('orgName', params['org_name'])) # noqa: E501
|
|
1133
|
+
if 'model_provider' in params:
|
|
1134
|
+
query_params.append(('modelProvider', params['model_provider'])) # noqa: E501
|
|
1135
|
+
if 'model_name' in params:
|
|
1136
|
+
query_params.append(('modelName', params['model_name'])) # noqa: E501
|
|
1137
|
+
if 'model_display_name' in params:
|
|
1138
|
+
query_params.append(('modelDisplayName', params['model_display_name'])) # noqa: E501
|
|
1139
|
+
|
|
1140
|
+
header_params = {}
|
|
1141
|
+
|
|
1142
|
+
form_params = []
|
|
1143
|
+
local_var_files = {}
|
|
1144
|
+
|
|
1145
|
+
body_params = None
|
|
1146
|
+
# HTTP header `Accept`
|
|
1147
|
+
header_params['Accept'] = self.api_client.select_header_accept(
|
|
1148
|
+
['application/json']) # noqa: E501
|
|
1149
|
+
|
|
1150
|
+
# Authentication setting
|
|
1151
|
+
auth_settings = [] # noqa: E501
|
|
1152
|
+
|
|
1153
|
+
return self.api_client.call_api(
|
|
1154
|
+
'/v1/agents/managed-model', 'GET',
|
|
1155
|
+
path_params,
|
|
1156
|
+
query_params,
|
|
1157
|
+
header_params,
|
|
1158
|
+
body=body_params,
|
|
1159
|
+
post_params=form_params,
|
|
1160
|
+
files=local_var_files,
|
|
1161
|
+
response_type='V1Assistant', # noqa: E501
|
|
1162
|
+
auth_settings=auth_settings,
|
|
1163
|
+
async_req=params.get('async_req'),
|
|
1164
|
+
_return_http_data_only=params.get('_return_http_data_only'),
|
|
1165
|
+
_preload_content=params.get('_preload_content', True),
|
|
1166
|
+
_request_timeout=params.get('_request_timeout'),
|
|
1167
|
+
collection_formats=collection_formats)
|
|
1168
|
+
|
|
1060
1169
|
def assistants_service_get_managed_model_by_name(self, project_id: 'str', managed_endpoint_id: 'str', name: 'str', **kwargs) -> 'V1ManagedModel': # noqa: E501
|
|
1061
1170
|
"""assistants_service_get_managed_model_by_name # noqa: E501
|
|
1062
1171
|
|