lightning-sdk 0.2.7__py3-none-any.whl → 0.2.9__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.
Files changed (32) hide show
  1. lightning_sdk/__init__.py +1 -1
  2. lightning_sdk/api/cluster_api.py +22 -0
  3. lightning_sdk/api/lit_container_api.py +7 -12
  4. lightning_sdk/api/teamspace_api.py +2 -1
  5. lightning_sdk/cli/clusters_menu.py +46 -0
  6. lightning_sdk/cli/list.py +25 -5
  7. lightning_sdk/cli/serve.py +133 -27
  8. lightning_sdk/lightning_cloud/openapi/__init__.py +5 -0
  9. lightning_sdk/lightning_cloud/openapi/api/cloud_space_service_api.py +206 -0
  10. lightning_sdk/lightning_cloud/openapi/models/__init__.py +5 -0
  11. lightning_sdk/lightning_cloud/openapi/models/cloudspace_id_systemmetrics_body.py +149 -0
  12. lightning_sdk/lightning_cloud/openapi/models/v1_billing_tier.py +1 -0
  13. lightning_sdk/lightning_cloud/openapi/models/v1_cloud_space_cold_start_metrics.py +53 -1
  14. lightning_sdk/lightning_cloud/openapi/models/v1_cluster_security_options.py +27 -1
  15. lightning_sdk/lightning_cloud/openapi/models/v1_data_connection.py +27 -1
  16. lightning_sdk/lightning_cloud/openapi/models/v1_get_cloud_space_instance_system_metrics_aggregate_response.py +123 -0
  17. lightning_sdk/lightning_cloud/openapi/models/v1_google_cloud_direct_v1.py +27 -1
  18. lightning_sdk/lightning_cloud/openapi/models/v1_report_cloud_space_instance_system_metrics_response.py +97 -0
  19. lightning_sdk/lightning_cloud/openapi/models/v1_server_alert_phase.py +1 -0
  20. lightning_sdk/lightning_cloud/openapi/models/v1_system_metrics_aggregated.py +227 -0
  21. lightning_sdk/lightning_cloud/openapi/models/v1_user_features.py +55 -185
  22. lightning_sdk/lightning_cloud/openapi/models/v1_weka_data_connection.py +227 -0
  23. lightning_sdk/lit_container.py +13 -5
  24. lightning_sdk/models.py +7 -2
  25. lightning_sdk/serve.py +23 -46
  26. lightning_sdk/teamspace.py +19 -4
  27. {lightning_sdk-0.2.7.dist-info → lightning_sdk-0.2.9.dist-info}/METADATA +1 -1
  28. {lightning_sdk-0.2.7.dist-info → lightning_sdk-0.2.9.dist-info}/RECORD +32 -25
  29. {lightning_sdk-0.2.7.dist-info → lightning_sdk-0.2.9.dist-info}/LICENSE +0 -0
  30. {lightning_sdk-0.2.7.dist-info → lightning_sdk-0.2.9.dist-info}/WHEEL +0 -0
  31. {lightning_sdk-0.2.7.dist-info → lightning_sdk-0.2.9.dist-info}/entry_points.txt +0 -0
  32. {lightning_sdk-0.2.7.dist-info → lightning_sdk-0.2.9.dist-info}/top_level.txt +0 -0
lightning_sdk/__init__.py CHANGED
@@ -31,6 +31,6 @@ __all__ = [
31
31
  "User",
32
32
  ]
33
33
 
34
- __version__ = "0.2.7"
34
+ __version__ = "0.2.9"
35
35
  _check_version_and_prompt_upgrade(__version__)
36
36
  _set_tqdm_envvars_noninteractive()
@@ -0,0 +1,22 @@
1
+ from lightning_sdk.lightning_cloud.openapi import Externalv1Cluster
2
+ from lightning_sdk.lightning_cloud.rest_client import LightningClient
3
+
4
+
5
+ class ClusterApi:
6
+ """Internal API client for API requests to cluster endpoints."""
7
+
8
+ def __init__(self) -> None:
9
+ self._client = LightningClient(max_tries=7)
10
+
11
+ def get_cluster(self, cluster_id: str, project_id: str, org_id: str) -> Externalv1Cluster:
12
+ """Gets the cluster from given params cluster_id, project_id and owner.
13
+
14
+ :param cluster_id: cluster ID test
15
+ :param project_id: the project the cluster is supposed to be associated with
16
+ :param org_id: The owning org of this cluster
17
+ :return:
18
+ """
19
+ res = self._client.cluster_service_get_cluster(id=cluster_id, org_id=org_id, project_id=project_id)
20
+ if not res:
21
+ raise ValueError(f"Cluster {cluster_id} does not exist")
22
+ return res
@@ -7,7 +7,6 @@ import requests
7
7
  from rich.console import Console
