lightning-sdk 2025.12.16__py3-none-any.whl → 2026.1.22__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/__version__.py +1 -1
- lightning_sdk/api/k8s_api.py +75 -29
- lightning_sdk/api/org_api.py +7 -0
- lightning_sdk/api/studio_api.py +223 -36
- lightning_sdk/api/teamspace_api.py +28 -9
- lightning_sdk/api/user_api.py +5 -0
- lightning_sdk/cli/cp/__init__.py +64 -0
- lightning_sdk/cli/entrypoint.py +2 -0
- lightning_sdk/cli/groups.py +22 -0
- lightning_sdk/cli/legacy/clusters_menu.py +2 -2
- lightning_sdk/cli/legacy/deploy/_auth.py +7 -6
- lightning_sdk/cli/legacy/download.py +2 -1
- lightning_sdk/cli/legacy/run.py +13 -2
- lightning_sdk/cli/legacy/studios_menu.py +8 -1
- lightning_sdk/cli/studio/__init__.py +4 -0
- lightning_sdk/cli/studio/cp.py +20 -64
- lightning_sdk/cli/studio/ls.py +57 -0
- lightning_sdk/cli/studio/rm.py +71 -0
- lightning_sdk/cli/utils/logging.py +2 -1
- lightning_sdk/cli/utils/studio_filesystem.py +65 -0
- lightning_sdk/cli/utils/teamspace_selection.py +5 -0
- lightning_sdk/exceptions.py +4 -0
- lightning_sdk/job/base.py +24 -5
- lightning_sdk/job/job.py +12 -5
- lightning_sdk/job/v1.py +5 -2
- lightning_sdk/job/v2.py +9 -1
- lightning_sdk/k8s_cluster.py +9 -10
- lightning_sdk/lightning_cloud/__version__.py +1 -1
- lightning_sdk/lightning_cloud/openapi/__init__.py +46 -3
- lightning_sdk/lightning_cloud/openapi/api/__init__.py +1 -0
- lightning_sdk/lightning_cloud/openapi/api/cloud_space_service_api.py +118 -1
- lightning_sdk/lightning_cloud/openapi/api/cluster_service_api.py +787 -125
- lightning_sdk/lightning_cloud/openapi/api/data_connection_service_api.py +5 -1
- lightning_sdk/lightning_cloud/openapi/api/file_system_service_api.py +11 -11
- lightning_sdk/lightning_cloud/openapi/api/k8_s_cluster_service_api.py +246 -19
- lightning_sdk/lightning_cloud/openapi/api/lightningwork_service_api.py +116 -11
- lightning_sdk/lightning_cloud/openapi/api/lit_logger_service_api.py +588 -2
- lightning_sdk/lightning_cloud/openapi/api/models_store_api.py +9 -1
- lightning_sdk/lightning_cloud/openapi/api/storage_service_api.py +5 -1
- lightning_sdk/lightning_cloud/openapi/api/virtual_machine_service_api.py +557 -0
- lightning_sdk/lightning_cloud/openapi/models/__init__.py +45 -3
- lightning_sdk/lightning_cloud/openapi/models/cloud_space_environment_template_service_update_cloud_space_environment_template_body.py +27 -1
- lightning_sdk/lightning_cloud/openapi/models/cluster_service_add_container_registry_body.py +123 -0
- lightning_sdk/lightning_cloud/openapi/models/cluster_service_create_cluster_capacity_reservation_body.py +53 -1
- lightning_sdk/lightning_cloud/openapi/models/cluster_service_create_machine_body.py +79 -1
- lightning_sdk/lightning_cloud/openapi/models/cluster_service_create_org_cluster_capacity_reservation_body.py +409 -0
- lightning_sdk/lightning_cloud/openapi/models/cluster_service_refresh_container_registry_credentials_body.py +97 -0
- lightning_sdk/lightning_cloud/openapi/models/cluster_service_report_machine_system_metrics_body.py +123 -0
- lightning_sdk/lightning_cloud/openapi/models/cluster_service_validate_container_registry_body.py +97 -0
- lightning_sdk/lightning_cloud/openapi/models/externalv1_cloud_space_instance_status.py +27 -1
- lightning_sdk/lightning_cloud/openapi/models/lit_logger_service_create_lit_logger_media_body.py +305 -0
- lightning_sdk/lightning_cloud/openapi/models/lit_logger_service_update_lit_logger_media_body.py +149 -0
- lightning_sdk/lightning_cloud/openapi/models/lit_logger_service_update_metrics_stream_body.py +53 -1
- lightning_sdk/lightning_cloud/openapi/models/v1_add_container_registry_response.py +123 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_capacity_reservation_used_by.py +227 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_cloud_provider.py +1 -1
- lightning_sdk/lightning_cloud/openapi/models/v1_cloud_space_environment_template_config.py +27 -1
- lightning_sdk/lightning_cloud/openapi/models/v1_cloud_space_environment_type.py +1 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_cloud_space_specialized_view.py +1 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_cluster_accelerator.py +27 -1
- lightning_sdk/lightning_cloud/openapi/models/v1_cluster_capacity_reservation.py +27 -1
- lightning_sdk/lightning_cloud/openapi/models/v1_cluster_spec.py +53 -27
- lightning_sdk/lightning_cloud/openapi/models/v1_cluster_type.py +0 -1
- lightning_sdk/lightning_cloud/openapi/models/v1_container_registry.py +253 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_container_registry_info.py +281 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_container_registry_integration.py +123 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_container_registry_status.py +105 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_create_cloud_space_environment_template_request.py +27 -1
- lightning_sdk/lightning_cloud/openapi/models/v1_create_lit_logger_media_response.py +149 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_create_org_cluster_capacity_reservation_response.py +201 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_create_sdk_command_history_request.py +29 -3
- lightning_sdk/lightning_cloud/openapi/models/v1_cudo_direct_v1.py +175 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_delete_container_registry_response.py +97 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_delete_lit_logger_media_response.py +97 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_delete_virtual_machine_response.py +97 -0
- lightning_sdk/lightning_cloud/openapi/models/{v1_ai_pod_v1.py → v1_ecr_registry_config.py} +49 -49
- lightning_sdk/lightning_cloud/openapi/models/v1_ecr_registry_config_input.py +123 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_ecr_registry_details.py +201 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_external_cluster_spec.py +27 -27
- lightning_sdk/lightning_cloud/openapi/models/v1_external_search_user.py +27 -1
- lightning_sdk/lightning_cloud/openapi/models/v1_get_artifacts_page_response.py +29 -3
- lightning_sdk/lightning_cloud/openapi/models/v1_get_kubernetes_pod_logs_response.py +149 -0
- lightning_sdk/lightning_cloud/openapi/models/{v1_get_machine_response.py → v1_get_kubernetes_pod_response.py} +23 -23
- lightning_sdk/lightning_cloud/openapi/models/v1_get_user_response.py +27 -1
- lightning_sdk/lightning_cloud/openapi/models/v1_job_spec.py +27 -1
- lightning_sdk/lightning_cloud/openapi/models/v1_joinable_organization.py +27 -1
- lightning_sdk/lightning_cloud/openapi/models/v1_k8s_incident_setting.py +149 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_k8s_incident_type.py +108 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_kubernetes_direct_settings_v1.py +53 -1
- lightning_sdk/lightning_cloud/openapi/models/v1_kubernetes_direct_v1.py +105 -1
- lightning_sdk/lightning_cloud/openapi/models/v1_kubernetes_pod.py +27 -1
- lightning_sdk/lightning_cloud/openapi/models/v1_kubernetes_pod_logs_page.py +227 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_kubevirt_config.py +357 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_list_container_registries_response.py +123 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_list_kubernetes_pods_response.py +43 -17
- lightning_sdk/lightning_cloud/openapi/models/v1_list_kubernetes_pods_sort_order.py +104 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_list_lit_logger_media_response.py +149 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_list_models_response.py +55 -3
- lightning_sdk/lightning_cloud/openapi/models/v1_list_virtual_machines_response.py +123 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_lit_logger_media.py +513 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_machine.py +53 -53
- lightning_sdk/lightning_cloud/openapi/models/v1_machine_direct_v1.py +107 -3
- lightning_sdk/lightning_cloud/openapi/models/v1_media_type.py +104 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_nebius_direct_v1.py +29 -3
- lightning_sdk/lightning_cloud/openapi/models/v1_node_metrics.py +27 -1
- lightning_sdk/lightning_cloud/openapi/models/v1_organization.py +27 -1
- lightning_sdk/lightning_cloud/openapi/models/v1_refresh_container_registry_credentials_response.py +123 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_report_cloud_space_instance_idle_state_response.py +97 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_report_machine_system_metrics_response.py +97 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_search_user.py +27 -1
- lightning_sdk/lightning_cloud/openapi/models/v1_tenant_credentials.py +201 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_user_features.py +217 -113
- lightning_sdk/lightning_cloud/openapi/models/v1_validate_container_registry_response.py +149 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_virtual_machine.py +409 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_vm_configuration.py +149 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_vm_provider_configuration.py +227 -0
- lightning_sdk/lightning_cloud/openapi/models/virtual_machine_service_create_virtual_machine_body.py +565 -0
- lightning_sdk/lightning_cloud/openapi/models/virtual_machine_service_update_virtual_machine_body.py +97 -0
- lightning_sdk/lightning_cloud/openapi/rest.py +2 -2
- lightning_sdk/lightning_cloud/rest_client.py +0 -2
- lightning_sdk/machine.py +3 -3
- lightning_sdk/mmt/base.py +26 -7
- lightning_sdk/mmt/mmt.py +11 -6
- lightning_sdk/mmt/v1.py +5 -2
- lightning_sdk/mmt/v2.py +5 -2
- lightning_sdk/organization.py +10 -1
- lightning_sdk/owner.py +4 -0
- lightning_sdk/plugin.py +2 -2
- lightning_sdk/studio.py +47 -6
- lightning_sdk/user.py +22 -2
- lightning_sdk/utils/logging.py +2 -1
- lightning_sdk/utils/resolve.py +9 -7
- {lightning_sdk-2025.12.16.dist-info → lightning_sdk-2026.1.22.dist-info}/METADATA +1 -5
- {lightning_sdk-2025.12.16.dist-info → lightning_sdk-2026.1.22.dist-info}/RECORD +139 -94
- {lightning_sdk-2025.12.16.dist-info → lightning_sdk-2026.1.22.dist-info}/WHEEL +1 -1
- lightning_sdk/lightning_cloud/cli/__main__.py +0 -29
- lightning_sdk/lightning_cloud/source_code/logs_socket_api.py +0 -103
- /lightning_sdk/lightning_cloud/openapi/models/{v1_list_filesystem_mm_ts_response.py → v1_list_filesystem_mmts_response.py} +0 -0
- {lightning_sdk-2025.12.16.dist-info → lightning_sdk-2026.1.22.dist-info}/LICENSE +0 -0
- {lightning_sdk-2025.12.16.dist-info → lightning_sdk-2026.1.22.dist-info}/entry_points.txt +0 -0
- {lightning_sdk-2025.12.16.dist-info → lightning_sdk-2026.1.22.dist-info}/top_level.txt +0 -0
lightning_sdk/machine.py
CHANGED
|
@@ -162,12 +162,12 @@ Machine.CPU_X_4 = Machine(name="CPU_X_4", slug="cpu-4", family="CPU", accelerato
|
|
|
162
162
|
Machine.CPU_X_8 = Machine(name="CPU_X_8", slug="cpu-8", family="CPU", accelerator_count=8)
|
|
163
163
|
Machine.CPU_X_16 = Machine(name="CPU_X_16", slug="cpu-16", family="CPU", accelerator_count=16)
|
|
164
164
|
# available data-prep (big disk) machines
|
|
165
|
-
Machine.DATA_PREP = Machine(name="DATA_PREP", slug="data-prep-mid", family="
|
|
165
|
+
Machine.DATA_PREP = Machine(name="DATA_PREP", slug="data-prep-mid", family="DATA-PREP", accelerator_count=32)
|
|
166
166
|
Machine.DATA_PREP_MAX = Machine(
|
|
167
|
-
name="DATA_PREP_MAX", slug="data-prep-max-large", family="
|
|
167
|
+
name="DATA_PREP_MAX", slug="data-prep-max-large", family="DATA-PREP", accelerator_count=64
|
|
168
168
|
)
|
|
169
169
|
Machine.DATA_PREP_ULTRA = Machine(
|
|
170
|
-
name="DATA_PREP_ULTRA", slug="data-prep-ultra-extra-large", family="
|
|
170
|
+
name="DATA_PREP_ULTRA", slug="data-prep-ultra-extra-large", family="DATA-PREP", accelerator_count=96
|
|
171
171
|
)
|
|
172
172
|
|
|
173
173
|
# GPU machines
|
lightning_sdk/mmt/base.py
CHANGED
|
@@ -69,7 +69,7 @@ class _BaseMMT(_BaseJob):
|
|
|
69
69
|
interruptible: bool = False,
|
|
70
70
|
image_credentials: Optional[str] = None,
|
|
71
71
|
cloud_account_auth: bool = False,
|
|
72
|
-
entrypoint: str =
|
|
72
|
+
entrypoint: Optional[str] = None,
|
|
73
73
|
path_mappings: Optional[Dict[str, str]] = None,
|
|
74
74
|
max_runtime: Optional[int] = None,
|
|
75
75
|
artifacts_local: Optional[str] = None, # deprecated in favor of path_mappings
|
|
@@ -104,8 +104,10 @@ class _BaseMMT(_BaseJob):
|
|
|
104
104
|
cloud_account_auth: Whether to authenticate with the cloud account to pull the image.
|
|
105
105
|
Required if the registry is part of a cloud provider (e.g. ECR).
|
|
106
106
|
entrypoint: The entrypoint of your docker container. Defaults to `sh -c` which
|
|
107
|
-
just runs the provided command in a standard shell.
|
|
108
|
-
|
|
107
|
+
just runs the provided command in a standard shell if a command is provided.
|
|
108
|
+
If no command is provided, it will run the pre-defined entrypoint of the provided image.
|
|
109
|
+
To use the pre-defined entrypoint of the provided image with a specified command,
|
|
110
|
+
set this to an empty string.
|
|
109
111
|
Only applicable when submitting docker jobs.
|
|
110
112
|
path_mappings: Dictionary of path mappings. The keys are the path inside the container whereas the value
|
|
111
113
|
represents the data-connection name and the path inside that connection.
|
|
@@ -173,7 +175,7 @@ class _BaseMMT(_BaseJob):
|
|
|
173
175
|
"Other jobs will automatically persist artifacts to the teamspace distributed filesystem."
|
|
174
176
|
)
|
|
175
177
|
|
|
176
|
-
if entrypoint
|
|
178
|
+
if entrypoint is not None:
|
|
177
179
|
raise ValueError("Specifying the entrypoint has no effect for jobs with Studio envs.")
|
|
178
180
|
|
|
179
181
|
else:
|
|
@@ -199,6 +201,20 @@ class _BaseMMT(_BaseJob):
|
|
|
199
201
|
f"<CONNECTION_TYPE>:<CONNECTION_NAME>:<PATH_WITHIN_CONNECTION>, got {artifacts_local}"
|
|
200
202
|
)
|
|
201
203
|
|
|
204
|
+
# command specified, so use the default entrypoint of sh -c
|
|
205
|
+
if command is not None and entrypoint is None:
|
|
206
|
+
entrypoint = "sh -c"
|
|
207
|
+
|
|
208
|
+
# entrypoint specifically set to empty string, so set to None here to fall back to the image entrypoint
|
|
209
|
+
elif entrypoint == "": # noqa: SIM114
|
|
210
|
+
entrypoint = None
|
|
211
|
+
|
|
212
|
+
# entrypoint not specified, but also no command specified, so use the image entrypoint
|
|
213
|
+
elif entrypoint is None:
|
|
214
|
+
entrypoint = None
|
|
215
|
+
|
|
216
|
+
# all other cases, the entrypoint has been specifically set, so use it as is
|
|
217
|
+
|
|
202
218
|
inst = cls(name=name, teamspace=teamspace, org=org, user=user, _fetch_job=False)
|
|
203
219
|
inst._submit(
|
|
204
220
|
num_machines=num_machines,
|
|
@@ -235,7 +251,7 @@ class _BaseMMT(_BaseJob):
|
|
|
235
251
|
cloud_provider: Optional[Union["CloudProvider", str]] = None,
|
|
236
252
|
image_credentials: Optional[str] = None,
|
|
237
253
|
cloud_account_auth: bool = False,
|
|
238
|
-
entrypoint: str =
|
|
254
|
+
entrypoint: Optional[str] = None,
|
|
239
255
|
path_mappings: Optional[Dict[str, str]] = None,
|
|
240
256
|
artifacts_local: Optional[str] = None, # deprecated in favor of path_mappings
|
|
241
257
|
artifacts_remote: Optional[str] = None, # deprecated in favor of path_mappings
|
|
@@ -260,8 +276,11 @@ class _BaseMMT(_BaseJob):
|
|
|
260
276
|
This should be the name of the respective credentials secret created on the Lightning AI platform.
|
|
261
277
|
cloud_account_auth: Whether to authenticate with the cloud account to pull the image.
|
|
262
278
|
Required if the registry is part of a cloud provider (e.g. ECR).
|
|
263
|
-
entrypoint: The entrypoint of your docker container. Defaults to sh -c
|
|
264
|
-
|
|
279
|
+
entrypoint: The entrypoint of your docker container. Defaults to `sh -c` which
|
|
280
|
+
just runs the provided command in a standard shell if a command is provided.
|
|
281
|
+
If no command is provided, it will run the pre-defined entrypoint of the provided image.
|
|
282
|
+
To use the pre-defined entrypoint of the provided image with a specified command,
|
|
283
|
+
set this to an empty string.
|
|
265
284
|
Only applicable when submitting docker jobs.
|
|
266
285
|
path_mappings: Dictionary of path mappings. The keys are the path inside the container whereas the value
|
|
267
286
|
represents the data-connection name and the path inside that connection.
|
lightning_sdk/mmt/mmt.py
CHANGED
|
@@ -100,7 +100,7 @@ class MMT(_BaseMMT):
|
|
|
100
100
|
interruptible: bool = False,
|
|
101
101
|
image_credentials: Optional[str] = None,
|
|
102
102
|
cloud_account_auth: bool = False,
|
|
103
|
-
entrypoint: str =
|
|
103
|
+
entrypoint: Optional[str] = None,
|
|
104
104
|
path_mappings: Optional[Dict[str, str]] = None,
|
|
105
105
|
max_runtime: Optional[int] = None,
|
|
106
106
|
artifacts_local: Optional[str] = None,
|
|
@@ -134,8 +134,11 @@ class MMT(_BaseMMT):
|
|
|
134
134
|
This should be the name of the respective credentials secret created on the Lightning AI platform.
|
|
135
135
|
cloud_account_auth: Whether to authenticate with the cloud account to pull the image.
|
|
136
136
|
Required if the registry is part of a cloud provider (e.g. ECR).
|
|
137
|
-
entrypoint: The entrypoint of your docker container. Defaults to sh -c
|
|
138
|
-
|
|
137
|
+
entrypoint: The entrypoint of your docker container. Defaults to `sh -c` which
|
|
138
|
+
just runs the provided command in a standard shell if a command is provided.
|
|
139
|
+
If no command is provided, it will run the pre-defined entrypoint of the provided image.
|
|
140
|
+
To use the pre-defined entrypoint of the provided image with a specified command,
|
|
141
|
+
set this to an empty string.
|
|
139
142
|
Only applicable when submitting docker jobs.
|
|
140
143
|
path_mappings: Dictionary of path mappings. The keys are the path inside the container whereas the value
|
|
141
144
|
represents the data-connection name and the path inside that connection.
|
|
@@ -194,7 +197,7 @@ class MMT(_BaseMMT):
|
|
|
194
197
|
cloud_provider: Optional[Union["CloudProvider", str]] = None,
|
|
195
198
|
image_credentials: Optional[str] = None,
|
|
196
199
|
cloud_account_auth: bool = False,
|
|
197
|
-
entrypoint: str =
|
|
200
|
+
entrypoint: Optional[str] = None,
|
|
198
201
|
path_mappings: Optional[Dict[str, str]] = None,
|
|
199
202
|
max_runtime: Optional[int] = None,
|
|
200
203
|
artifacts_local: Optional[str] = None, # deprecated in favor of path_mappings
|
|
@@ -224,8 +227,10 @@ class MMT(_BaseMMT):
|
|
|
224
227
|
cloud_account_auth: Whether to authenticate with the cloud account to pull the image.
|
|
225
228
|
Required if the registry is part of a cloud provider (e.g. ECR).
|
|
226
229
|
entrypoint: The entrypoint of your docker container. Defaults to `sh -c` which
|
|
227
|
-
just runs the provided command in a standard shell.
|
|
228
|
-
|
|
230
|
+
just runs the provided command in a standard shell if a command is provided.
|
|
231
|
+
If no command is provided, it will run the pre-defined entrypoint of the provided image.
|
|
232
|
+
To use the pre-defined entrypoint of the provided image with a specified command,
|
|
233
|
+
set this to an empty string.
|
|
229
234
|
Only applicable when submitting docker jobs.
|
|
230
235
|
path_mappings: Dictionary of path mappings. The keys are the path inside the container whereas the value
|
|
231
236
|
represents the data-connection name and the path inside that connection.
|
lightning_sdk/mmt/v1.py
CHANGED
|
@@ -53,7 +53,7 @@ class _MMTV1(_BaseMMT):
|
|
|
53
53
|
cloud_provider: Optional[Union["CloudProvider", str]] = None,
|
|
54
54
|
image_credentials: Optional[str] = None,
|
|
55
55
|
cloud_account_auth: bool = False,
|
|
56
|
-
entrypoint: str =
|
|
56
|
+
entrypoint: Optional[str] = None,
|
|
57
57
|
path_mappings: Optional[Dict[str, str]] = None,
|
|
58
58
|
max_runtime: Optional[int] = None,
|
|
59
59
|
artifacts_local: Optional[str] = None,
|
|
@@ -89,7 +89,10 @@ class _MMTV1(_BaseMMT):
|
|
|
89
89
|
Note that the connection needs to be added to the teamspace already in order for it to be found.
|
|
90
90
|
Only supported for jobs with a docker image compute environment.
|
|
91
91
|
entrypoint: The entrypoint of your docker container. Defaults to `sh -c` which
|
|
92
|
-
just runs the provided command in a standard shell.
|
|
92
|
+
just runs the provided command in a standard shell if a command is provided.
|
|
93
|
+
If no command is provided, it will run the pre-defined entrypoint of the provided image.
|
|
94
|
+
To use the pre-defined entrypoint of the provided image with a specified command,
|
|
95
|
+
set this to an empty string.
|
|
93
96
|
To use the pre-defined entrypoint of the provided image, set this to an empty string.
|
|
94
97
|
Only applicable when submitting docker jobs.
|
|
95
98
|
path_mappings: The mappings from data connection inside your container (not supported)
|
lightning_sdk/mmt/v2.py
CHANGED
|
@@ -53,7 +53,7 @@ class _MMTV2(_BaseMMT):
|
|
|
53
53
|
cloud_provider: Optional[Union["CloudProvider", str]] = None,
|
|
54
54
|
image_credentials: Optional[str] = None,
|
|
55
55
|
cloud_account_auth: bool = False,
|
|
56
|
-
entrypoint: str =
|
|
56
|
+
entrypoint: Optional[str] = None,
|
|
57
57
|
path_mappings: Optional[Dict[str, str]] = None,
|
|
58
58
|
max_runtime: Optional[int] = None,
|
|
59
59
|
artifacts_local: Optional[str] = None, # deprecated in favor of path_mappings
|
|
@@ -83,7 +83,10 @@ class _MMTV2(_BaseMMT):
|
|
|
83
83
|
cloud_account_auth: Whether to authenticate with the cloud account to pull the image.
|
|
84
84
|
Required if the registry is part of a cloud provider (e.g. ECR).
|
|
85
85
|
entrypoint: The entrypoint of your docker container. Defaults to `sh -c` which
|
|
86
|
-
just runs the provided command in a standard shell.
|
|
86
|
+
just runs the provided command in a standard shell if a command is provided.
|
|
87
|
+
If no command is provided, it will run the pre-defined entrypoint of the provided image.
|
|
88
|
+
To use the pre-defined entrypoint of the provided image with a specified command,
|
|
89
|
+
set this to an empty string.
|
|
87
90
|
To use the pre-defined entrypoint of the provided image, set this to an empty string.
|
|
88
91
|
Only applicable when submitting docker jobs.
|
|
89
92
|
path_mappings: Dictionary of path mappings. The keys are the path inside the container whereas the value
|
lightning_sdk/organization.py
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
|
-
from typing import Optional
|
|
1
|
+
from typing import TYPE_CHECKING, Optional
|
|
2
2
|
|
|
3
3
|
from lightning_sdk.api import OrgApi
|
|
4
4
|
from lightning_sdk.owner import Owner
|
|
5
5
|
from lightning_sdk.utils.resolve import _resolve_org_name
|
|
6
6
|
|
|
7
|
+
if TYPE_CHECKING:
|
|
8
|
+
from lightning_sdk.teamspace import Teamspace
|
|
9
|
+
|
|
7
10
|
|
|
8
11
|
class Organization(Owner):
|
|
9
12
|
"""Represents an organization owner of teamspaces and studios.
|
|
@@ -44,6 +47,12 @@ class Organization(Owner):
|
|
|
44
47
|
def default_cloud_account(self) -> Optional[str]:
|
|
45
48
|
return self._org.preferred_cluster or None
|
|
46
49
|
|
|
50
|
+
def create_teamspace(self, name: str) -> "Teamspace":
|
|
51
|
+
from lightning_sdk.teamspace import Teamspace
|
|
52
|
+
|
|
53
|
+
self._org_api.create_teamspace(name, self.id)
|
|
54
|
+
return Teamspace(name=name, org=self)
|
|
55
|
+
|
|
47
56
|
def __repr__(self) -> str:
|
|
48
57
|
"""Returns reader friendly representation."""
|
|
49
58
|
return f"Organization(name={self.name})"
|
lightning_sdk/owner.py
CHANGED
|
@@ -24,6 +24,10 @@ class Owner(ABC, metaclass=TrackCallsABCMeta):
|
|
|
24
24
|
def id(self) -> str:
|
|
25
25
|
"""The owner's ID."""
|
|
26
26
|
|
|
27
|
+
@abstractmethod
|
|
28
|
+
def create_teamspace(self, name: str) -> "Teamspace":
|
|
29
|
+
"""Creates a new teamspace."""
|
|
30
|
+
|
|
27
31
|
@property
|
|
28
32
|
def teamspaces(self) -> List["Teamspace"]:
|
|
29
33
|
"""All teamspaces by this owner."""
|
lightning_sdk/plugin.py
CHANGED
|
@@ -411,12 +411,12 @@ class CustomPortPlugin(_Plugin):
|
|
|
411
411
|
if name is None:
|
|
412
412
|
name = _run_name("port")
|
|
413
413
|
|
|
414
|
-
return self._studio._studio_api.
|
|
414
|
+
return self._studio._studio_api.add_port(
|
|
415
415
|
teamspace_id=self._studio._teamspace.id,
|
|
416
416
|
studio_id=self._studio._studio.id,
|
|
417
417
|
name=name,
|
|
418
418
|
port=port,
|
|
419
|
-
)
|
|
419
|
+
).urls[0]
|
|
420
420
|
|
|
421
421
|
|
|
422
422
|
@runtime_checkable
|
lightning_sdk/studio.py
CHANGED
|
@@ -2,7 +2,7 @@ import glob
|
|
|
2
2
|
import os
|
|
3
3
|
import threading
|
|
4
4
|
import warnings
|
|
5
|
-
from typing import TYPE_CHECKING, Any, Dict, Mapping, Optional, Tuple, Union
|
|
5
|
+
from typing import TYPE_CHECKING, Any, Dict, List, Mapping, Optional, Tuple, Union
|
|
6
6
|
|
|
7
7
|
from tqdm.auto import tqdm
|
|
8
8
|
|
|
@@ -11,8 +11,8 @@ from lightning_sdk.api.studio_api import StudioApi
|
|
|
11
11
|
from lightning_sdk.api.utils import AccessibleResource, raise_access_error_if_not_allowed
|
|
12
12
|
from lightning_sdk.base_studio import BaseStudio
|
|
13
13
|
from lightning_sdk.constants import _LIGHTNING_DEBUG
|
|
14
|
-
from lightning_sdk.exceptions import OutOfCapacityError
|
|
15
|
-
from lightning_sdk.lightning_cloud.openapi import V1ClusterType
|
|
14
|
+
from lightning_sdk.exceptions import NotSupportedError, OutOfCapacityError
|
|
15
|
+
from lightning_sdk.lightning_cloud.openapi import V1ClusterType, V1Endpoint
|
|
16
16
|
from lightning_sdk.machine import DEFAULT_MACHINE, CloudProvider, Machine
|
|
17
17
|
from lightning_sdk.organization import Organization
|
|
18
18
|
from lightning_sdk.owner import Owner
|
|
@@ -341,12 +341,20 @@ class Studio(metaclass=TrackCallsMeta):
|
|
|
341
341
|
if new_machine != self.machine:
|
|
342
342
|
raise RuntimeError(
|
|
343
343
|
f"Requested to start {self._cls_name} on {new_machine}, "
|
|
344
|
-
"but {self._cls_name} is already running on {self.machine}."
|
|
344
|
+
f"but {self._cls_name} is already running on {self.machine}."
|
|
345
345
|
" Consider switching instead!"
|
|
346
346
|
)
|
|
347
347
|
_logger.info(f"{self._cls_name} {self.name} is already running")
|
|
348
348
|
return
|
|
349
349
|
|
|
350
|
+
if not self._studio_api.machine_is_supported(
|
|
351
|
+
new_machine, self._teamspace.id, self.cloud_account, _get_org_id(self._teamspace)
|
|
352
|
+
):
|
|
353
|
+
raise NotSupportedError(
|
|
354
|
+
"Requested machine is not supported in the selected cloud account. "
|
|
355
|
+
"Try a different machine or cloud account by setting the `machine` or `cloud_account` argument."
|
|
356
|
+
)
|
|
357
|
+
|
|
350
358
|
if not self._studio_api.machine_has_capacity(
|
|
351
359
|
new_machine,
|
|
352
360
|
self._teamspace.id,
|
|
@@ -548,7 +556,7 @@ class Studio(metaclass=TrackCallsMeta):
|
|
|
548
556
|
if status != Status.Running:
|
|
549
557
|
raise RuntimeError(
|
|
550
558
|
f"Cannot run a command in a {self._cls_name} that is not running. "
|
|
551
|
-
"{self._cls_name} {self.name} is {status}."
|
|
559
|
+
f"{self._cls_name} {self.name} is {status}."
|
|
552
560
|
)
|
|
553
561
|
output, exit_code = self._studio_api.run_studio_commands(self._studio.id, self._teamspace.id, *commands)
|
|
554
562
|
output = output.strip()
|
|
@@ -605,11 +613,13 @@ class Studio(metaclass=TrackCallsMeta):
|
|
|
605
613
|
progress_bar = tqdm(total=len(all_files), desc="Uploading files", unit="file")
|
|
606
614
|
for local_file, remote_path in sorted(all_files, key=lambda p: p[1]):
|
|
607
615
|
if progress_bar:
|
|
608
|
-
progress_bar.set_description(
|
|
616
|
+
progress_bar.set_description("Uploading files")
|
|
609
617
|
self.upload_file(local_file, remote_path=remote_path, progress_bar=False)
|
|
610
618
|
if progress_bar:
|
|
611
619
|
progress_bar.update(1)
|
|
612
620
|
if progress_bar:
|
|
621
|
+
progress_bar.set_description("Upload complete")
|
|
622
|
+
progress_bar.refresh()
|
|
613
623
|
progress_bar.close()
|
|
614
624
|
|
|
615
625
|
def download_file(self, remote_path: str, file_path: Optional[str] = None) -> None:
|
|
@@ -707,6 +717,37 @@ class Studio(metaclass=TrackCallsMeta):
|
|
|
707
717
|
interruptible=interruptible,
|
|
708
718
|
)
|
|
709
719
|
|
|
720
|
+
def add_ports(self, ports: Union[int, List[int], Dict[str, int]]) -> List[V1Endpoint]:
|
|
721
|
+
"""Add one or more ports to the studio and return their endpoints.
|
|
722
|
+
|
|
723
|
+
Args:
|
|
724
|
+
ports: Port to add. Can be:
|
|
725
|
+
- int: Single port (e.g., 8080)
|
|
726
|
+
- List[int]: Multiple ports ()
|
|
727
|
+
- dict[str, int]: Named ports (e.g., {"web": 8080})
|
|
728
|
+
|
|
729
|
+
Returns:
|
|
730
|
+
List of V1Endpoint objects. Access endpoint properties like:
|
|
731
|
+
- endpoint.name: Port name (None for unnamed ports)
|
|
732
|
+
- endpoint.ports: List of port numbers
|
|
733
|
+
- endpoint.urls: List of accessible URLs
|
|
734
|
+
"""
|
|
735
|
+
if isinstance(ports, dict):
|
|
736
|
+
port_items = ports.items()
|
|
737
|
+
elif isinstance(ports, list):
|
|
738
|
+
port_items = ((None, port) for port in ports)
|
|
739
|
+
else:
|
|
740
|
+
port_items = [(None, ports)]
|
|
741
|
+
|
|
742
|
+
return [
|
|
743
|
+
self._studio_api.add_port(self._teamspace.id, self._studio.id, name=name, port=port)
|
|
744
|
+
for name, port in port_items
|
|
745
|
+
]
|
|
746
|
+
|
|
747
|
+
def list_ports(self) -> List[V1Endpoint]:
|
|
748
|
+
"""List ports that are exposed in the Studio."""
|
|
749
|
+
return self._studio_api.list_ports(self._teamspace.id, self._studio.id)
|
|
750
|
+
|
|
710
751
|
def create_assistant(self, name: str, port: int) -> None:
|
|
711
752
|
assistant = self._studio_api.create_assistant(
|
|
712
753
|
studio_id=self._studio.id, teamspace_id=self._teamspace.id, port=port, assistant_name=name
|
lightning_sdk/user.py
CHANGED
|
@@ -1,8 +1,12 @@
|
|
|
1
|
-
from typing import Dict, Optional
|
|
1
|
+
from typing import TYPE_CHECKING, Dict, List, Optional
|
|
2
2
|
|
|
3
3
|
from lightning_sdk.api import UserApi
|
|
4
4
|
from lightning_sdk.owner import Owner
|
|
5
|
-
from lightning_sdk.utils.resolve import _resolve_user_name
|
|
5
|
+
from lightning_sdk.utils.resolve import _get_authed_user, _get_organizations_for_authed_user, _resolve_user_name
|
|
6
|
+
|
|
7
|
+
if TYPE_CHECKING:
|
|
8
|
+
from lightning_sdk.organization import Organization
|
|
9
|
+
from lightning_sdk.teamspace import Teamspace
|
|
6
10
|
|
|
7
11
|
|
|
8
12
|
class User(Owner):
|
|
@@ -55,6 +59,22 @@ class User(Owner):
|
|
|
55
59
|
|
|
56
60
|
self._user_api.set_secret(key, value)
|
|
57
61
|
|
|
62
|
+
def create_teamspace(self, name: str) -> "Teamspace":
|
|
63
|
+
from lightning_sdk.teamspace import Teamspace
|
|
64
|
+
|
|
65
|
+
if not _get_authed_user().id == self.id:
|
|
66
|
+
raise ValueError("Can only create teamspaces for currently authenticated user")
|
|
67
|
+
|
|
68
|
+
self._user_api.create_teamspace(name)
|
|
69
|
+
return Teamspace(name=name, user=self)
|
|
70
|
+
|
|
71
|
+
@property
|
|
72
|
+
def organizations(self) -> List["Organization"]:
|
|
73
|
+
if not _get_authed_user().id == self.id:
|
|
74
|
+
raise ValueError("Can only list organizations for currently authenticated user")
|
|
75
|
+
|
|
76
|
+
return _get_organizations_for_authed_user(user_api=self._user_api)
|
|
77
|
+
|
|
58
78
|
def __repr__(self) -> str:
|
|
59
79
|
"""Returns reader friendly representation."""
|
|
60
80
|
return f"User(name={self.name})"
|
lightning_sdk/utils/logging.py
CHANGED
|
@@ -22,7 +22,7 @@ def track_calls() -> Callable[..., any]:
|
|
|
22
22
|
bound_args.apply_defaults()
|
|
23
23
|
|
|
24
24
|
args_str = ", ".join(f"{k}: {v}" for k, v in bound_args.arguments.items() if k != "self")
|
|
25
|
-
message = f"
|
|
25
|
+
message = f"ARGS: {args_str} "
|
|
26
26
|
|
|
27
27
|
body = V1CreateSDKCommandHistoryRequest(
|
|
28
28
|
command=func.__qualname__,
|
|
@@ -30,6 +30,7 @@ def track_calls() -> Callable[..., any]:
|
|
|
30
30
|
project_id=None,
|
|
31
31
|
severity=V1SDKCommandHistorySeverity.INFO,
|
|
32
32
|
type=V1SDKCommandHistoryType.SDK,
|
|
33
|
+
version=__version__,
|
|
33
34
|
)
|
|
34
35
|
|
|
35
36
|
try:
|
lightning_sdk/utils/resolve.py
CHANGED
|
@@ -2,6 +2,7 @@ import logging
|
|
|
2
2
|
import os
|
|
3
3
|
import warnings
|
|
4
4
|
from contextlib import contextmanager
|
|
5
|
+
from functools import lru_cache
|
|
5
6
|
from typing import TYPE_CHECKING, Generator, List, Optional, Tuple, Union
|
|
6
7
|
|
|
7
8
|
from lightning_sdk.api import TeamspaceApi, UserApi
|
|
@@ -222,25 +223,26 @@ def _resolve_teamspace(
|
|
|
222
223
|
raise RuntimeError("Neither user nor org provided, but one of them needs to be provided")
|
|
223
224
|
|
|
224
225
|
|
|
225
|
-
def _get_organizations_for_authed_user() -> List["Organization"]:
|
|
226
|
+
def _get_organizations_for_authed_user(user_api: Optional[UserApi] = None) -> List["Organization"]:
|
|
226
227
|
"""Returns Organizations the current Authed user is a member of."""
|
|
227
228
|
from lightning_sdk.organization import Organization
|
|
228
229
|
|
|
229
|
-
_orgs = UserApi()._get_organizations_for_authed_user()
|
|
230
|
+
_orgs = (user_api or UserApi())._get_organizations_for_authed_user()
|
|
230
231
|
return [Organization(_org.name) for _org in _orgs]
|
|
231
232
|
|
|
232
233
|
|
|
233
|
-
def _get_teamspace_names_for_authed_user() -> List[str]:
|
|
234
|
+
def _get_teamspace_names_for_authed_user(user_api: Optional[UserApi] = None) -> List[str]:
|
|
234
235
|
"""Returns Teamspace's names the current Authed user is a member of."""
|
|
235
|
-
teamspaces = UserApi()._get_all_teamspace_memberships("")
|
|
236
|
+
teamspaces = (user_api or UserApi())._get_all_teamspace_memberships("")
|
|
236
237
|
return sorted([ts.name for ts in teamspaces])
|
|
237
238
|
|
|
238
239
|
|
|
239
|
-
|
|
240
|
+
@lru_cache(maxsize=1)
|
|
241
|
+
def _get_authed_user(user_api: Optional[UserApi] = None, teamspace_api: Optional[TeamspaceApi] = None) -> "User":
|
|
240
242
|
from lightning_sdk.user import User
|
|
241
243
|
|
|
242
|
-
user_id = TeamspaceApi()._get_authed_user_id()
|
|
243
|
-
_user = UserApi()._get_user_by_id(user_id)
|
|
244
|
+
user_id = (teamspace_api or TeamspaceApi())._get_authed_user_id()
|
|
245
|
+
_user = (user_api or UserApi())._get_user_by_id(user_id)
|
|
244
246
|
return User(name=_user.username)
|
|
245
247
|
|
|
246
248
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: lightning_sdk
|
|
3
|
-
Version:
|
|
3
|
+
Version: 2026.1.22
|
|
4
4
|
Summary: SDK to develop using Lightning AI Studios
|
|
5
5
|
Author-email: Lightning-AI <justus@lightning.ai>
|
|
6
6
|
License: MIT License
|
|
@@ -38,8 +38,6 @@ Requires-Dist: click
|
|
|
38
38
|
Requires-Dist: docker
|
|
39
39
|
Requires-Dist: fastapi
|
|
40
40
|
Requires-Dist: packaging
|
|
41
|
-
Requires-Dist: pandas
|
|
42
|
-
Requires-Dist: pyjwt
|
|
43
41
|
Requires-Dist: pyyaml
|
|
44
42
|
Requires-Dist: requests
|
|
45
43
|
Requires-Dist: rich
|
|
@@ -48,8 +46,6 @@ Requires-Dist: six
|
|
|
48
46
|
Requires-Dist: tqdm
|
|
49
47
|
Requires-Dist: urllib3<=2.5.0
|
|
50
48
|
Requires-Dist: uvicorn
|
|
51
|
-
Requires-Dist: websocket-client
|
|
52
|
-
Requires-Dist: wget
|
|
53
49
|
Provides-Extra: serve
|
|
54
50
|
Requires-Dist: litserve>=0.2.5; extra == "serve"
|
|
55
51
|
|