lightning-sdk 0.2.6__py3-none-any.whl → 0.2.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/api/ai_hub_api.py +1 -0
- lightning_sdk/api/lit_container_api.py +83 -30
- lightning_sdk/api/teamspace_api.py +8 -9
- lightning_sdk/api/utils.py +0 -1
- lightning_sdk/cli/docker.py +1 -1
- lightning_sdk/cli/download.py +10 -2
- lightning_sdk/cli/serve.py +51 -41
- lightning_sdk/cli/upload.py +41 -6
- lightning_sdk/lightning_cloud/openapi/__init__.py +8 -0
- lightning_sdk/lightning_cloud/openapi/api/cloud_space_service_api.py +202 -0
- lightning_sdk/lightning_cloud/openapi/models/__init__.py +8 -0
- lightning_sdk/lightning_cloud/openapi/models/alerts_config_billing.py +175 -0
- lightning_sdk/lightning_cloud/openapi/models/alerts_config_studios.py +149 -0
- lightning_sdk/lightning_cloud/openapi/models/orgs_id_body.py +53 -1
- lightning_sdk/lightning_cloud/openapi/models/projects_id_body.py +27 -1
- lightning_sdk/lightning_cloud/openapi/models/server_id_alerts_body.py +27 -1
- lightning_sdk/lightning_cloud/openapi/models/v1_alert_method.py +102 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_alerts_config.py +149 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_cloud_space_cold_start_metrics.py +617 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_conversation_response_chunk.py +29 -3
- lightning_sdk/lightning_cloud/openapi/models/v1_create_project_request.py +27 -1
- lightning_sdk/lightning_cloud/openapi/models/v1_google_cloud_direct_v1.py +29 -3
- lightning_sdk/lightning_cloud/openapi/models/v1_list_cloud_space_cold_start_metrics_response.py +123 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_message.py +29 -3
- lightning_sdk/lightning_cloud/openapi/models/v1_organization.py +53 -1
- lightning_sdk/lightning_cloud/openapi/models/v1_project_settings.py +27 -1
- lightning_sdk/lightning_cloud/openapi/models/v1_report_cloud_space_instance_stop_at_response.py +97 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_server_alert.py +27 -1
- lightning_sdk/lightning_cloud/openapi/models/v1_server_alert_phase.py +104 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_user_features.py +53 -1
- lightning_sdk/lightning_cloud/rest_client.py +42 -44
- lightning_sdk/lit_container.py +19 -4
- lightning_sdk/models.py +1 -1
- lightning_sdk/serve.py +107 -41
- lightning_sdk/teamspace.py +32 -18
- {lightning_sdk-0.2.6.dist-info → lightning_sdk-0.2.8.dist-info}/METADATA +1 -1
- {lightning_sdk-0.2.6.dist-info → lightning_sdk-0.2.8.dist-info}/RECORD +42 -34
- {lightning_sdk-0.2.6.dist-info → lightning_sdk-0.2.8.dist-info}/LICENSE +0 -0
- {lightning_sdk-0.2.6.dist-info → lightning_sdk-0.2.8.dist-info}/WHEEL +0 -0
- {lightning_sdk-0.2.6.dist-info → lightning_sdk-0.2.8.dist-info}/entry_points.txt +0 -0
- {lightning_sdk-0.2.6.dist-info → lightning_sdk-0.2.8.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
|
|
3
|
+
"""
|
|
4
|
+
external/v1/auth_service.proto
|
|
5
|
+
|
|
6
|
+
No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) # noqa: E501
|
|
7
|
+
|
|
8
|
+
OpenAPI spec version: version not set
|
|
9
|
+
|
|
10
|
+
Generated by: https://github.com/swagger-api/swagger-codegen.git
|
|
11
|
+
|
|
12
|
+
NOTE
|
|
13
|
+
----
|
|
14
|
+
standard swagger-codegen-cli for this python client has been modified
|
|
15
|
+
by custom templates. The purpose of these templates is to include
|
|
16
|
+
typing information in the API and Model code. Please refer to the
|
|
17
|
+
main grid repository for more info
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
import pprint
|
|
21
|
+
import re # noqa: F401
|
|
22
|
+
|
|
23
|
+
from typing import TYPE_CHECKING
|
|
24
|
+
|
|
25
|
+
import six
|
|
26
|
+
|
|
27
|
+
if TYPE_CHECKING:
|
|
28
|
+
from datetime import datetime
|
|
29
|
+
from lightning_sdk.lightning_cloud.openapi.models import *
|
|
30
|
+
|
|
31
|
+
class V1ServerAlertPhase(object):
|
|
32
|
+
"""NOTE: This class is auto generated by the swagger code generator program.
|
|
33
|
+
|
|
34
|
+
Do not edit the class manually.
|
|
35
|
+
"""
|
|
36
|
+
|
|
37
|
+
"""
|
|
38
|
+
allowed enum values
|
|
39
|
+
"""
|
|
40
|
+
UNSPECIFIED = "SERVER_ALERT_PHASE_UNSPECIFIED"
|
|
41
|
+
STARTUP = "SERVER_ALERT_PHASE_STARTUP"
|
|
42
|
+
SHUTDOWN = "SERVER_ALERT_PHASE_SHUTDOWN"
|
|
43
|
+
"""
|
|
44
|
+
Attributes:
|
|
45
|
+
swagger_types (dict): The key is attribute name
|
|
46
|
+
and the value is attribute type.
|
|
47
|
+
attribute_map (dict): The key is attribute name
|
|
48
|
+
and the value is json key in definition.
|
|
49
|
+
"""
|
|
50
|
+
swagger_types = {
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
attribute_map = {
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
def __init__(self): # noqa: E501
|
|
57
|
+
"""V1ServerAlertPhase - a model defined in Swagger""" # noqa: E501
|
|
58
|
+
self.discriminator = None
|
|
59
|
+
|
|
60
|
+
def to_dict(self) -> dict:
|
|
61
|
+
"""Returns the model properties as a dict"""
|
|
62
|
+
result = {}
|
|
63
|
+
|
|
64
|
+
for attr, _ in six.iteritems(self.swagger_types):
|
|
65
|
+
value = getattr(self, attr)
|
|
66
|
+
if isinstance(value, list):
|
|
67
|
+
result[attr] = list(map(
|
|
68
|
+
lambda x: x.to_dict() if hasattr(x, "to_dict") else x,
|
|
69
|
+
value
|
|
70
|
+
))
|
|
71
|
+
elif hasattr(value, "to_dict"):
|
|
72
|
+
result[attr] = value.to_dict()
|
|
73
|
+
elif isinstance(value, dict):
|
|
74
|
+
result[attr] = dict(map(
|
|
75
|
+
lambda item: (item[0], item[1].to_dict())
|
|
76
|
+
if hasattr(item[1], "to_dict") else item,
|
|
77
|
+
value.items()
|
|
78
|
+
))
|
|
79
|
+
else:
|
|
80
|
+
result[attr] = value
|
|
81
|
+
if issubclass(V1ServerAlertPhase, dict):
|
|
82
|
+
for key, value in self.items():
|
|
83
|
+
result[key] = value
|
|
84
|
+
|
|
85
|
+
return result
|
|
86
|
+
|
|
87
|
+
def to_str(self) -> str:
|
|
88
|
+
"""Returns the string representation of the model"""
|
|
89
|
+
return pprint.pformat(self.to_dict())
|
|
90
|
+
|
|
91
|
+
def __repr__(self) -> str:
|
|
92
|
+
"""For `print` and `pprint`"""
|
|
93
|
+
return self.to_str()
|
|
94
|
+
|
|
95
|
+
def __eq__(self, other: 'V1ServerAlertPhase') -> bool:
|
|
96
|
+
"""Returns true if both objects are equal"""
|
|
97
|
+
if not isinstance(other, V1ServerAlertPhase):
|
|
98
|
+
return False
|
|
99
|
+
|
|
100
|
+
return self.__dict__ == other.__dict__
|
|
101
|
+
|
|
102
|
+
def __ne__(self, other: 'V1ServerAlertPhase') -> bool:
|
|
103
|
+
"""Returns true if both objects are not equal"""
|
|
104
|
+
return not self == other
|
|
@@ -79,6 +79,7 @@ class V1UserFeatures(object):
|
|
|
79
79
|
'lambda_labs': 'bool',
|
|
80
80
|
'landing_studios': 'bool',
|
|
81
81
|
'lit_logger': 'bool',
|
|
82
|
+
'manage_default_studio_machine': 'bool',
|
|
82
83
|
'marketplace': 'bool',
|
|
83
84
|
'mmt_fault_tolerance': 'bool',
|
|
84
85
|
'mmt_strategy_selector': 'bool',
|
|
@@ -107,6 +108,7 @@ class V1UserFeatures(object):
|
|
|
107
108
|
'runnable_public_studio_page': 'bool',
|
|
108
109
|
'security_docs': 'bool',
|
|
109
110
|
'show_dev_admin': 'bool',
|
|
111
|
+
'single_wallet': 'bool',
|
|
110
112
|
'slurm': 'bool',
|
|
111
113
|
'slurm_machine_selector': 'bool',
|
|
112
114
|
'stop_ide_container_on_shutdown': 'bool',
|
|
@@ -159,6 +161,7 @@ class V1UserFeatures(object):
|
|
|
159
161
|
'lambda_labs': 'lambdaLabs',
|
|
160
162
|
'landing_studios': 'landingStudios',
|
|
161
163
|
'lit_logger': 'litLogger',
|
|
164
|
+
'manage_default_studio_machine': 'manageDefaultStudioMachine',
|
|
162
165
|
'marketplace': 'marketplace',
|
|
163
166
|
'mmt_fault_tolerance': 'mmtFaultTolerance',
|
|
164
167
|
'mmt_strategy_selector': 'mmtStrategySelector',
|
|
@@ -187,6 +190,7 @@ class V1UserFeatures(object):
|
|
|
187
190
|
'runnable_public_studio_page': 'runnablePublicStudioPage',
|
|
188
191
|
'security_docs': 'securityDocs',
|
|
189
192
|
'show_dev_admin': 'showDevAdmin',
|
|
193
|
+
'single_wallet': 'singleWallet',
|
|
190
194
|
'slurm': 'slurm',
|
|
191
195
|
'slurm_machine_selector': 'slurmMachineSelector',
|
|
192
196
|
'stop_ide_container_on_shutdown': 'stopIdeContainerOnShutdown',
|
|
@@ -200,7 +204,7 @@ class V1UserFeatures(object):
|
|
|
200
204
|
'vultr': 'vultr'
|
|
201
205
|
}
|
|
202
206
|
|
|
203
|
-
def __init__(self, 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, byoc_litcr: '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, cloud_space_environment_templates: 'bool' =None, code_tab: 'bool' =None, collab_screen_sharing: 'bool' =None, cost_attribution_settings: 'bool' =None, custom_app_domain: 'bool' =None, custom_instance_types: 'bool' =None, datasets: 'bool' =None, default_one_cluster: 'bool' =None, deployment_alerts: 'bool' =None, deployment_persistent_disk: 'bool' =None, deployment_reservations: 'bool' =None, dgx_cloud: 'bool' =None, docs_agent: 'bool' =None, drive_v2: 'bool' =None, enable_crypto_crackdown: 'bool' =None, enable_storage_limits: 'bool' =None, enterprise_compute_admin: 'bool' =None, fair_share: 'bool' =None, featured_studios_admin: 'bool' =None, filestore: 'bool' =None, inactive_notify_delete: 'bool' =None, instant_capacity_reservation: 'bool' =None, job_artifacts_v2: 'bool' =None, lambda_labs: 'bool' =None, landing_studios: 'bool' =None, lit_logger: 'bool' =None, marketplace: 'bool' =None, mmt_fault_tolerance: 'bool' =None, mmt_strategy_selector: 'bool' =None, multicloud_saas: 'bool' =None, multiple_studio_versions: 'bool' =None, org_admin_alerts: 'bool' =None, org_level_member_permissions: 'bool' =None, pipelines: 'bool' =None, plugin_distributed: 'bool' =None, plugin_inference: 'bool' =None, plugin_label_studio: 'bool' =None, plugin_langflow: 'bool' =None, plugin_lightning_apps: 'bool' =None, plugin_lightning_apps_distributed: 'bool' =None, plugin_milvus: 'bool' =None, plugin_python_profiler: 'bool' =None, plugin_react: 'bool' =None, plugin_service: 'bool' =None, plugin_sweeps: 'bool' =None, plugin_weviate: 'bool' =None, pricing_updates: 'bool' =None, product_generator: 'bool' =None, project_selector: 'bool' =None, publish_pipelines: 'bool' =None, restartable_jobs: 'bool' =None, runnable_public_studio_page: 'bool' =None, security_docs: 'bool' =None, show_dev_admin: 'bool' =None, slurm: 'bool' =None, slurm_machine_selector: 'bool' =None, stop_ide_container_on_shutdown: 'bool' =None, studio_config: 'bool' =None, studio_on_stop: 'bool' =None, studio_version_visibility: 'bool' =None, studios_dashboard: 'bool' =None, teamspace_storage_tab: 'bool' =None, trainium2: 'bool' =None, use_rclone_mounts_only: 'bool' =None, vultr: 'bool' =None): # noqa: E501
|
|
207
|
+
def __init__(self, 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, byoc_litcr: '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, cloud_space_environment_templates: 'bool' =None, code_tab: 'bool' =None, collab_screen_sharing: 'bool' =None, cost_attribution_settings: 'bool' =None, custom_app_domain: 'bool' =None, custom_instance_types: 'bool' =None, datasets: 'bool' =None, default_one_cluster: 'bool' =None, deployment_alerts: 'bool' =None, deployment_persistent_disk: 'bool' =None, deployment_reservations: 'bool' =None, dgx_cloud: 'bool' =None, docs_agent: 'bool' =None, drive_v2: 'bool' =None, enable_crypto_crackdown: 'bool' =None, enable_storage_limits: 'bool' =None, enterprise_compute_admin: 'bool' =None, fair_share: 'bool' =None, featured_studios_admin: 'bool' =None, filestore: 'bool' =None, inactive_notify_delete: 'bool' =None, instant_capacity_reservation: 'bool' =None, job_artifacts_v2: 'bool' =None, lambda_labs: 'bool' =None, landing_studios: 'bool' =None, lit_logger: 'bool' =None, manage_default_studio_machine: 'bool' =None, marketplace: 'bool' =None, mmt_fault_tolerance: 'bool' =None, mmt_strategy_selector: 'bool' =None, multicloud_saas: 'bool' =None, multiple_studio_versions: 'bool' =None, org_admin_alerts: 'bool' =None, org_level_member_permissions: 'bool' =None, pipelines: 'bool' =None, plugin_distributed: 'bool' =None, plugin_inference: 'bool' =None, plugin_label_studio: 'bool' =None, plugin_langflow: 'bool' =None, plugin_lightning_apps: 'bool' =None, plugin_lightning_apps_distributed: 'bool' =None, plugin_milvus: 'bool' =None, plugin_python_profiler: 'bool' =None, plugin_react: 'bool' =None, plugin_service: 'bool' =None, plugin_sweeps: 'bool' =None, plugin_weviate: 'bool' =None, pricing_updates: 'bool' =None, product_generator: 'bool' =None, project_selector: 'bool' =None, publish_pipelines: '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, slurm_machine_selector: 'bool' =None, stop_ide_container_on_shutdown: 'bool' =None, studio_config: 'bool' =None, studio_on_stop: 'bool' =None, studio_version_visibility: 'bool' =None, studios_dashboard: 'bool' =None, teamspace_storage_tab: 'bool' =None, trainium2: 'bool' =None, use_rclone_mounts_only: 'bool' =None, vultr: 'bool' =None): # noqa: E501
|
|
204
208
|
"""V1UserFeatures - a model defined in Swagger""" # noqa: E501
|
|
205
209
|
self._affiliate_links = None
|
|
206
210
|
self._agents_v2 = None
|
|
@@ -240,6 +244,7 @@ class V1UserFeatures(object):
|
|
|
240
244
|
self._lambda_labs = None
|
|
241
245
|
self._landing_studios = None
|
|
242
246
|
self._lit_logger = None
|
|
247
|
+
self._manage_default_studio_machine = None
|
|
243
248
|
self._marketplace = None
|
|
244
249
|
self._mmt_fault_tolerance = None
|
|
245
250
|
self._mmt_strategy_selector = None
|
|
@@ -268,6 +273,7 @@ class V1UserFeatures(object):
|
|
|
268
273
|
self._runnable_public_studio_page = None
|
|
269
274
|
self._security_docs = None
|
|
270
275
|
self._show_dev_admin = None
|
|
276
|
+
self._single_wallet = None
|
|
271
277
|
self._slurm = None
|
|
272
278
|
self._slurm_machine_selector = None
|
|
273
279
|
self._stop_ide_container_on_shutdown = None
|
|
@@ -356,6 +362,8 @@ class V1UserFeatures(object):
|
|
|
356
362
|
self.landing_studios = landing_studios
|
|
357
363
|
if lit_logger is not None:
|
|
358
364
|
self.lit_logger = lit_logger
|
|
365
|
+
if manage_default_studio_machine is not None:
|
|
366
|
+
self.manage_default_studio_machine = manage_default_studio_machine
|
|
359
367
|
if marketplace is not None:
|
|
360
368
|
self.marketplace = marketplace
|
|
361
369
|
if mmt_fault_tolerance is not None:
|
|
@@ -412,6 +420,8 @@ class V1UserFeatures(object):
|
|
|
412
420
|
self.security_docs = security_docs
|
|
413
421
|
if show_dev_admin is not None:
|
|
414
422
|
self.show_dev_admin = show_dev_admin
|
|
423
|
+
if single_wallet is not None:
|
|
424
|
+
self.single_wallet = single_wallet
|
|
415
425
|
if slurm is not None:
|
|
416
426
|
self.slurm = slurm
|
|
417
427
|
if slurm_machine_selector is not None:
|
|
@@ -1233,6 +1243,27 @@ class V1UserFeatures(object):
|
|
|
1233
1243
|
|
|
1234
1244
|
self._lit_logger = lit_logger
|
|
1235
1245
|
|
|
1246
|
+
@property
|
|
1247
|
+
def manage_default_studio_machine(self) -> 'bool':
|
|
1248
|
+
"""Gets the manage_default_studio_machine of this V1UserFeatures. # noqa: E501
|
|
1249
|
+
|
|
1250
|
+
|
|
1251
|
+
:return: The manage_default_studio_machine of this V1UserFeatures. # noqa: E501
|
|
1252
|
+
:rtype: bool
|
|
1253
|
+
"""
|
|
1254
|
+
return self._manage_default_studio_machine
|
|
1255
|
+
|
|
1256
|
+
@manage_default_studio_machine.setter
|
|
1257
|
+
def manage_default_studio_machine(self, manage_default_studio_machine: 'bool'):
|
|
1258
|
+
"""Sets the manage_default_studio_machine of this V1UserFeatures.
|
|
1259
|
+
|
|
1260
|
+
|
|
1261
|
+
:param manage_default_studio_machine: The manage_default_studio_machine of this V1UserFeatures. # noqa: E501
|
|
1262
|
+
:type: bool
|
|
1263
|
+
"""
|
|
1264
|
+
|
|
1265
|
+
self._manage_default_studio_machine = manage_default_studio_machine
|
|
1266
|
+
|
|
1236
1267
|
@property
|
|
1237
1268
|
def marketplace(self) -> 'bool':
|
|
1238
1269
|
"""Gets the marketplace of this V1UserFeatures. # noqa: E501
|
|
@@ -1821,6 +1852,27 @@ class V1UserFeatures(object):
|
|
|
1821
1852
|
|
|
1822
1853
|
self._show_dev_admin = show_dev_admin
|
|
1823
1854
|
|
|
1855
|
+
@property
|
|
1856
|
+
def single_wallet(self) -> 'bool':
|
|
1857
|
+
"""Gets the single_wallet of this V1UserFeatures. # noqa: E501
|
|
1858
|
+
|
|
1859
|
+
|
|
1860
|
+
:return: The single_wallet of this V1UserFeatures. # noqa: E501
|
|
1861
|
+
:rtype: bool
|
|
1862
|
+
"""
|
|
1863
|
+
return self._single_wallet
|
|
1864
|
+
|
|
1865
|
+
@single_wallet.setter
|
|
1866
|
+
def single_wallet(self, single_wallet: 'bool'):
|
|
1867
|
+
"""Sets the single_wallet of this V1UserFeatures.
|
|
1868
|
+
|
|
1869
|
+
|
|
1870
|
+
:param single_wallet: The single_wallet of this V1UserFeatures. # noqa: E501
|
|
1871
|
+
:type: bool
|
|
1872
|
+
"""
|
|
1873
|
+
|
|
1874
|
+
self._single_wallet = single_wallet
|
|
1875
|
+
|
|
1824
1876
|
@property
|
|
1825
1877
|
def slurm(self) -> 'bool':
|
|
1826
1878
|
"""Gets the slurm of this V1UserFeatures. # noqa: E501
|
|
@@ -2,41 +2,39 @@ import functools
|
|
|
2
2
|
import logging
|
|
3
3
|
import time
|
|
4
4
|
from functools import wraps
|
|
5
|
-
from typing import
|
|
5
|
+
from typing import Callable, Optional, Any
|
|
6
6
|
|
|
7
7
|
import urllib3
|
|
8
|
-
|
|
9
8
|
from lightning_sdk.lightning_cloud import env
|
|
10
9
|
from lightning_sdk.lightning_cloud.login import Auth
|
|
11
10
|
from lightning_sdk.lightning_cloud.openapi import (
|
|
12
11
|
ApiClient,
|
|
13
|
-
AssistantsServiceApi,
|
|
14
12
|
AuthServiceApi,
|
|
15
|
-
BillingServiceApi,
|
|
16
|
-
CloudSpaceEnvironmentTemplateServiceApi,
|
|
17
13
|
CloudSpaceServiceApi,
|
|
18
14
|
ClusterServiceApi,
|
|
19
15
|
Configuration,
|
|
20
16
|
DataConnectionServiceApi,
|
|
21
|
-
DatasetServiceApi,
|
|
22
|
-
DeploymentTemplatesServiceApi,
|
|
23
|
-
EndpointServiceApi,
|
|
24
|
-
JobsServiceApi,
|
|
25
17
|
LightningappInstanceServiceApi,
|
|
26
18
|
LightningappV2ServiceApi,
|
|
27
19
|
LightningworkServiceApi,
|
|
28
|
-
LitLoggerServiceApi,
|
|
29
|
-
LitRegistryServiceApi,
|
|
30
|
-
ModelsStoreApi,
|
|
31
|
-
OrganizationsServiceApi,
|
|
32
|
-
PipelinesServiceApi,
|
|
33
20
|
ProjectsServiceApi,
|
|
34
|
-
SchedulesServiceApi,
|
|
35
21
|
SecretServiceApi,
|
|
36
|
-
SlurmJobsUserServiceApi,
|
|
37
22
|
SSHPublicKeyServiceApi,
|
|
38
|
-
|
|
23
|
+
DatasetServiceApi,
|
|
24
|
+
OrganizationsServiceApi,
|
|
39
25
|
UserServiceApi,
|
|
26
|
+
BillingServiceApi,
|
|
27
|
+
EndpointServiceApi,
|
|
28
|
+
SlurmJobsUserServiceApi,
|
|
29
|
+
LitLoggerServiceApi,
|
|
30
|
+
JobsServiceApi,
|
|
31
|
+
AssistantsServiceApi,
|
|
32
|
+
StorageServiceApi,
|
|
33
|
+
DeploymentTemplatesServiceApi,
|
|
34
|
+
ModelsStoreApi,
|
|
35
|
+
LitRegistryServiceApi,
|
|
36
|
+
PipelinesServiceApi,
|
|
37
|
+
SchedulesServiceApi,
|
|
40
38
|
)
|
|
41
39
|
from lightning_sdk.lightning_cloud.openapi.rest import ApiException
|
|
42
40
|
from lightning_sdk.lightning_cloud.source_code.logs_socket_api import LightningLogsSocketAPI
|
|
@@ -73,34 +71,34 @@ def create_swagger_client(check_context=True):
|
|
|
73
71
|
|
|
74
72
|
|
|
75
73
|
class GridRestClient(
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
CloudSpaceEnvironmentTemplateServiceApi,
|
|
74
|
+
LightningLogsSocketAPI,
|
|
75
|
+
LightningappInstanceServiceApi,
|
|
76
|
+
LightningappV2ServiceApi,
|
|
77
|
+
AuthServiceApi,
|
|
78
|
+
CloudSpaceServiceApi,
|
|
79
|
+
ClusterServiceApi,
|
|
80
|
+
ProjectsServiceApi,
|
|
81
|
+
LightningworkServiceApi,
|
|
82
|
+
SecretServiceApi,
|
|
83
|
+
SSHPublicKeyServiceApi,
|
|
84
|
+
DataConnectionServiceApi,
|
|
85
|
+
DatasetServiceApi,
|
|
86
|
+
OrganizationsServiceApi,
|
|
87
|
+
UserServiceApi,
|
|
88
|
+
BillingServiceApi,
|
|
89
|
+
EndpointServiceApi,
|
|
90
|
+
SlurmJobsUserServiceApi,
|
|
91
|
+
LitLoggerServiceApi,
|
|
92
|
+
JobsServiceApi,
|
|
93
|
+
AssistantsServiceApi,
|
|
94
|
+
StorageServiceApi,
|
|
95
|
+
DeploymentTemplatesServiceApi,
|
|
96
|
+
ModelsStoreApi,
|
|
97
|
+
LitRegistryServiceApi,
|
|
98
|
+
PipelinesServiceApi,
|
|
99
|
+
SchedulesServiceApi,
|
|
103
100
|
):
|
|
101
|
+
|
|
104
102
|
def __init__(self, api_client: Optional[ApiClient] = None):
|
|
105
103
|
api_client = api_client if api_client else create_swagger_client()
|
|
106
104
|
api_client.request = request_auth_warning_wrapper(api_client.request)
|
lightning_sdk/lit_container.py
CHANGED
|
@@ -64,7 +64,14 @@ class LitContainer:
|
|
|
64
64
|
return self._api.delete_container(project_id, container)
|
|
65
65
|
|
|
66
66
|
def upload_container(
|
|
67
|
-
self,
|
|
67
|
+
self,
|
|
68
|
+
container: str,
|
|
69
|
+
teamspace: str,
|
|
70
|
+
org: Optional[str] = None,
|
|
71
|
+
user: Optional[str] = None,
|
|
72
|
+
tag: str = "latest",
|
|
73
|
+
cloud_account: Optional[str] = None,
|
|
74
|
+
platform: Optional[str] = "linux/amd64",
|
|
68
75
|
) -> None:
|
|
69
76
|
"""Upload a container to the docker registry.
|
|
70
77
|
|
|
@@ -74,18 +81,26 @@ class LitContainer:
|
|
|
74
81
|
org: The organization which contains the container.
|
|
75
82
|
user: The user which contains the container.
|
|
76
83
|
tag: The tag to use for the container.
|
|
84
|
+
cloud_account: The cloud account where the container is stored.
|
|
85
|
+
platform: The platform the container is meant to run on.
|
|
77
86
|
"""
|
|
78
87
|
try:
|
|
79
88
|
teamspace = _resolve_teamspace(teamspace=teamspace, org=org, user=user)
|
|
80
89
|
except Exception as e:
|
|
81
90
|
raise ValueError(f"Could not resolve teamspace: {e}") from e
|
|
82
91
|
|
|
83
|
-
resp = self._api.upload_container(container, teamspace, tag)
|
|
92
|
+
resp = self._api.upload_container(container, teamspace, tag, cloud_account, platform=platform)
|
|
84
93
|
for line in resp:
|
|
85
94
|
print(line)
|
|
86
95
|
|
|
87
96
|
def download_container(
|
|
88
|
-
self,
|
|
97
|
+
self,
|
|
98
|
+
container: str,
|
|
99
|
+
teamspace: str,
|
|
100
|
+
org: Optional[str] = None,
|
|
101
|
+
user: Optional[str] = None,
|
|
102
|
+
tag: str = "latest",
|
|
103
|
+
cloud_account: Optional[str] = None,
|
|
89
104
|
) -> None:
|
|
90
105
|
"""Download a container from the docker registry.
|
|
91
106
|
|
|
@@ -101,4 +116,4 @@ class LitContainer:
|
|
|
101
116
|
except Exception as e:
|
|
102
117
|
raise ValueError(f"Could not resolve teamspace: {e}") from e
|
|
103
118
|
|
|
104
|
-
return self._api.download_container(container, teamspace, tag)
|
|
119
|
+
return self._api.download_container(container, teamspace, tag, cloud_account)
|
lightning_sdk/models.py
CHANGED
|
@@ -144,7 +144,7 @@ def download_model(
|
|
|
144
144
|
|
|
145
145
|
def upload_model(
|
|
146
146
|
name: str,
|
|
147
|
-
path: Union[Path, str] = ".",
|
|
147
|
+
path: Union[str, Path, List[Union[str, Path]]] = ".",
|
|
148
148
|
cloud_account: Optional[str] = None,
|
|
149
149
|
progress_bar: bool = True,
|
|
150
150
|
) -> UploadedModelInfo:
|
lightning_sdk/serve.py
CHANGED
|
@@ -2,18 +2,18 @@ import os
|
|
|
2
2
|
import shlex
|
|
3
3
|
import subprocess
|
|
4
4
|
from pathlib import Path
|
|
5
|
-
from typing import Generator, Optional
|
|
5
|
+
from typing import Generator, List, Optional, Union
|
|
6
6
|
from urllib.parse import urlencode
|
|
7
7
|
|
|
8
8
|
import docker
|
|
9
9
|
from rich.console import Console
|
|
10
|
-
from rich.progress import Progress
|
|
11
10
|
|
|
12
11
|
from lightning_sdk import Deployment, Machine, Teamspace
|
|
13
|
-
from lightning_sdk.api.deployment_api import AutoScaleConfig
|
|
12
|
+
from lightning_sdk.api.deployment_api import AutoScaleConfig, DeploymentApi, Env, Secret
|
|
14
13
|
from lightning_sdk.api.lit_container_api import LitContainerApi
|
|
15
|
-
from lightning_sdk.api.utils import _get_cloud_url
|
|
14
|
+
from lightning_sdk.api.utils import _get_cloud_url, _get_registry_url
|
|
16
15
|
from lightning_sdk.lightning_cloud import env
|
|
16
|
+
from lightning_sdk.lightning_cloud.env import LIGHTNING_CLOUD_URL
|
|
17
17
|
from lightning_sdk.lightning_cloud.login import Auth, AuthServer
|
|
18
18
|
|
|
19
19
|
_DOCKER_NOT_RUNNING_MSG = (
|
|
@@ -35,16 +35,18 @@ class _Auth(Auth):
|
|
|
35
35
|
_AuthServer().login_with_browser(self)
|
|
36
36
|
|
|
37
37
|
|
|
38
|
+
def authenticate() -> None:
|
|
39
|
+
auth = _Auth()
|
|
40
|
+
auth.authenticate()
|
|
41
|
+
|
|
42
|
+
|
|
38
43
|
class _LitServeDeployer:
|
|
39
|
-
def __init__(self) -> None:
|
|
44
|
+
def __init__(self, name: Optional[str], teamspace: Optional[Teamspace]) -> None:
|
|
45
|
+
self.name = name
|
|
46
|
+
self.teamspace = teamspace
|
|
40
47
|
self._console = Console()
|
|
41
48
|
self._client = None
|
|
42
49
|
|
|
43
|
-
@staticmethod
|
|
44
|
-
def authenticate() -> None:
|
|
45
|
-
auth = _Auth()
|
|
46
|
-
auth.authenticate()
|
|
47
|
-
|
|
48
50
|
@property
|
|
49
51
|
def client(self) -> docker.DockerClient:
|
|
50
52
|
if self._client is None:
|
|
@@ -56,6 +58,10 @@ class _LitServeDeployer:
|
|
|
56
58
|
raise RuntimeError(_DOCKER_NOT_RUNNING_MSG) from None
|
|
57
59
|
return self._client
|
|
58
60
|
|
|
61
|
+
@property
|
|
62
|
+
def created(self) -> bool:
|
|
63
|
+
return DeploymentApi().get_deployment_by_name(self.name, self.teamspace.id) is not None
|
|
64
|
+
|
|
59
65
|
def dockerize_api(
|
|
60
66
|
self,
|
|
61
67
|
server_filename: str,
|
|
@@ -176,45 +182,79 @@ Update [underline]{os.path.abspath("Dockerfile")}[/underline] to add any additio
|
|
|
176
182
|
|
|
177
183
|
return log_generator()
|
|
178
184
|
|
|
179
|
-
def build_container(self, path: str, repository: str, tag: str
|
|
180
|
-
build_task = progress.add_task("Building Docker image", total=None)
|
|
185
|
+
def build_container(self, path: str, repository: str, tag: str) -> Generator[str, None, None]:
|
|
181
186
|
build_logs = self._docker_build_with_logs(path, repository, tag=tag)
|
|
182
187
|
|
|
183
188
|
for line in build_logs:
|
|
184
189
|
if "error" in line:
|
|
185
|
-
progress.stop()
|
|
186
|
-
console.print(f"\n[red]{line}[/red]")
|
|
187
190
|
raise RuntimeError(f"Failed to build image: {line}")
|
|
188
191
|
else:
|
|
189
|
-
|
|
190
|
-
line.strip(),
|
|
191
|
-
)
|
|
192
|
-
progress.update(build_task, description="Building Docker image")
|
|
193
|
-
|
|
194
|
-
progress.update(build_task, description="[green]Build completed![/green]")
|
|
192
|
+
yield line.strip()
|
|
195
193
|
|
|
196
194
|
def push_container(
|
|
197
|
-
self,
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
195
|
+
self,
|
|
196
|
+
repository: str,
|
|
197
|
+
tag: str,
|
|
198
|
+
teamspace: Teamspace,
|
|
199
|
+
lit_cr: LitContainerApi,
|
|
200
|
+
cloud_account: str,
|
|
201
|
+
) -> Generator[dict, None, dict]:
|
|
202
202
|
lit_cr.authenticate()
|
|
203
|
-
push_status = lit_cr.upload_container(
|
|
204
|
-
|
|
203
|
+
push_status = lit_cr.upload_container(
|
|
204
|
+
repository, teamspace, tag=tag, cloud_account=cloud_account, platform=None
|
|
205
|
+
)
|
|
205
206
|
for line in push_status:
|
|
206
|
-
last_status = line
|
|
207
207
|
if "error" in line:
|
|
208
|
-
progress.stop()
|
|
209
|
-
console.print(f"\n[red]{line}[/red]")
|
|
210
208
|
raise RuntimeError(f"Failed to push image: {line}")
|
|
211
209
|
if "status" in line:
|
|
212
|
-
|
|
213
|
-
progress.update(push_task, description="Pushing to registry")
|
|
214
|
-
progress.update(push_task, description="[green]Push completed![/green]")
|
|
215
|
-
return last_status
|
|
210
|
+
yield {"status": line["status"].strip()}
|
|
216
211
|
|
|
217
|
-
|
|
212
|
+
registry_url = _get_registry_url()
|
|
213
|
+
container_basename = repository.split("/")[-1]
|
|
214
|
+
repository = (
|
|
215
|
+
f"{registry_url}/lit-container{f'-{cloud_account}' if cloud_account is not None else ''}/"
|
|
216
|
+
f"{teamspace.owner.name}/{teamspace.name}/{container_basename}"
|
|
217
|
+
)
|
|
218
|
+
yield {
|
|
219
|
+
"finish": True,
|
|
220
|
+
"status": "Container pushed successfully",
|
|
221
|
+
"url": f"{LIGHTNING_CLOUD_URL}/{teamspace.owner.name}/{teamspace.name}/containers/{container_basename}"
|
|
222
|
+
f"{f'?clusterId={cloud_account}' if cloud_account is not None else ''}",
|
|
223
|
+
"image": repository,
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
def _update_deployment(
|
|
227
|
+
self,
|
|
228
|
+
deployment: Deployment,
|
|
229
|
+
machine: Optional[Machine] = None,
|
|
230
|
+
image: Optional[str] = None,
|
|
231
|
+
entrypoint: Optional[str] = None,
|
|
232
|
+
command: Optional[str] = None,
|
|
233
|
+
env: Optional[List[Union[Env, Secret]]] = None,
|
|
234
|
+
min_replica: Optional[int] = 0,
|
|
235
|
+
max_replica: Optional[int] = 1,
|
|
236
|
+
spot: Optional[bool] = None,
|
|
237
|
+
replicas: Optional[int] = 1,
|
|
238
|
+
cloud_account: Optional[str] = None,
|
|
239
|
+
port: Optional[int] = 8000,
|
|
240
|
+
include_credentials: Optional[bool] = True,
|
|
241
|
+
) -> None:
|
|
242
|
+
return deployment.update(
|
|
243
|
+
machine=machine,
|
|
244
|
+
image=image,
|
|
245
|
+
entrypoint=entrypoint,
|
|
246
|
+
command=command,
|
|
247
|
+
env=env,
|
|
248
|
+
max_replicas=max_replica,
|
|
249
|
+
min_replicas=min_replica,
|
|
250
|
+
replicas=replicas,
|
|
251
|
+
spot=spot,
|
|
252
|
+
cloud_account=cloud_account,
|
|
253
|
+
ports=[port],
|
|
254
|
+
include_credentials=include_credentials,
|
|
255
|
+
)
|
|
256
|
+
|
|
257
|
+
def run_on_cloud(
|
|
218
258
|
self,
|
|
219
259
|
deployment_name: str,
|
|
220
260
|
teamspace: Teamspace,
|
|
@@ -229,18 +269,44 @@ Update [underline]{os.path.abspath("Dockerfile")}[/underline] to add any additio
|
|
|
229
269
|
port: Optional[int] = 8000,
|
|
230
270
|
include_credentials: Optional[bool] = True,
|
|
231
271
|
) -> dict:
|
|
272
|
+
"""Run a deployment on the cloud. If the deployment already exists, it will be updated.
|
|
273
|
+
|
|
274
|
+
Args:
|
|
275
|
+
deployment_name: The name of the deployment.
|
|
276
|
+
teamspace: The teamspace to run the deployment on.
|
|
277
|
+
image: The image to run the deployment on.
|
|
278
|
+
metric: The metric to use for autoscaling. Defaults to None.
|
|
279
|
+
machine: The machine to run the deployment on. Defaults to None.
|
|
280
|
+
min_replica: The minimum number of replicas to run. Defaults to 0.
|
|
281
|
+
max_replica: The maximum number of replicas to run. Defaults to 1.
|
|
282
|
+
spot: Whether to run the deployment on spot instances. Defaults to None.
|
|
283
|
+
replicas: The number of replicas to run. Defaults to 1.
|
|
284
|
+
cloud_account: The cloud account to run the deployment on. Defaults to None.
|
|
285
|
+
port: The port to run the deployment on. Defaults to 8000.
|
|
286
|
+
include_credentials: Whether to include credentials in the deployment. Defaults to True.
|
|
287
|
+
|
|
288
|
+
Returns:
|
|
289
|
+
dict: The deployment and the URL of the deployment.
|
|
290
|
+
"""
|
|
232
291
|
url = f"{_get_cloud_url()}/{teamspace.owner.name}/{teamspace.name}/jobs/{deployment_name}"
|
|
233
292
|
machine = machine or Machine.CPU
|
|
234
293
|
metric = metric or ("CPU" if machine.is_cpu() else "GPU")
|
|
235
294
|
deployment = Deployment(deployment_name, teamspace)
|
|
236
295
|
if deployment.is_started:
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
296
|
+
self._console.print(f"Deployment with name {deployment_name} already running. Updating the deployment.")
|
|
297
|
+
self._update_deployment(
|
|
298
|
+
deployment,
|
|
299
|
+
machine,
|
|
300
|
+
image,
|
|
301
|
+
min_replica=min_replica,
|
|
302
|
+
max_replica=max_replica,
|
|
303
|
+
spot=spot,
|
|
304
|
+
replicas=replicas,
|
|
305
|
+
cloud_account=cloud_account,
|
|
306
|
+
port=port,
|
|
307
|
+
include_credentials=include_credentials,
|
|
243
308
|
)
|
|
309
|
+
return {"deployment": deployment, "url": url, "updated": True}
|
|
244
310
|
autoscale = AutoScaleConfig(min_replicas=min_replica, max_replicas=max_replica, metric=metric, threshold=0.95)
|
|
245
311
|
deployment.start(
|
|
246
312
|
machine=machine,
|