8
8
 
9
9
  from lightning_sdk.api.utils import _get_registry_url
10
- from lightning_sdk.lightning_cloud.env import LIGHTNING_CLOUD_URL
11
10
  from lightning_sdk.lightning_cloud.openapi.models import V1DeleteLitRepositoryResponse
12
11
  from lightning_sdk.lightning_cloud.rest_client import LightningClient
13
12
  from lightning_sdk.teamspace import Teamspace
@@ -103,11 +102,14 @@ class LitContainerApi:
103
102
  """Lists containers of the project ID.
104
103
 
105
104
  :param project_id: The non-human readable project ID used internally to identify projects.
105
+ :param cloud_account: The cluster ID of the cloud account. If None, will use the default cluster.
106
106
  :return:
107
107
  """
108
- project = self._client.lit_registry_service_get_lit_project_registry(
109
- project_id, cluster_id=cloud_account
110
- ) # cloud account on the CLI is cluster_id
108
+ if cloud_account is None:
109
+ project = self._client.lit_registry_service_get_lit_project_registry(project_id)
110
+ else:
111
+ project = self._client.lit_registry_service_get_lit_project_registry(project_id, cluster_id=cloud_account)
112
+
111
113
  return project.repositories
112
114
 
113
115
  def delete_container(self, project_id: str, container: str) -> V1DeleteLitRepositoryResponse:
@@ -138,7 +140,7 @@ class LitContainerApi:
138
140
  Named cloud-account in the CLI options.
139
141
  :param platform: If empty will be linux/amd64. This is important because our entire deployment infra runs on
140
142
  linux/amd64. Will show user a warning otherwise.
