lightning-sdk 2025.9.23__py3-none-any.whl → 2025.9.29__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/entrypoint.py +3 -1
- lightning_sdk/cli/groups.py +8 -1
- lightning_sdk/cli/legacy/entrypoint.py +1 -1
- lightning_sdk/cli/studio/create.py +19 -5
- lightning_sdk/cli/studio/delete.py +9 -5
- lightning_sdk/cli/studio/list.py +5 -1
- lightning_sdk/cli/studio/ssh.py +9 -3
- lightning_sdk/cli/studio/start.py +26 -3
- lightning_sdk/cli/studio/stop.py +7 -3
- lightning_sdk/cli/studio/switch.py +21 -5
- lightning_sdk/cli/utils/studio_selection.py +22 -15
- lightning_sdk/cli/vm/__init__.py +20 -0
- lightning_sdk/cli/vm/create.py +33 -0
- lightning_sdk/cli/vm/delete.py +25 -0
- lightning_sdk/cli/vm/list.py +30 -0
- lightning_sdk/cli/vm/ssh.py +31 -0
- lightning_sdk/cli/vm/start.py +60 -0
- lightning_sdk/cli/vm/stop.py +25 -0
- lightning_sdk/cli/vm/switch.py +38 -0
- lightning_sdk/lightning_cloud/openapi/__init__.py +20 -1
- lightning_sdk/lightning_cloud/openapi/api/assistants_service_api.py +2 -95
- lightning_sdk/lightning_cloud/openapi/api/billing_service_api.py +24 -8
- lightning_sdk/lightning_cloud/openapi/api/cluster_service_api.py +420 -0
- lightning_sdk/lightning_cloud/openapi/api/jobs_service_api.py +121 -0
- lightning_sdk/lightning_cloud/openapi/api/storage_service_api.py +655 -0
- lightning_sdk/lightning_cloud/openapi/models/__init__.py +20 -1
- lightning_sdk/lightning_cloud/openapi/models/create_machine_request_represents_the_request_to_create_a_machine.py +435 -0
- lightning_sdk/lightning_cloud/openapi/models/job_id_reportroutingtelemetry_body.py +123 -0
- lightning_sdk/lightning_cloud/openapi/models/project_id_storagetransfers_body.py +149 -0
- lightning_sdk/lightning_cloud/openapi/models/user_id_affiliatelinks_body.py +107 -3
- lightning_sdk/lightning_cloud/openapi/models/v1_abort_storage_transfer_response.py +97 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_assistant_session_daily_aggregated.py +27 -1
- lightning_sdk/lightning_cloud/openapi/models/v1_cloud_provider.py +2 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_cluster_accelerator.py +27 -1
- lightning_sdk/lightning_cloud/openapi/models/v1_cluster_spec.py +53 -1
- lightning_sdk/lightning_cloud/openapi/models/v1_cluster_type.py +1 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_create_machine_response.py +123 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_create_project_request.py +27 -1
- lightning_sdk/lightning_cloud/openapi/models/v1_delete_machine_response.py +97 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_external_cluster_spec.py +27 -1
- lightning_sdk/lightning_cloud/openapi/models/v1_get_machine_response.py +123 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_get_user_response.py +27 -1
- lightning_sdk/lightning_cloud/openapi/models/v1_kubernetes_direct_v1.py +27 -1
- lightning_sdk/lightning_cloud/openapi/models/v1_lightning_elastic_cluster_v1.py +97 -0
- lightning_sdk/lightning_cloud/openapi/models/{v1_get_model_total_usage_metrics_response.py → v1_list_machines_response.py} +37 -37
- lightning_sdk/lightning_cloud/openapi/models/v1_list_storage_transfers_response.py +123 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_machine.py +539 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_machine_direct_v1.py +123 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_pause_storage_transfer_response.py +97 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_purchase_annual_upsell_request.py +123 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_report_deployment_routing_telemetry_response.py +97 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_resume_storage_transfer_response.py +97 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_routing_telemetry.py +79 -1
- lightning_sdk/lightning_cloud/openapi/models/v1_rule_resource.py +1 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_slack_notifier.py +149 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_slack_notifier_type.py +105 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_storage_transfer.py +435 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_storage_transfer_status.py +108 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_update_user_request.py +27 -1
- lightning_sdk/lightning_cloud/openapi/models/v1_user_features.py +105 -79
- lightning_sdk/studio.py +55 -11
- lightning_sdk/teamspace.py +11 -2
- {lightning_sdk-2025.9.23.dist-info → lightning_sdk-2025.9.29.dist-info}/METADATA +1 -1
- {lightning_sdk-2025.9.23.dist-info → lightning_sdk-2025.9.29.dist-info}/RECORD +69 -42
- {lightning_sdk-2025.9.23.dist-info → lightning_sdk-2025.9.29.dist-info}/LICENSE +0 -0
- {lightning_sdk-2025.9.23.dist-info → lightning_sdk-2025.9.29.dist-info}/WHEEL +0 -0
- {lightning_sdk-2025.9.23.dist-info → lightning_sdk-2025.9.29.dist-info}/entry_points.txt +0 -0
- {lightning_sdk-2025.9.23.dist-info → lightning_sdk-2025.9.29.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,108 @@
|
|
|
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 V1StorageTransferStatus(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
|
+
QUEUED = "STATUS_QUEUED"
|
|
41
|
+
IN_PROGRESS = "STATUS_IN_PROGRESS"
|
|
42
|
+
FAILED = "STATUS_FAILED"
|
|
43
|
+
ABORTED = "STATUS_ABORTED"
|
|
44
|
+
PAUSED = "STATUS_PAUSED"
|
|
45
|
+
COMPLETED = "STATUS_COMPLETED"
|
|
46
|
+
UNSPECIFIED = "STATUS_UNSPECIFIED"
|
|
47
|
+
"""
|
|
48
|
+
Attributes:
|
|
49
|
+
swagger_types (dict): The key is attribute name
|
|
50
|
+
and the value is attribute type.
|
|
51
|
+
attribute_map (dict): The key is attribute name
|
|
52
|
+
and the value is json key in definition.
|
|
53
|
+
"""
|
|
54
|
+
swagger_types = {
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
attribute_map = {
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
def __init__(self): # noqa: E501
|
|
61
|
+
"""V1StorageTransferStatus - a model defined in Swagger""" # noqa: E501
|
|
62
|
+
self.discriminator = None
|
|
63
|
+
|
|
64
|
+
def to_dict(self) -> dict:
|
|
65
|
+
"""Returns the model properties as a dict"""
|
|
66
|
+
result = {}
|
|
67
|
+
|
|
68
|
+
for attr, _ in six.iteritems(self.swagger_types):
|
|
69
|
+
value = getattr(self, attr)
|
|
70
|
+
if isinstance(value, list):
|
|
71
|
+
result[attr] = list(map(
|
|
72
|
+
lambda x: x.to_dict() if hasattr(x, "to_dict") else x,
|
|
73
|
+
value
|
|
74
|
+
))
|
|
75
|
+
elif hasattr(value, "to_dict"):
|
|
76
|
+
result[attr] = value.to_dict()
|
|
77
|
+
elif isinstance(value, dict):
|
|
78
|
+
result[attr] = dict(map(
|
|
79
|
+
lambda item: (item[0], item[1].to_dict())
|
|
80
|
+
if hasattr(item[1], "to_dict") else item,
|
|
81
|
+
value.items()
|
|
82
|
+
))
|
|
83
|
+
else:
|
|
84
|
+
result[attr] = value
|
|
85
|
+
if issubclass(V1StorageTransferStatus, dict):
|
|
86
|
+
for key, value in self.items():
|
|
87
|
+
result[key] = value
|
|
88
|
+
|
|
89
|
+
return result
|
|
90
|
+
|
|
91
|
+
def to_str(self) -> str:
|
|
92
|
+
"""Returns the string representation of the model"""
|
|
93
|
+
return pprint.pformat(self.to_dict())
|
|
94
|
+
|
|
95
|
+
def __repr__(self) -> str:
|
|
96
|
+
"""For `print` and `pprint`"""
|
|
97
|
+
return self.to_str()
|
|
98
|
+
|
|
99
|
+
def __eq__(self, other: 'V1StorageTransferStatus') -> bool:
|
|
100
|
+
"""Returns true if both objects are equal"""
|
|
101
|
+
if not isinstance(other, V1StorageTransferStatus):
|
|
102
|
+
return False
|
|
103
|
+
|
|
104
|
+
return self.__dict__ == other.__dict__
|
|
105
|
+
|
|
106
|
+
def __ne__(self, other: 'V1StorageTransferStatus') -> bool:
|
|
107
|
+
"""Returns true if both objects are not equal"""
|
|
108
|
+
return not self == other
|
|
@@ -53,6 +53,7 @@ class V1UpdateUserRequest(object):
|
|
|
53
53
|
'first_name': 'str',
|
|
54
54
|
'general_audience_mode': 'bool',
|
|
55
55
|
'last_name': 'str',
|
|
56
|
+
'linux_username': 'str',
|
|
56
57
|
'non_developer_mode': 'bool',
|
|
57
58
|
'opted_in_marketing_emails': 'bool',
|
|
58
59
|
'organization': 'str',
|
|
@@ -82,6 +83,7 @@ class V1UpdateUserRequest(object):
|
|
|
82
83
|
'first_name': 'firstName',
|
|
83
84
|
'general_audience_mode': 'generalAudienceMode',
|
|
84
85
|
'last_name': 'lastName',
|
|
86
|
+
'linux_username': 'linuxUsername',
|
|
85
87
|
'non_developer_mode': 'nonDeveloperMode',
|
|
86
88
|
'opted_in_marketing_emails': 'optedInMarketingEmails',
|
|
87
89
|
'organization': 'organization',
|
|
@@ -98,7 +100,7 @@ class V1UpdateUserRequest(object):
|
|
|
98
100
|
'website': 'website'
|
|
99
101
|
}
|
|
100
102
|
|
|
101
|
-
def __init__(self, agree_to_terms_and_conditions: 'bool' =None, allow_credits_auto_replenish: 'bool' =None, auto_replenish_amount: 'float' =None, auto_replenish_threshold: 'float' =None, complete_sign_up: 'bool' =None, completed_project_onboarding: 'bool' =None, country: 'str' =None, email: 'str' =None, experimentation_id: 'str' =None, first_name: 'str' =None, general_audience_mode: 'bool' =None, last_name: 'str' =None, non_developer_mode: 'bool' =None, opted_in_marketing_emails: 'bool' =None, organization: 'str' =None, preferred_color_scheme: 'str' =None, preferred_ide: 'str' =None, preferred_shell: 'str' =None, preferred_vscode_marketplace: 'str' =None, role: 'str' =None, saw_create_first_project_dialog: 'bool' =None, saw_forums_login_merge_dialog: 'bool' =None, saw_free_credits_notification: 'bool' =None, user_metadata: 'str' =None, username: 'str' =None, website: 'str' =None): # noqa: E501
|
|
103
|
+
def __init__(self, agree_to_terms_and_conditions: 'bool' =None, allow_credits_auto_replenish: 'bool' =None, auto_replenish_amount: 'float' =None, auto_replenish_threshold: 'float' =None, complete_sign_up: 'bool' =None, completed_project_onboarding: 'bool' =None, country: 'str' =None, email: 'str' =None, experimentation_id: 'str' =None, first_name: 'str' =None, general_audience_mode: 'bool' =None, last_name: 'str' =None, linux_username: 'str' =None, non_developer_mode: 'bool' =None, opted_in_marketing_emails: 'bool' =None, organization: 'str' =None, preferred_color_scheme: 'str' =None, preferred_ide: 'str' =None, preferred_shell: 'str' =None, preferred_vscode_marketplace: 'str' =None, role: 'str' =None, saw_create_first_project_dialog: 'bool' =None, saw_forums_login_merge_dialog: 'bool' =None, saw_free_credits_notification: 'bool' =None, user_metadata: 'str' =None, username: 'str' =None, website: 'str' =None): # noqa: E501
|
|
102
104
|
"""V1UpdateUserRequest - a model defined in Swagger""" # noqa: E501
|
|
103
105
|
self._agree_to_terms_and_conditions = None
|
|
104
106
|
self._allow_credits_auto_replenish = None
|
|
@@ -112,6 +114,7 @@ class V1UpdateUserRequest(object):
|
|
|
112
114
|
self._first_name = None
|
|
113
115
|
self._general_audience_mode = None
|
|
114
116
|
self._last_name = None
|
|
117
|
+
self._linux_username = None
|
|
115
118
|
self._non_developer_mode = None
|
|
116
119
|
self._opted_in_marketing_emails = None
|
|
117
120
|
self._organization = None
|
|
@@ -151,6 +154,8 @@ class V1UpdateUserRequest(object):
|
|
|
151
154
|
self.general_audience_mode = general_audience_mode
|
|
152
155
|
if last_name is not None:
|
|
153
156
|
self.last_name = last_name
|
|
157
|
+
if linux_username is not None:
|
|
158
|
+
self.linux_username = linux_username
|
|
154
159
|
if non_developer_mode is not None:
|
|
155
160
|
self.non_developer_mode = non_developer_mode
|
|
156
161
|
if opted_in_marketing_emails is not None:
|
|
@@ -432,6 +437,27 @@ class V1UpdateUserRequest(object):
|
|
|
432
437
|
|
|
433
438
|
self._last_name = last_name
|
|
434
439
|
|
|
440
|
+
@property
|
|
441
|
+
def linux_username(self) -> 'str':
|
|
442
|
+
"""Gets the linux_username of this V1UpdateUserRequest. # noqa: E501
|
|
443
|
+
|
|
444
|
+
|
|
445
|
+
:return: The linux_username of this V1UpdateUserRequest. # noqa: E501
|
|
446
|
+
:rtype: str
|
|
447
|
+
"""
|
|
448
|
+
return self._linux_username
|
|
449
|
+
|
|
450
|
+
@linux_username.setter
|
|
451
|
+
def linux_username(self, linux_username: 'str'):
|
|
452
|
+
"""Sets the linux_username of this V1UpdateUserRequest.
|
|
453
|
+
|
|
454
|
+
|
|
455
|
+
:param linux_username: The linux_username of this V1UpdateUserRequest. # noqa: E501
|
|
456
|
+
:type: str
|
|
457
|
+
"""
|
|
458
|
+
|
|
459
|
+
self._linux_username = linux_username
|
|
460
|
+
|
|
435
461
|
@property
|
|
436
462
|
def non_developer_mode(self) -> 'bool':
|
|
437
463
|
"""Gets the non_developer_mode of this V1UpdateUserRequest. # noqa: E501
|
|
@@ -67,7 +67,6 @@ class V1UserFeatures(object):
|
|
|
67
67
|
'f227': 'bool',
|
|
68
68
|
'f234': 'bool',
|
|
69
69
|
'f236': 'bool',
|
|
70
|
-
'f237': 'bool',
|
|
71
70
|
'f239': 'bool',
|
|
72
71
|
'f240': 'bool',
|
|
73
72
|
'f241': 'bool',
|
|
@@ -75,14 +74,16 @@ class V1UserFeatures(object):
|
|
|
75
74
|
'f245': 'bool',
|
|
76
75
|
'f247': 'bool',
|
|
77
76
|
'f248': 'bool',
|
|
78
|
-
'f249': 'bool',
|
|
79
77
|
'f250': 'bool',
|
|
80
78
|
'f251': 'bool',
|
|
81
79
|
'f252': 'bool',
|
|
82
80
|
'f253': 'bool',
|
|
81
|
+
'f254': 'bool',
|
|
82
|
+
'f255': 'bool',
|
|
83
|
+
'f257': 'bool',
|
|
84
|
+
'f258': 'bool',
|
|
83
85
|
'fair_share': 'bool',
|
|
84
86
|
'featured_studios_admin': 'bool',
|
|
85
|
-
'gcp_overprovisioning': 'bool',
|
|
86
87
|
'gcs_connections_optimized': 'bool',
|
|
87
88
|
'instant_capacity_reservation': 'bool',
|
|
88
89
|
'job_artifacts_v2': 'bool',
|
|
@@ -155,7 +156,6 @@ class V1UserFeatures(object):
|
|
|
155
156
|
'f227': 'f227',
|
|
156
157
|
'f234': 'f234',
|
|
157
158
|
'f236': 'f236',
|
|
158
|
-
'f237': 'f237',
|
|
159
159
|
'f239': 'f239',
|
|
160
160
|
'f240': 'f240',
|
|
161
161
|
'f241': 'f241',
|
|
@@ -163,14 +163,16 @@ class V1UserFeatures(object):
|
|
|
163
163
|
'f245': 'f245',
|
|
164
164
|
'f247': 'f247',
|
|
165
165
|
'f248': 'f248',
|
|
166
|
-
'f249': 'f249',
|
|
167
166
|
'f250': 'f250',
|
|
168
167
|
'f251': 'f251',
|
|
169
168
|
'f252': 'f252',
|
|
170
169
|
'f253': 'f253',
|
|
170
|
+
'f254': 'f254',
|
|
171
|
+
'f255': 'f255',
|
|
172
|
+
'f257': 'f257',
|
|
173
|
+
'f258': 'f258',
|
|
171
174
|
'fair_share': 'fairShare',
|
|
172
175
|
'featured_studios_admin': 'featuredStudiosAdmin',
|
|
173
|
-
'gcp_overprovisioning': 'gcpOverprovisioning',
|
|
174
176
|
'gcs_connections_optimized': 'gcsConnectionsOptimized',
|
|
175
177
|
'instant_capacity_reservation': 'instantCapacityReservation',
|
|
176
178
|
'job_artifacts_v2': 'jobArtifactsV2',
|
|
@@ -216,7 +218,7 @@ class V1UserFeatures(object):
|
|
|
216
218
|
'writable_s3_connections': 'writableS3Connections'
|
|
217
219
|
}
|
|
218
220
|
|
|
219
|
-
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, byo_machine_type: '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, code_tab: 'bool' =None, collab_screen_sharing: 'bool' =None, control_center_monitoring: 'bool' =None, cost_attribution_settings: 'bool' =None, custom_app_domain: 'bool' =None, datasets: 'bool' =None, default_one_cluster: 'bool' =None, deployment_persistent_disk: 'bool' =None, drive_v2: 'bool' =None, enterprise_compute_admin: 'bool' =None, f227: 'bool' =None, f234: 'bool' =None, f236: 'bool' =None,
|
|
221
|
+
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, byo_machine_type: '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, code_tab: 'bool' =None, collab_screen_sharing: 'bool' =None, control_center_monitoring: 'bool' =None, cost_attribution_settings: 'bool' =None, custom_app_domain: 'bool' =None, datasets: 'bool' =None, default_one_cluster: 'bool' =None, deployment_persistent_disk: 'bool' =None, drive_v2: 'bool' =None, enterprise_compute_admin: 'bool' =None, f227: 'bool' =None, f234: 'bool' =None, f236: 'bool' =None, f239: 'bool' =None, f240: 'bool' =None, f241: 'bool' =None, f243: 'bool' =None, f245: 'bool' =None, f247: 'bool' =None, f248: 'bool' =None, f250: 'bool' =None, f251: 'bool' =None, f252: 'bool' =None, f253: 'bool' =None, f254: 'bool' =None, f255: 'bool' =None, f257: 'bool' =None, f258: 'bool' =None, fair_share: 'bool' =None, featured_studios_admin: 'bool' =None, gcs_connections_optimized: 'bool' =None, instant_capacity_reservation: 'bool' =None, job_artifacts_v2: 'bool' =None, kubernetes_cluster_ui: 'bool' =None, kubernetes_clusters: 'bool' =None, landing_studios: 'bool' =None, lit_logger: 'bool' =None, marketplace: 'bool' =None, mmt_fault_tolerance: 'bool' =None, mmt_strategy_selector: 'bool' =None, model_api_dashboard: 'bool' =None, multiple_studio_versions: 'bool' =None, nerf_fs_nonpaying: 'bool' =None, org_level_member_permissions: 'bool' =None, org_usage_limits: '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_sweeps: 'bool' =None, pricing_updates: 'bool' =None, product_generator: 'bool' =None, product_license: 'bool' =None, project_selector: 'bool' =None, publish_pipelines: '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, vultr: 'bool' =None, weka: 'bool' =None, writable_s3_connections: 'bool' =None): # noqa: E501
|
|
220
222
|
"""V1UserFeatures - a model defined in Swagger""" # noqa: E501
|
|
221
223
|
self._affiliate_links = None
|
|
222
224
|
self._agents_v2 = None
|
|
@@ -244,7 +246,6 @@ class V1UserFeatures(object):
|
|
|
244
246
|
self._f227 = None
|
|
245
247
|
self._f234 = None
|
|
246
248
|
self._f236 = None
|
|
247
|
-
self._f237 = None
|
|
248
249
|
self._f239 = None
|
|
249
250
|
self._f240 = None
|
|
250
251
|
self._f241 = None
|
|
@@ -252,14 +253,16 @@ class V1UserFeatures(object):
|
|
|
252
253
|
self._f245 = None
|
|
253
254
|
self._f247 = None
|
|
254
255
|
self._f248 = None
|
|
255
|
-
self._f249 = None
|
|
256
256
|
self._f250 = None
|
|
257
257
|
self._f251 = None
|
|
258
258
|
self._f252 = None
|
|
259
259
|
self._f253 = None
|
|
260
|
+
self._f254 = None
|
|
261
|
+
self._f255 = None
|
|
262
|
+
self._f257 = None
|
|
263
|
+
self._f258 = None
|
|
260
264
|
self._fair_share = None
|
|
261
265
|
self._featured_studios_admin = None
|
|
262
|
-
self._gcp_overprovisioning = None
|
|
263
266
|
self._gcs_connections_optimized = None
|
|
264
267
|
self._instant_capacity_reservation = None
|
|
265
268
|
self._job_artifacts_v2 = None
|
|
@@ -356,8 +359,6 @@ class V1UserFeatures(object):
|
|
|
356
359
|
self.f234 = f234
|
|
357
360
|
if f236 is not None:
|
|
358
361
|
self.f236 = f236
|
|
359
|
-
if f237 is not None:
|
|
360
|
-
self.f237 = f237
|
|
361
362
|
if f239 is not None:
|
|
362
363
|
self.f239 = f239
|
|
363
364
|
if f240 is not None:
|
|
@@ -372,8 +373,6 @@ class V1UserFeatures(object):
|
|
|
372
373
|
self.f247 = f247
|
|
373
374
|
if f248 is not None:
|
|
374
375
|
self.f248 = f248
|
|
375
|
-
if f249 is not None:
|
|
376
|
-
self.f249 = f249
|
|
377
376
|
if f250 is not None:
|
|
378
377
|
self.f250 = f250
|
|
379
378
|
if f251 is not None:
|
|
@@ -382,12 +381,18 @@ class V1UserFeatures(object):
|
|
|
382
381
|
self.f252 = f252
|
|
383
382
|
if f253 is not None:
|
|
384
383
|
self.f253 = f253
|
|
384
|
+
if f254 is not None:
|
|
385
|
+
self.f254 = f254
|
|
386
|
+
if f255 is not None:
|
|
387
|
+
self.f255 = f255
|
|
388
|
+
if f257 is not None:
|
|
389
|
+
self.f257 = f257
|
|
390
|
+
if f258 is not None:
|
|
391
|
+
self.f258 = f258
|
|
385
392
|
if fair_share is not None:
|
|
386
393
|
self.fair_share = fair_share
|
|
387
394
|
if featured_studios_admin is not None:
|
|
388
395
|
self.featured_studios_admin = featured_studios_admin
|
|
389
|
-
if gcp_overprovisioning is not None:
|
|
390
|
-
self.gcp_overprovisioning = gcp_overprovisioning
|
|
391
396
|
if gcs_connections_optimized is not None:
|
|
392
397
|
self.gcs_connections_optimized = gcs_connections_optimized
|
|
393
398
|
if instant_capacity_reservation is not None:
|
|
@@ -1021,27 +1026,6 @@ class V1UserFeatures(object):
|
|
|
1021
1026
|
|
|
1022
1027
|
self._f236 = f236
|
|
1023
1028
|
|
|
1024
|
-
@property
|
|
1025
|
-
def f237(self) -> 'bool':
|
|
1026
|
-
"""Gets the f237 of this V1UserFeatures. # noqa: E501
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
:return: The f237 of this V1UserFeatures. # noqa: E501
|
|
1030
|
-
:rtype: bool
|
|
1031
|
-
"""
|
|
1032
|
-
return self._f237
|
|
1033
|
-
|
|
1034
|
-
@f237.setter
|
|
1035
|
-
def f237(self, f237: 'bool'):
|
|
1036
|
-
"""Sets the f237 of this V1UserFeatures.
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
:param f237: The f237 of this V1UserFeatures. # noqa: E501
|
|
1040
|
-
:type: bool
|
|
1041
|
-
"""
|
|
1042
|
-
|
|
1043
|
-
self._f237 = f237
|
|
1044
|
-
|
|
1045
1029
|
@property
|
|
1046
1030
|
def f239(self) -> 'bool':
|
|
1047
1031
|
"""Gets the f239 of this V1UserFeatures. # noqa: E501
|
|
@@ -1189,27 +1173,6 @@ class V1UserFeatures(object):
|
|
|
1189
1173
|
|
|
1190
1174
|
self._f248 = f248
|
|
1191
1175
|
|
|
1192
|
-
@property
|
|
1193
|
-
def f249(self) -> 'bool':
|
|
1194
|
-
"""Gets the f249 of this V1UserFeatures. # noqa: E501
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
:return: The f249 of this V1UserFeatures. # noqa: E501
|
|
1198
|
-
:rtype: bool
|
|
1199
|
-
"""
|
|
1200
|
-
return self._f249
|
|
1201
|
-
|
|
1202
|
-
@f249.setter
|
|
1203
|
-
def f249(self, f249: 'bool'):
|
|
1204
|
-
"""Sets the f249 of this V1UserFeatures.
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
:param f249: The f249 of this V1UserFeatures. # noqa: E501
|
|
1208
|
-
:type: bool
|
|
1209
|
-
"""
|
|
1210
|
-
|
|
1211
|
-
self._f249 = f249
|
|
1212
|
-
|
|
1213
1176
|
@property
|
|
1214
1177
|
def f250(self) -> 'bool':
|
|
1215
1178
|
"""Gets the f250 of this V1UserFeatures. # noqa: E501
|
|
@@ -1294,6 +1257,90 @@ class V1UserFeatures(object):
|
|
|
1294
1257
|
|
|
1295
1258
|
self._f253 = f253
|
|
1296
1259
|
|
|
1260
|
+
@property
|
|
1261
|
+
def f254(self) -> 'bool':
|
|
1262
|
+
"""Gets the f254 of this V1UserFeatures. # noqa: E501
|
|
1263
|
+
|
|
1264
|
+
|
|
1265
|
+
:return: The f254 of this V1UserFeatures. # noqa: E501
|
|
1266
|
+
:rtype: bool
|
|
1267
|
+
"""
|
|
1268
|
+
return self._f254
|
|
1269
|
+
|
|
1270
|
+
@f254.setter
|
|
1271
|
+
def f254(self, f254: 'bool'):
|
|
1272
|
+
"""Sets the f254 of this V1UserFeatures.
|
|
1273
|
+
|
|
1274
|
+
|
|
1275
|
+
:param f254: The f254 of this V1UserFeatures. # noqa: E501
|
|
1276
|
+
:type: bool
|
|
1277
|
+
"""
|
|
1278
|
+
|
|
1279
|
+
self._f254 = f254
|
|
1280
|
+
|
|
1281
|
+
@property
|
|
1282
|
+
def f255(self) -> 'bool':
|
|
1283
|
+
"""Gets the f255 of this V1UserFeatures. # noqa: E501
|
|
1284
|
+
|
|
1285
|
+
|
|
1286
|
+
:return: The f255 of this V1UserFeatures. # noqa: E501
|
|
1287
|
+
:rtype: bool
|
|
1288
|
+
"""
|
|
1289
|
+
return self._f255
|
|
1290
|
+
|
|
1291
|
+
@f255.setter
|
|
1292
|
+
def f255(self, f255: 'bool'):
|
|
1293
|
+
"""Sets the f255 of this V1UserFeatures.
|
|
1294
|
+
|
|
1295
|
+
|
|
1296
|
+
:param f255: The f255 of this V1UserFeatures. # noqa: E501
|
|
1297
|
+
:type: bool
|
|
1298
|
+
"""
|
|
1299
|
+
|
|
1300
|
+
self._f255 = f255
|
|
1301
|
+
|
|
1302
|
+
@property
|
|
1303
|
+
def f257(self) -> 'bool':
|
|
1304
|
+
"""Gets the f257 of this V1UserFeatures. # noqa: E501
|
|
1305
|
+
|
|
1306
|
+
|
|
1307
|
+
:return: The f257 of this V1UserFeatures. # noqa: E501
|
|
1308
|
+
:rtype: bool
|
|
1309
|
+
"""
|
|
1310
|
+
return self._f257
|
|
1311
|
+
|
|
1312
|
+
@f257.setter
|
|
1313
|
+
def f257(self, f257: 'bool'):
|
|
1314
|
+
"""Sets the f257 of this V1UserFeatures.
|
|
1315
|
+
|
|
1316
|
+
|
|
1317
|
+
:param f257: The f257 of this V1UserFeatures. # noqa: E501
|
|
1318
|
+
:type: bool
|
|
1319
|
+
"""
|
|
1320
|
+
|
|
1321
|
+
self._f257 = f257
|
|
1322
|
+
|
|
1323
|
+
@property
|
|
1324
|
+
def f258(self) -> 'bool':
|
|
1325
|
+
"""Gets the f258 of this V1UserFeatures. # noqa: E501
|
|
1326
|
+
|
|
1327
|
+
|
|
1328
|
+
:return: The f258 of this V1UserFeatures. # noqa: E501
|
|
1329
|
+
:rtype: bool
|
|
1330
|
+
"""
|
|
1331
|
+
return self._f258
|
|
1332
|
+
|
|
1333
|
+
@f258.setter
|
|
1334
|
+
def f258(self, f258: 'bool'):
|
|
1335
|
+
"""Sets the f258 of this V1UserFeatures.
|
|
1336
|
+
|
|
1337
|
+
|
|
1338
|
+
:param f258: The f258 of this V1UserFeatures. # noqa: E501
|
|
1339
|
+
:type: bool
|
|
1340
|
+
"""
|
|
1341
|
+
|
|
1342
|
+
self._f258 = f258
|
|
1343
|
+
|
|
1297
1344
|
@property
|
|
1298
1345
|
def fair_share(self) -> 'bool':
|
|
1299
1346
|
"""Gets the fair_share of this V1UserFeatures. # noqa: E501
|
|
@@ -1336,27 +1383,6 @@ class V1UserFeatures(object):
|
|
|
1336
1383
|
|
|
1337
1384
|
self._featured_studios_admin = featured_studios_admin
|
|
1338
1385
|
|
|
1339
|
-
@property
|
|
1340
|
-
def gcp_overprovisioning(self) -> 'bool':
|
|
1341
|
-
"""Gets the gcp_overprovisioning of this V1UserFeatures. # noqa: E501
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
:return: The gcp_overprovisioning of this V1UserFeatures. # noqa: E501
|
|
1345
|
-
:rtype: bool
|
|
1346
|
-
"""
|
|
1347
|
-
return self._gcp_overprovisioning
|
|
1348
|
-
|
|
1349
|
-
@gcp_overprovisioning.setter
|
|
1350
|
-
def gcp_overprovisioning(self, gcp_overprovisioning: 'bool'):
|
|
1351
|
-
"""Sets the gcp_overprovisioning of this V1UserFeatures.
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
:param gcp_overprovisioning: The gcp_overprovisioning of this V1UserFeatures. # noqa: E501
|
|
1355
|
-
:type: bool
|
|
1356
|
-
"""
|
|
1357
|
-
|
|
1358
|
-
self._gcp_overprovisioning = gcp_overprovisioning
|
|
1359
|
-
|
|
1360
1386
|
@property
|
|
1361
1387
|
def gcs_connections_optimized(self) -> 'bool':
|
|
1362
1388
|
"""Gets the gcs_connections_optimized of this V1UserFeatures. # noqa: E501
|
lightning_sdk/studio.py
CHANGED
|
@@ -102,6 +102,8 @@ class Studio:
|
|
|
102
102
|
cloud_account = _resolve_deprecated_cluster(cloud_account, cluster)
|
|
103
103
|
cloud_provider = _resolve_deprecated_provider(cloud_provider, provider)
|
|
104
104
|
|
|
105
|
+
cls_name = self._cls_name
|
|
106
|
+
|
|
105
107
|
# if we're skipping init, we don't need to resolve the cloud account as then we're not creating a studio
|
|
106
108
|
if self._teamspace is not None:
|
|
107
109
|
_cloud_account = self._cloud_account_api.resolve_cloud_account(
|
|
@@ -126,7 +128,7 @@ class Studio:
|
|
|
126
128
|
name = config.get_value(DefaultConfigKeys.studio)
|
|
127
129
|
if name is None and not create_ok:
|
|
128
130
|
raise ValueError(
|
|
129
|
-
"Cannot autodetect
|
|
131
|
+
f"Cannot autodetect {cls_name}. Either use the SDK from within a {cls_name} or pass a name!"
|
|
130
132
|
)
|
|
131
133
|
|
|
132
134
|
if self._studio is None and not getattr(self._skip_init, "value", False):
|
|
@@ -136,7 +138,7 @@ class Studio:
|
|
|
136
138
|
# if we don't have a name, raise an error to get
|
|
137
139
|
# to the exception path and optionally create a studio
|
|
138
140
|
raise ValueError(
|
|
139
|
-
"Cannot autodetect
|
|
141
|
+
f"Cannot autodetect {cls_name}. Either use the SDK from within a {cls_name} or pass a name!"
|
|
140
142
|
)
|
|
141
143
|
self._studio = self._studio_api.get_studio(name, self._teamspace.id)
|
|
142
144
|
except ValueError as e:
|
|
@@ -227,7 +229,9 @@ class Studio:
|
|
|
227
229
|
@property
|
|
228
230
|
def cluster(self) -> str:
|
|
229
231
|
"""Returns the cluster the Studio is running on."""
|
|
230
|
-
warnings.warn(
|
|
232
|
+
warnings.warn(
|
|
233
|
+
f"{self._cls_name}.cluster is deprecated. Use {self._cls_name}.cloud_account instead", DeprecationWarning
|
|
234
|
+
)
|
|
231
235
|
return self.cloud_account
|
|
232
236
|
|
|
233
237
|
@property
|
|
@@ -266,14 +270,17 @@ class Studio:
|
|
|
266
270
|
new_machine = Machine.from_str(machine)
|
|
267
271
|
if new_machine != self.machine:
|
|
268
272
|
raise RuntimeError(
|
|
269
|
-
f"Requested to start
|
|
273
|
+
f"Requested to start {self._cls_name} on {new_machine}, "
|
|
274
|
+
"but {self._cls_name} is already running on {self.machine}."
|
|
270
275
|
" Consider switching instead!"
|
|
271
276
|
)
|
|
272
|
-
_logger.info(f"
|
|
277
|
+
_logger.info(f"{self._cls_name} {self.name} is already running")
|
|
273
278
|
return
|
|
274
279
|
|
|
275
280
|
if status != Status.Stopped:
|
|
276
|
-
raise RuntimeError(
|
|
281
|
+
raise RuntimeError(
|
|
282
|
+
f"Cannot start a {self._cls_name} that is not stopped. {self._cls_name} {self.name} is {status}."
|
|
283
|
+
)
|
|
277
284
|
|
|
278
285
|
# Show progress bar during startup
|
|
279
286
|
if self.show_progress:
|
|
@@ -362,7 +369,8 @@ class Studio:
|
|
|
362
369
|
status = self.status
|
|
363
370
|
if status != Status.Running:
|
|
364
371
|
raise RuntimeError(
|
|
365
|
-
f"Cannot switch machine on a
|
|
372
|
+
f"Cannot switch machine on a {self._cls_name} that is not running. "
|
|
373
|
+
"{self._cls_name} {self.name} is {status}."
|
|
366
374
|
)
|
|
367
375
|
|
|
368
376
|
current_cloud = self._cloud_account_api.get_cloud_account_non_org(
|
|
@@ -420,7 +428,10 @@ class Studio:
|
|
|
420
428
|
print(f"Running {commands=}")
|
|
421
429
|
status = self.status
|
|
422
430
|
if status != Status.Running:
|
|
423
|
-
raise RuntimeError(
|
|
431
|
+
raise RuntimeError(
|
|
432
|
+
f"Cannot run a command in a {self._cls_name} that is not running. "
|
|
433
|
+
"{self._cls_name} {self.name} is {status}."
|
|
434
|
+
)
|
|
424
435
|
|
|
425
436
|
iter_output = self._studio_api.run_studio_commands_and_yield(
|
|
426
437
|
self._studio.id, self._teamspace.id, *commands, timeout=timeout, check_interval=check_interval
|
|
@@ -446,7 +457,10 @@ class Studio:
|
|
|
446
457
|
|
|
447
458
|
status = self.status
|
|
448
459
|
if status != Status.Running:
|
|
449
|
-
raise RuntimeError(
|
|
460
|
+
raise RuntimeError(
|
|
461
|
+
f"Cannot run a command in a {self._cls_name} that is not running. "
|
|
462
|
+
"{self._cls_name} {self.name} is {status}."
|
|
463
|
+
)
|
|
450
464
|
output, exit_code = self._studio_api.run_studio_commands(self._studio.id, self._teamspace.id, *commands)
|
|
451
465
|
output = output.strip()
|
|
452
466
|
|
|
@@ -616,7 +630,7 @@ class Studio:
|
|
|
616
630
|
@auto_sleep.setter
|
|
617
631
|
def auto_sleep(self, value: bool) -> None:
|
|
618
632
|
if not value and self.machine == Machine.CPU:
|
|
619
|
-
warnings.warn("Disabling auto-sleep will convert the
|
|
633
|
+
warnings.warn(f"Disabling auto-sleep will convert the {self._cls_name} from free to paid!")
|
|
620
634
|
self._studio_api.update_autoshutdown(self._studio.id, self._teamspace.id, enabled=value)
|
|
621
635
|
self._update_studio_reference()
|
|
622
636
|
|
|
@@ -627,7 +641,7 @@ class Studio:
|
|
|
627
641
|
|
|
628
642
|
@auto_sleep_time.setter
|
|
629
643
|
def auto_sleep_time(self, value: int) -> None:
|
|
630
|
-
warnings.warn("Setting auto-sleep time will convert the
|
|
644
|
+
warnings.warn(f"Setting auto-sleep time will convert the {self._cls_name} from free to paid!")
|
|
631
645
|
self._studio_api.update_autoshutdown(self._studio.id, self._teamspace.id, idle_shutdown_seconds=value)
|
|
632
646
|
self._update_studio_reference()
|
|
633
647
|
|
|
@@ -758,6 +772,36 @@ class Studio:
|
|
|
758
772
|
def _update_studio_reference(self) -> None:
|
|
759
773
|
self._studio = self._studio_api.get_studio_by_id(studio_id=self._studio.id, teamspace_id=self._teamspace.id)
|
|
760
774
|
|
|
775
|
+
@property
|
|
776
|
+
def _cls_name(self) -> str:
|
|
777
|
+
return self.__class__.__qualname__
|
|
778
|
+
|
|
779
|
+
|
|
780
|
+
class VM(Studio):
|
|
781
|
+
"""A single Lightning AI VM.
|
|
782
|
+
|
|
783
|
+
Allows to fully control a vm, including retrieving the status, running commands
|
|
784
|
+
and switching machine types.
|
|
785
|
+
|
|
786
|
+
Args:
|
|
787
|
+
name: the name of the vm
|
|
788
|
+
teamspace: the name of the teamspace the vm is contained by
|
|
789
|
+
org: the name of the organization owning the :param`teamspace` in case it is owned by an org
|
|
790
|
+
user: the name of the user owning the :param`teamspace` in case it is owned directly by a user instead of an org
|
|
791
|
+
cloud_account: the name of the cloud account, the vm should be created on.
|
|
792
|
+
Doesn't matter when the vm already exists.
|
|
793
|
+
cloud_account_provider: The provider to select the cloud-account from.
|
|
794
|
+
If set, must be in agreement with the provider from the cloud_account (if specified).
|
|
795
|
+
If not specified, falls backto the teamspace default cloud account.
|
|
796
|
+
create_ok: whether the vm will be created if it does not yet exist. Defaults to True
|
|
797
|
+
provider: the provider of the machine, the vm should be created on.
|
|
798
|
+
|
|
799
|
+
Note:
|
|
800
|
+
Since a teamspace can either be owned by an org or by a user directly,
|
|
801
|
+
only one of the arguments can be provided.
|
|
802
|
+
|
|
803
|
+
"""
|
|
804
|
+
|
|
761
805
|
|
|
762
806
|
def _internal_status_to_external_status(internal_status: str) -> Status:
|
|
763
807
|
"""Converts internal status strings from HTTP requests to external enums."""
|
lightning_sdk/teamspace.py
CHANGED
|
@@ -28,7 +28,7 @@ from lightning_sdk.utils.resolve import (
|
|
|
28
28
|
if TYPE_CHECKING:
|
|
29
29
|
from lightning_sdk.job import Job
|
|
30
30
|
from lightning_sdk.mmt import MMT
|
|
31
|
-
from lightning_sdk.studio import Studio
|
|
31
|
+
from lightning_sdk.studio import VM, Studio
|
|
32
32
|
|
|
33
33
|
|
|
34
34
|
class FolderLocation(Enum):
|
|
@@ -144,13 +144,22 @@ class Teamspace:
|
|
|
144
144
|
"""All studios within that teamspace."""
|
|
145
145
|
from lightning_sdk.studio import Studio
|
|
146
146
|
|
|
147
|
+
return self._get_studios(Studio)
|
|
148
|
+
|
|
149
|
+
@property
|
|
150
|
+
def vms(self) -> List["VM"]:
|
|
151
|
+
from lightning_sdk.studio import VM
|
|
152
|
+
|
|
153
|
+
return [x for x in self._get_studios(VM) if isinstance(x, VM)]
|
|
154
|
+
|
|
155
|
+
def _get_studios(self, target_cls: type) -> List[Union["Studio", "VM"]]:
|
|
147
156
|
studios = []
|
|
148
157
|
cloud_accounts = self._teamspace_api.list_cloud_accounts(teamspace_id=self.id)
|
|
149
158
|
for cl in cloud_accounts:
|
|
150
159
|
_studios = self._teamspace_api.list_studios(teamspace_id=self.id, cloud_account=cl.cluster_id)
|
|
151
160
|
for s in _studios:
|
|
152
161
|
with skip_studio_init():
|
|
153
|
-
studio =
|
|
162
|
+
studio = target_cls(name=s.name, teamspace=self, cluster=cl.cluster_name, create_ok=False)
|
|
154
163
|
studio._studio = s
|
|
155
164
|
studio._teamspace = self
|
|
156
165
|
studios.append(studio)
|