141
- :return: Generator[dict, None, None]
143
+ :return: Generator[dict, None, dict]
142
144
  """
143
145
  try:
144
146
  self._docker_client.images.get(f"{container}:{tag}")
@@ -164,13 +166,6 @@ class LitContainerApi:
164
166
  raise ValueError(f"Could not tag container {container}:{tag} with {repository}:{tag}")
165
167
  yield from self._push_with_retry(repository, tag=tag)
166
168
 
167
- yield {
168
- "finish": True,
169
- "url": f"{LIGHTNING_CLOUD_URL}/{teamspace.owner.name}/{teamspace.name}/containers/{container_basename}"
170
- f"{f'?clusterId={cloud_account}' if cloud_account is not None else ''}",
171
- "repository": repository,
172
- }
173
-
174
169
  def _push_with_retry(self, repository: str, tag: str, max_retries: int = 3) -> Iterator[Dict[str, Any]]:
175
170
  def is_auth_error(error_msg: str) -> bool:
176
171
  auth_errors = ["unauthorized", "authentication required", "unauth"]
@@ -177,6 +177,7 @@ class TeamspaceApi:
177
177
  def create_model(
178
178
  self,
179
179
  name: str,
180
+ version: Optional[str],
180
181
  metadata: Dict[str, str],
181
182
  private: bool,
182
183
  teamspace_id: str,
@@ -191,7 +192,7 @@ class TeamspaceApi:
191
192
  )
192
193
  assert len(models) == 1, "Multiple models with the same name found"
193
194
  return self.models.models_store_create_model_version(
194
- body=ModelIdVersionsBody(cluster_id=cloud_account),
195
+ body=ModelIdVersionsBody(cluster_id=cloud_account, version=version),
195
196
  project_id=teamspace_id,
196
197
  model_id=models[0].id,
197
198
  )
@@ -0,0 +1,46 @@
1
+ import sys
2
+ from typing import List
3
+
4
+ from rich.console import Console
5
+ from simple_term_menu import TerminalMenu
6
+
7
+ from lightning_sdk import Teamspace
8
+ from lightning_sdk.api.cluster_api import ClusterApi
9
+ from lightning_sdk.lightning_cloud.openapi import Externalv1Cluster, V1ProjectClusterBinding
10
+
11
+
12
+ class _ClustersMenu:
13
+ def _get_cluster_from_interactive_menu(self, possible_clusters: List[V1ProjectClusterBinding]) -> str:
14
+ terminal_menu = self._prepare_terminal_menu_teamspaces([cluster.cluster_id for cluster in possible_clusters])
15
+ terminal_menu.show()
16
+
17
+ return possible_clusters[terminal_menu.chosen_menu_index].cluster_id
18
+
19
+ @staticmethod
20
+ def _prepare_terminal_menu_teamspaces(cluster_ids: List[str]) -> TerminalMenu:
21
+ title = "Please select a cluster from the following:"
22
+
23
+ return TerminalMenu(cluster_ids, title=title, clear_menu_on_exit=True)
24
+
25
+ def _resolve_cluster(self, teamspace: Teamspace) -> Externalv1Cluster:
26
+ selected_cluster_id = None
27
+ console = Console()
28
+ try:
29
+ selected_cluster_id = self._get_cluster_from_interactive_menu(
30
+ possible_clusters=teamspace.cloud_account_objs
31
+ )
32
+ cluster_api = ClusterApi()
33
+
34
+ return cluster_api.get_cluster(
35
+ cluster_id=selected_cluster_id, org_id=teamspace.owner.id, project_id=teamspace.id
36
+ )
37
+ except KeyboardInterrupt:
38
+ console.print("Operation cancelled by user")
39
+ sys.exit(0)
40
+
41
+ except Exception:
42
+ console.print(
43
+ f"[red]Could not find the given Cluster:[/red] {selected_cluster_id}. "
44
+ "Please contact Lightning AI directly to resolve this issue."
45
+ )
46
+ sys.exit(1)
lightning_sdk/cli/list.py CHANGED
@@ -7,8 +7,9 @@ from rich.table import Table
7
7
  from typing_extensions import Literal
8
8
 
9
9
  from lightning_sdk import Job, Machine, Studio, Teamspace
10
+ from lightning_sdk.cli.clusters_menu import _ClustersMenu
10
11
  from lightning_sdk.cli.teamspace_menu import _TeamspacesMenu
11
- from lightning_sdk.lightning_cloud.openapi import V1MultiMachineJob
12
+ from lightning_sdk.lightning_cloud.openapi import V1ClusterType, V1MultiMachineJob
12
13
  from lightning_sdk.lit_container import LitContainer
13
14
  from lightning_sdk.utils.resolve import _get_authed_user
14
15
 
@@ -232,18 +233,37 @@ def mmts(
232
233
  "If not provided, can be selected in an interactive menu."
233
234
  ),
234
235
  )
235
- def containers(teamspace: Optional[str] = None) -> None:
236
+ @click.option(
237
+ "--cloud-account",
238
+ "--cloud_account", # The UI will present the above variant, using this as a secondary to be consistent w/ models
239
+ default=None,
240
+ help="The name of the cloud account where containers are stored in.",
241
+ )
242
+ def containers(teamspace: Optional[str] = None, cloud_account: Optional[str] = None) -> None:
236
243
  """Display the list of available containers."""
237
244
  api = LitContainer()
238
245
  menu = _TeamspacesMenu()
246
+ clusters_menu = _ClustersMenu()
239
247
  resolved_teamspace = menu._resolve_teamspace(teamspace=teamspace)
240
- result = api.list_containers(teamspace=resolved_teamspace.name, org=resolved_teamspace.owner.name)
248
+
249
+ if not cloud_account:
250
+ cloud_account_obj = clusters_menu._resolve_cluster(resolved_teamspace)
251
+ cloud_account = "" if cloud_account_obj.spec.cluster_type == V1ClusterType.GLOBAL else cloud_account_obj.id
252
+
253
+ result = api.list_containers(
254
+ teamspace=resolved_teamspace.name, org=resolved_teamspace.owner.name, cloud_account=cloud_account
255
+ )
256
+
257
+ if not result:
258
+ return
259
+
241
260
  table = Table(pad_edge=True, box=None)
242
261
  table.add_column("REPOSITORY")
243
- table.add_column("IMAGE ID")
262
+ table.add_column("CLOUD ACCOUNT")
263
+ table.add_column("LATEST TAG")
244
264
  table.add_column("CREATED")
245
265
  for repo in result:
246
- table.add_row(repo["REPOSITORY"], repo["IMAGE ID"], repo["CREATED"])
266
+ table.add_row(repo["REPOSITORY"], repo["CLOUD ACCOUNT"], repo["LATEST TAG"], repo["CREATED"])
247
267
  Console().print(table)
248
268
 
249
269
 
@@ -1,8 +1,11 @@
1
1
  import os
2
2
  import subprocess
3
+ import time
4
+ import webbrowser
3
5
  from datetime import datetime
4
6
  from pathlib import Path
5
7
  from typing import Optional, Union
8
+ from urllib.parse import urlencode
6
9
 
7
10
  import click
8
11
  from rich.console import Console
@@ -10,24 +13,37 @@ from rich.progress import Progress, SpinnerColumn, TextColumn, TimeElapsedColumn
10
13
  from rich.prompt import Confirm
11
14
 
12
15
  from lightning_sdk import Machine, Teamspace
16
+ from lightning_sdk.api import UserApi
13
17
  from lightning_sdk.api.lit_container_api import LitContainerApi
14
18
  from lightning_sdk.cli.teamspace_menu import _TeamspacesMenu
15
- from lightning_sdk.serve import _LitServeDeployer, authenticate
19
+ from lightning_sdk.lightning_cloud import env
20
+ from lightning_sdk.lightning_cloud.login import Auth, AuthServer
21
+ from lightning_sdk.serve import _LitServeDeployer
22
+ from lightning_sdk.utils.resolve import _get_authed_user, _resolve_teamspace
16
23
 
17
24
  _MACHINE_VALUES = tuple([machine.name for machine in Machine.__dict__.values() if isinstance(machine, Machine)])
18
25
 
19
26
 
20
- @click.group("serve")
27
+ class _ServeGroup(click.Group):
28
+ def parse_args(self, ctx: click.Context, args: list) -> click.Group:
29
+ # Check if first arg is a file path and not a command name
30
+ if args and os.path.exists(args[0]) and args[0] not in self.commands:
31
+ # Insert the 'api' command before the file path
32
+ args.insert(0, "api")
33
+ return super().parse_args(ctx, args)
34
+
35
+
36
+ @click.group("serve", cls=_ServeGroup)
21
37
  def serve() -> None:
22
38
  """Serve a LitServe model.
23
39
 
24
40
  Example:
25
- lightning serve api server.py # serve locally
41
+ lightning serve server.py # deploy to the cloud
26
42
 
27
43
  Example:
28
- lightning serve api server.py --cloud --name litserve-api # deploy to the cloud
44
+ lightning serve server.py --local # serve locally
29
45
 
30
- You can deploy the API to the cloud by running `lightning serve api server.py --cloud`.
46
+ You can deploy the API to the cloud by running `lightning serve server.py`.
31
47
  This will build a docker container for the server.py script and deploy it to the Lightning AI platform.
32
48
  """
33
49
 
@@ -42,11 +58,11 @@ def serve() -> None:
42
58
  help="Generate a client for the model",
43
59
  )
44
60
  @click.option(
45
- "--cloud",
61
+ "--local",
46
62
  is_flag=True,
47
63
  default=False,
48
64
  flag_value=True,
49
- help="Deploy the model to the Lightning AI platform",
65
+ help="Run the model locally",
50
66
  )
51
67
  @click.option("--name", default=None, help="Name of the deployed API (e.g., 'classification-api', 'Llama-api')")
52
68
  @click.option(
@@ -107,7 +123,7 @@ def serve() -> None:
107
123
  def api(
108
124
  script_path: str,
109
125
  easy: bool,
110
- cloud: bool,
126
+ local: bool,
111
127
  name: Optional[str],
112
128
  non_interactive: bool,
113
129
  machine: str,
@@ -126,7 +142,7 @@ def api(
126
142
  return api_impl(
127
143
  script_path=script_path,
128
144
  easy=easy,
129
- cloud=cloud,
145
+ local=local,
130
146
  repository=name,
131
147
  non_interactive=non_interactive,
132
148
  machine=machine,
@@ -146,7 +162,7 @@ def api(
146
162
  def api_impl(
147
163
  script_path: Union[str, Path],
148
164
  easy: bool = False,
149
- cloud: bool = False,
165
+ local: bool = False,
150
166
  repository: [str] = None,
151
167
  tag: Optional[str] = None,
152
168
  non_interactive: bool = False,
@@ -176,7 +192,7 @@ def api_impl(
176
192
  timestr = datetime.now().strftime("%b-%d-%H_%M")
177
193
  repository = f"litserve-{timestr}".lower()
178
194
 
179
- if cloud:
195
+ if not local:
180
196
  repository = repository or "litserve-model"
181
197
  machine = Machine.from_str(machine)
182
198
  return _handle_cloud(
@@ -209,6 +225,69 @@ def api_impl(
209
225
  raise RuntimeError(error_msg) from None
210
226
 
211
227
 
228
+ class _AuthServer(AuthServer):
229
+ def get_auth_url(self, port: int) -> str:
230
+ redirect_uri = f"http://localhost:{port}/login-complete"
231
+ params = urlencode({"redirectTo": redirect_uri, "inviteCode": "litserve"})
232
+ return f"{env.LIGHTNING_CLOUD_URL}/sign-in?{params}"
233
+
234
+
235
+ class _Auth(Auth):
236
+ def __init__(self, shall_confirm: bool = False) -> None:
237
+ super().__init__()
238
+ self._shall_confirm = shall_confirm
239
+
240
+ def _run_server(self) -> None:
241
+ if self._shall_confirm:
242
+ proceed = Confirm.ask(
243
+ "Authenticating with Lightning AI. This will open a browser window. Continue?", default=True
244
+ )
245
+ if not proceed:
246
+ raise RuntimeError(
247
+ "Login cancelled. Please login to Lightning AI to deploy the API."
248
+ " Run `lightning login` to login."
249
+ ) from None
250
+ print("Opening browser for authentication...")
251
+ print("Please come back to the terminal after logging in.")
252
+ time.sleep(3)
253
+ _AuthServer().login_with_browser(self)
254
+
255
+
256
+ def authenticate(shall_confirm: bool = True) -> None:
257
+ auth = _Auth(shall_confirm)
258
+ auth.authenticate()
259
+
260
+
261
+ def select_teamspace(teamspace: Optional[str], org: Optional[str], user: Optional[str]) -> Teamspace:
262
+ if teamspace is None:
263
+ user = _get_authed_user()
264
+ menu = _TeamspacesMenu()
265
+ possible_teamspaces = menu._get_possible_teamspaces(user)
266
+ if len(possible_teamspaces) == 1:
267
+ name = next(iter(possible_teamspaces.values()))["name"]
268
+ return Teamspace(name=name, org=org, user=user)
269
+
270
+ return menu._resolve_teamspace(teamspace)
271
+
272
+ return _resolve_teamspace(teamspace=teamspace, org=org, user=user)
273
+
274
+
275
+ def poll_verified_status() -> bool:
276
+ """Polls the verified status of the user until it is True or a timeout occurs."""
277
+ user_api = UserApi()
278
+ user = _get_authed_user()
279
+ start_time = datetime.now()
280
+ timeout = 600 # 10 minutes
281
+ while True:
282
+ user_resp = user_api.get_user(name=user.name)
283
+ if user_resp.status.verified:
284
+ return True
285
+ if (datetime.now() - start_time).total_seconds() > timeout:
286
+ break
287
+ time.sleep(5)
288
+ return False
289
+
290
+
212
291
  def _handle_cloud(
213
292
  script_path: Union[str, Path],
214
293
  console: Console,
@@ -233,16 +312,8 @@ def _handle_cloud(
233
312
  if non_interactive:
234
313
  console.print("[italic]non-interactive[/italic] mode enabled, skipping confirmation prompts", style="blue")
235
314
 
236
- # Authenticate with LitServe affiliate
237
- authenticate()
238
- if teamspace is None:
239
- menu = _TeamspacesMenu()
240
- resolved_teamspace = menu._resolve_teamspace(teamspace)
241
- else:
242
- resolved_teamspace = Teamspace(name=teamspace, org=org, user=user)
243
-
244
315
  port = port or 8000
245
- ls_deployer = _LitServeDeployer(name=deployment_name, teamspace=resolved_teamspace)
316
+ ls_deployer = _LitServeDeployer(name=deployment_name, teamspace=None)
246
317
  path = ls_deployer.dockerize_api(script_path, port=port, gpu=not machine.is_cpu(), tag=tag, print_success=False)
247
318
 
248
319
  console.print(f"\nPlease review the Dockerfile at [u]{path}[/u] and make sure it is correct.", style="bold")
@@ -251,6 +322,36 @@ def _handle_cloud(
251
322
  console.print("Please fix the Dockerfile and try again.", style="red")
252
323
  return
253
324
 
325
+ with Progress(
326
+ SpinnerColumn(),
327
+ TextColumn("[progress.description]{task.description}"),
328
+ TimeElapsedColumn(),
329
+ console=console,
330
+ transient=True,
331
+ ) as progress:
332
+ try:
333
+ # Build the container
334
+ build_task = progress.add_task("Building Docker image", total=None)
335
+ for line in ls_deployer.build_container(path, repository, tag):
336
+ console.print(line.strip())
337
+ progress.update(build_task, advance=1)
338
+ progress.update(build_task, description="[green]Build completed![/green]", completed=1.0)
339
+ progress.remove_task(build_task)
340
+
341
+ except Exception as e:
342
+ console.print(f"❌ Deployment failed: {e}", style="red")
343
+ return
344
+
345
+ # Push the container to the registry
346
+ console.print("\nPushing container to registry. It may take a while...", style="bold")
347
+ # Authenticate with LitServe affiliate
348
+ authenticate(shall_confirm=not non_interactive)
349
+ resolved_teamspace = select_teamspace(teamspace, org, user)
350
+ verified = poll_verified_status()
351
+ if not verified:
352
+ console.print("❌ Verify phone number to continue. Visit lightning.ai.", style="red")
353
+ return
354
+
254
355
  # list containers to create the project if it doesn't exist
255
356
  lit_cr = LitContainerApi()
256
357
  lit_cr.list_containers(resolved_teamspace.id, cloud_account=cloud_account)
@@ -263,17 +364,21 @@ def _handle_cloud(
263
364
  transient=True,
264
365
  ) as progress:
265
366
  try:
266
- # TODO: @aniketmaurya improve the console prints here
267
- ls_deployer.build_container(path, repository, tag, console, progress)
268
- push_status = ls_deployer.push_container(
269
- repository, tag, resolved_teamspace, lit_cr, progress, cloud_account=cloud_account
270
- )
367
+ push_task = progress.add_task("Pushing to registry", total=None)
368
+ push_status = {}
369
+ for line in ls_deployer.push_container(
370
+ repository, tag, resolved_teamspace, lit_cr, cloud_account=cloud_account
371
+ ):
372
+ push_status = line
373
+ progress.update(push_task, advance=1)
374
+ if not ("Pushing" in line["status"] or "Waiting" in line["status"]):
375
+ console.print(line["status"])
376
+ progress.update(push_task, description="[green]Push completed![/green]")
271
377
  except Exception as e:
272
378
  console.print(f"❌ Deployment failed: {e}", style="red")
273
379
  return
274
380
  console.print(f"\n✅ Image pushed to {repository}:{tag}")
275
- console.print(f"🔗 You can access the container at: [i]{push_status.get('url')}[/i]")
276
- image = push_status.get("repository")
381
+ image = push_status.get("image")
277
382
 
278
383
  deployment_status = ls_deployer.run_on_cloud(
279
384
  deployment_name=deployment_name,
@@ -290,3 +395,4 @@ def _handle_cloud(
290
395
  include_credentials=include_credentials,
291
396
  )
292
397
  console.print(f"🚀 Deployment started, access at [i]{deployment_status.get('url')}[/i]")
398
+ webbrowser.open(deployment_status.get("url"))
@@ -83,6 +83,7 @@ from lightning_sdk.lightning_cloud.openapi.models.cloud_space_id_versionpublicat
83
83
  from lightning_sdk.lightning_cloud.openapi.models.cloud_space_id_versions_body import CloudSpaceIdVersionsBody
84
84
  from lightning_sdk.lightning_cloud.openapi.models.cloudspace_id_metric_body import CloudspaceIdMetricBody
85
85
  from lightning_sdk.lightning_cloud.openapi.models.cloudspace_id_runs_body import CloudspaceIdRunsBody
86
+ from lightning_sdk.lightning_cloud.openapi.models.cloudspace_id_systemmetrics_body import CloudspaceIdSystemmetricsBody
86
87
  from lightning_sdk.lightning_cloud.openapi.models.cloudspaces_id_body import CloudspacesIdBody
87
88
  from lightning_sdk.lightning_cloud.openapi.models.cluster_id_capacityblock_body import ClusterIdCapacityblockBody
88
89
  from lightning_sdk.lightning_cloud.openapi.models.cluster_id_capacityreservations_body import ClusterIdCapacityreservationsBody
@@ -495,6 +496,7 @@ from lightning_sdk.lightning_cloud.openapi.models.v1_get_agent_job_env_response
495
496
  from lightning_sdk.lightning_cloud.openapi.models.v1_get_agent_job_logs_metadata_response import V1GetAgentJobLogsMetadataResponse
496
497
  from lightning_sdk.lightning_cloud.openapi.models.v1_get_artifacts_page_response import V1GetArtifactsPageResponse
497
498
  from lightning_sdk.lightning_cloud.openapi.models.v1_get_cloud_space_instance_status_response import V1GetCloudSpaceInstanceStatusResponse
499
+ from lightning_sdk.lightning_cloud.openapi.models.v1_get_cloud_space_instance_system_metrics_aggregate_response import V1GetCloudSpaceInstanceSystemMetricsAggregateResponse
498
500
  from lightning_sdk.lightning_cloud.openapi.models.v1_get_cloud_space_size_response import V1GetCloudSpaceSizeResponse
499
501
  from lightning_sdk.lightning_cloud.openapi.models.v1_get_cluster_accelerator_demand_response import V1GetClusterAcceleratorDemandResponse
500
502
  from lightning_sdk.lightning_cloud.openapi.models.v1_get_cluster_credentials_response import V1GetClusterCredentialsResponse
@@ -775,6 +777,7 @@ from lightning_sdk.lightning_cloud.openapi.models.v1_refresh_response import V1R
775
777
  from lightning_sdk.lightning_cloud.openapi.models.v1_region_state import V1RegionState
776
778
  from lightning_sdk.lightning_cloud.openapi.models.v1_regional_load_balancer import V1RegionalLoadBalancer
777
779
  from lightning_sdk.lightning_cloud.openapi.models.v1_report_cloud_space_instance_stop_at_response import V1ReportCloudSpaceInstanceStopAtResponse
780
+ from lightning_sdk.lightning_cloud.openapi.models.v1_report_cloud_space_instance_system_metrics_response import V1ReportCloudSpaceInstanceSystemMetricsResponse
778
781
  from lightning_sdk.lightning_cloud.openapi.models.v1_report_logs_activity_response import V1ReportLogsActivityResponse
779
782
  from lightning_sdk.lightning_cloud.openapi.models.v1_report_restart_timings_response import V1ReportRestartTimingsResponse
780
783
  from lightning_sdk.lightning_cloud.openapi.models.v1_request_cluster_access_request import V1RequestClusterAccessRequest
@@ -840,6 +843,7 @@ from lightning_sdk.lightning_cloud.openapi.models.v1_subnet_spec import V1Subnet
840
843
  from lightning_sdk.lightning_cloud.openapi.models.v1_switch_cloud_space_instance_response import V1SwitchCloudSpaceInstanceResponse
841
844
  from lightning_sdk.lightning_cloud.openapi.models.v1_system_info import V1SystemInfo
842
845
  from lightning_sdk.lightning_cloud.openapi.models.v1_system_metrics import V1SystemMetrics
846
+ from lightning_sdk.lightning_cloud.openapi.models.v1_system_metrics_aggregated import V1SystemMetricsAggregated
843
847
  from lightning_sdk.lightning_cloud.openapi.models.v1_system_metrics_list import V1SystemMetricsList
844
848
  from lightning_sdk.lightning_cloud.openapi.models.v1_telemetry import V1Telemetry
845
849
  from lightning_sdk.lightning_cloud.openapi.models.v1_timestamp_code_telemetry import V1TimestampCodeTelemetry
@@ -903,6 +907,7 @@ from lightning_sdk.lightning_cloud.openapi.models.v1_verify_verification_respons
903
907
  from lightning_sdk.lightning_cloud.openapi.models.v1_voltage_park_direct_v1 import V1VoltageParkDirectV1
904
908
  from lightning_sdk.lightning_cloud.openapi.models.v1_volume import V1Volume
905
909
  from lightning_sdk.lightning_cloud.openapi.models.v1_vultr_direct_v1 import V1VultrDirectV1
910
+ from lightning_sdk.lightning_cloud.openapi.models.v1_weka_data_connection import V1WekaDataConnection
906
911
  from lightning_sdk.lightning_cloud.openapi.models.v1_work import V1Work
907
912
  from lightning_sdk.lightning_cloud.openapi.models.validate import Validate
908
913
  from lightning_sdk.lightning_cloud.openapi.models.validateautojoindomain_domain_body import ValidateautojoindomainDomainBody