lightning-sdk 2025.9.30__py3-none-any.whl → 2025.10.14__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 (69) hide show
  1. lightning_sdk/__init__.py +1 -1
  2. lightning_sdk/api/cloud_account_api.py +0 -2
  3. lightning_sdk/api/studio_api.py +8 -0
  4. lightning_sdk/base_studio.py +23 -12
  5. lightning_sdk/cli/base_studio/__init__.py +10 -0
  6. lightning_sdk/cli/base_studio/list.py +45 -0
  7. lightning_sdk/cli/entrypoint.py +2 -0
  8. lightning_sdk/cli/groups.py +7 -0
  9. lightning_sdk/cli/studio/connect.py +117 -22
  10. lightning_sdk/cli/studio/ssh.py +3 -6
  11. lightning_sdk/cli/utils/ssh_connection.py +8 -0
  12. lightning_sdk/job/job.py +5 -0
  13. lightning_sdk/job/v1.py +8 -0
  14. lightning_sdk/job/v2.py +8 -0
  15. lightning_sdk/lightning_cloud/openapi/__init__.py +20 -0
  16. lightning_sdk/lightning_cloud/openapi/api/__init__.py +1 -0
  17. lightning_sdk/lightning_cloud/openapi/api/assistants_service_api.py +19 -19
  18. lightning_sdk/lightning_cloud/openapi/api/cloud_space_service_api.py +105 -0
  19. lightning_sdk/lightning_cloud/openapi/api/k8_s_cluster_service_api.py +1463 -240
  20. lightning_sdk/lightning_cloud/openapi/api/sdk_command_history_service_api.py +141 -0
  21. lightning_sdk/lightning_cloud/openapi/models/__init__.py +19 -0
  22. lightning_sdk/lightning_cloud/openapi/models/cloudspace_id_visibility_body.py +27 -1
  23. lightning_sdk/lightning_cloud/openapi/models/cluster_id_metrics_body.py +53 -1
  24. lightning_sdk/lightning_cloud/openapi/models/deployments_id_body.py +27 -1
  25. lightning_sdk/lightning_cloud/openapi/models/externalv1_cloud_space_instance_status.py +53 -1
  26. lightning_sdk/lightning_cloud/openapi/models/id_transfer_body.py +53 -1
  27. lightning_sdk/lightning_cloud/openapi/models/incident_id_messages_body.py +149 -0
  28. lightning_sdk/lightning_cloud/openapi/models/incidents_id_body.py +279 -0
  29. lightning_sdk/lightning_cloud/openapi/models/messages_message_id_body.py +149 -0
  30. lightning_sdk/lightning_cloud/openapi/models/project_id_incidents_body.py +279 -0
  31. lightning_sdk/lightning_cloud/openapi/models/projects_id_body.py +27 -1
  32. lightning_sdk/lightning_cloud/openapi/models/storage_complete_body.py +15 -15
  33. lightning_sdk/lightning_cloud/openapi/models/v1_cloud_space_transfer_metadata.py +53 -1
  34. lightning_sdk/lightning_cloud/openapi/models/v1_create_project_request.py +27 -1
  35. lightning_sdk/lightning_cloud/openapi/models/v1_create_sdk_command_history_request.py +253 -0
  36. lightning_sdk/lightning_cloud/openapi/models/v1_create_sdk_command_history_response.py +97 -0
  37. lightning_sdk/lightning_cloud/openapi/models/v1_delete_incident_message_response.py +97 -0
  38. lightning_sdk/lightning_cloud/openapi/models/v1_delete_incident_response.py +97 -0
  39. lightning_sdk/lightning_cloud/openapi/models/v1_deployment.py +27 -1
  40. lightning_sdk/lightning_cloud/openapi/models/v1_get_cloud_space_transfer_estimate_response.py +123 -0
  41. lightning_sdk/lightning_cloud/openapi/models/v1_group_pod_metrics.py +1241 -0
  42. lightning_sdk/lightning_cloud/openapi/models/v1_incident.py +539 -0
  43. lightning_sdk/lightning_cloud/openapi/models/v1_incident_message.py +253 -0
  44. lightning_sdk/lightning_cloud/openapi/models/v1_incident_type.py +1 -0
  45. lightning_sdk/lightning_cloud/openapi/models/v1_job.py +53 -1
  46. lightning_sdk/lightning_cloud/openapi/models/v1_job_spec.py +27 -1
  47. lightning_sdk/lightning_cloud/openapi/models/v1_kai_scheduler_queue_metrics.py +627 -0
  48. lightning_sdk/lightning_cloud/openapi/models/v1_list_group_pod_metrics_response.py +123 -0
  49. lightning_sdk/lightning_cloud/openapi/models/v1_list_incident_messages_response.py +149 -0
  50. lightning_sdk/lightning_cloud/openapi/models/v1_list_incidents_response.py +149 -0
  51. lightning_sdk/lightning_cloud/openapi/models/v1_list_kai_scheduler_queues_metrics_response.py +123 -0
  52. lightning_sdk/lightning_cloud/openapi/models/v1_machine.py +53 -1
  53. lightning_sdk/lightning_cloud/openapi/models/v1_membership.py +27 -1
  54. lightning_sdk/lightning_cloud/openapi/models/v1_project_membership.py +27 -1
  55. lightning_sdk/lightning_cloud/openapi/models/v1_project_settings.py +27 -1
  56. lightning_sdk/lightning_cloud/openapi/models/v1_resource_visibility.py +1 -27
  57. lightning_sdk/lightning_cloud/openapi/models/v1_sdk_command_history_severity.py +104 -0
  58. lightning_sdk/lightning_cloud/openapi/models/v1_sdk_command_history_type.py +104 -0
  59. lightning_sdk/lightning_cloud/openapi/models/v1_server_alert_type.py +1 -0
  60. lightning_sdk/lightning_cloud/openapi/models/v1_user_features.py +157 -53
  61. lightning_sdk/machine.py +0 -1
  62. lightning_sdk/studio.py +42 -5
  63. lightning_sdk/utils/progress.py +32 -33
  64. {lightning_sdk-2025.9.30.dist-info → lightning_sdk-2025.10.14.dist-info}/METADATA +1 -1
  65. {lightning_sdk-2025.9.30.dist-info → lightning_sdk-2025.10.14.dist-info}/RECORD +69 -47
  66. {lightning_sdk-2025.9.30.dist-info → lightning_sdk-2025.10.14.dist-info}/LICENSE +0 -0
  67. {lightning_sdk-2025.9.30.dist-info → lightning_sdk-2025.10.14.dist-info}/WHEEL +0 -0
  68. {lightning_sdk-2025.9.30.dist-info → lightning_sdk-2025.10.14.dist-info}/entry_points.txt +0 -0
  69. {lightning_sdk-2025.9.30.dist-info → lightning_sdk-2025.10.14.dist-info}/top_level.txt +0 -0
lightning_sdk/__init__.py CHANGED
@@ -35,6 +35,6 @@ __all__ = [
35
35
  "VM",
36
36
  ]
37
37
 
38
- __version__ = "2025.09.30"
38
+ __version__ = "2025.10.14"
39
39
  _check_version_and_prompt_upgrade(__version__)
40
40
  _set_tqdm_envvars_noninteractive()
@@ -173,8 +173,6 @@ class CloudAccountApi:
173
173
  return CloudProvider.GCP
174
174
  if cloud_account.spec.lambda_labs_v1:
175
175
  return CloudProvider.LAMBDA_LABS
176
- if cloud_account.spec.vultr_v1:
177
- return CloudProvider.VULTR
178
176
  if cloud_account.spec.voltage_park_v1:
179
177
  return CloudProvider.VOLTAGE_PARK
180
178
  if cloud_account.spec.nebius_v1:
@@ -438,6 +438,14 @@ class StudioApi:
438
438
 
439
439
  return response.compute_config.spot
440
440
 
441
+ def get_public_ip(self, studio_id: str, teamspace_id: str) -> Optional[str]:
442
+ """Get the public IP address of the Studio."""
443
+ internal_status = self.get_studio_status(studio_id=studio_id, teamspace_id=teamspace_id).in_use
444
+ if internal_status is None:
445
+ return None
446
+
447
+ return internal_status.public_ip_address
448
+
441
449
  def _get_machines_for_cloud_account(
442
450
  self, teamspace_id: str, cloud_account_id: str, org_id: str
443
451
  ) -> List[V1ClusterAccelerator]:
@@ -16,6 +16,8 @@ class BaseStudioInfo:
16
16
  name: str
17
17
  managed_id: str
18
18
  description: str
19
+ creator: str
20
+ enabled: bool
19
21
 
20
22
 
21
23
  class BaseStudio:
@@ -80,20 +82,29 @@ class BaseStudio:
80
82
  disabled=disabled,
81
83
  )
82
84
 
83
- def list(self, managed: bool = True) -> List[BaseStudioInfo]:
85
+ def list(self, managed: bool = True, include_disabled: bool = False) -> List[BaseStudioInfo]:
84
86
  """List all base studios in the organization.
85
87
 
88
+ Args:
89
+ managed: Whether to filter for managed base studios.
90
+ include_disabled: Whether to include disabled base studios in the results.
91
+
86
92
  Returns:
87
- List[V1CloudSpaceEnvironmentTemplate]: A list of base studio templates.
93
+ List[BaseStudioInfo]: A list of base studio templates.
88
94
  """
89
- result = []
90
- for template in self._base_studio_api.get_all_base_studios(self._org.id, managed).templates:
91
- result.append(
92
- BaseStudioInfo(
93
- id=template.id,
94
- name=template.name,
95
- managed_id=template.managed_id,
96
- description=template.description,
97
- ),
95
+ templates = self._base_studio_api.get_all_base_studios(self._org.id, managed).templates
96
+
97
+ return [
98
+ BaseStudioInfo(
99
+ id=template.id,
100
+ name=template.name,
101
+ managed_id=template.managed_id,
102
+ description=template.description,
103
+ creator="⚡ Lightning AI"
104
+ if template.managed_id
105
+ else UserApi()._get_user_by_id(template.user_id).username,
106
+ enabled=not template.disabled,
98
107
  )
99
- return result
108
+ for template in templates
109
+ if include_disabled or not template.disabled
110
+ ]
@@ -0,0 +1,10 @@
1
+ """Base Studio CLI commands."""
2
+
3
+ import click
4
+
5
+
6
+ def register_commands(group: click.Group) -> None:
7
+ """Register base studio commands with the given group."""
8
+ from lightning_sdk.cli.base_studio.list import list_base_studios
9
+
10
+ group.add_command(list_base_studios)
@@ -0,0 +1,45 @@
1
+ """Base Studio list command."""
2
+
3
+ import click
4
+ from rich.table import Table
5
+
6
+ from lightning_sdk.base_studio import BaseStudio
7
+ from lightning_sdk.cli.utils.richt_print import rich_to_str
8
+
9
+
10
+ @click.command("list")
11
+ @click.option("--include-disabled", help="Include disabled Base Studios in the list.", is_flag=True)
12
+ def list_base_studios(include_disabled: bool) -> None:
13
+ """List Base Studios in an org.
14
+
15
+ Example:
16
+ lightning base-studio list
17
+
18
+ """
19
+ return list_impl(include_disabled=include_disabled)
20
+
21
+
22
+ def list_impl(include_disabled: bool) -> None:
23
+ base_studio_cls = BaseStudio()
24
+ base_studios = base_studio_cls.list(include_disabled=include_disabled) + base_studio_cls.list(
25
+ managed=False, include_disabled=include_disabled
26
+ )
27
+
28
+ table = Table(
29
+ pad_edge=True,
30
+ )
31
+
32
+ table.add_column("Name")
33
+ table.add_column("Description")
34
+ table.add_column("Creator")
35
+ table.add_column("Enabled")
36
+
37
+ for base_studio in base_studios:
38
+ table.add_row(
39
+ base_studio.name.lower().replace(" ", "-"),
40
+ base_studio.description or "",
41
+ base_studio.creator,
42
+ "Yes" if base_studio.enabled else "No",
43
+ )
44
+
45
+ click.echo(rich_to_str(table), color=True)
@@ -17,6 +17,7 @@ from lightning_sdk.api.studio_api import _cloud_url
17
17
 
18
18
  # Import legacy groups directly from groups.py
19
19
  from lightning_sdk.cli.groups import (
20
+ base_studio,
20
21
  config,
21
22
  # job,
22
23
  # mmt,
@@ -85,6 +86,7 @@ main_cli.add_command(config)
85
86
  # main_cli.add_command(mmt)
86
87
  main_cli.add_command(studio)
87
88
  main_cli.add_command(vm)
89
+ main_cli.add_command(base_studio)
88
90
  if os.environ.get("LIGHTNING_EXPERIMENTAL_CLI_ONLY", "0") != "1":
89
91
  #### LEGACY COMMANDS ####
90
92
  # these commands are currently supported for backwards compatibility, but will potentially be removed in the future.
@@ -2,6 +2,7 @@
2
2
 
3
3
  import click
4
4
 
5
+ from lightning_sdk.cli.base_studio import register_commands as register_base_studio_commands
5
6
  from lightning_sdk.cli.config import register_commands as register_config_commands
6
7
  from lightning_sdk.cli.job import register_commands as register_job_commands
7
8
  from lightning_sdk.cli.mmt import register_commands as register_mmt_commands
@@ -34,9 +35,15 @@ def vm() -> None:
34
35
  """Manage Lightning AI VMs."""
35
36
 
36
37
 
38
+ @click.group(name="base-studio")
39
+ def base_studio() -> None:
40
+ """Manage Lightning AI Base Studios."""
41
+
42
+
37
43
  # Register config commands with the main config group
38
44
  register_job_commands(job)
39
45
  register_mmt_commands(mmt)
40
46
  register_studio_commands(studio)
41
47
  register_config_commands(config)
42
48
  register_vm_commands(vm)
49
+ register_base_studio_commands(base_studio)
@@ -2,20 +2,96 @@
2
2
 
3
3
  import subprocess
4
4
  import sys
5
- from typing import Optional
5
+ from typing import Dict, Optional, Set
6
6
 
7
7
  import click
8
8
 
9
+ from lightning_sdk.base_studio import BaseStudio
9
10
  from lightning_sdk.cli.utils.richt_print import studio_name_link
10
11
  from lightning_sdk.cli.utils.save_to_config import save_studio_to_config, save_teamspace_to_config
11
- from lightning_sdk.cli.utils.ssh_connection import download_ssh_keys
12
+ from lightning_sdk.cli.utils.ssh_connection import configure_ssh_internal
12
13
  from lightning_sdk.cli.utils.teamspace_selection import TeamspacesMenu
13
- from lightning_sdk.lightning_cloud.login import Auth
14
14
  from lightning_sdk.lightning_cloud.openapi.rest import ApiException
15
- from lightning_sdk.machine import CloudProvider
15
+ from lightning_sdk.machine import CloudProvider, Machine
16
16
  from lightning_sdk.studio import Studio
17
17
  from lightning_sdk.utils.names import random_unique_name
18
18
 
19
+ DEFAULT_MACHINE = "CPU"
20
+
21
+
22
+ def _split_gpus_spec(gpus: str) -> tuple[str, int]:
23
+ machine_name, machine_val = gpus.split(":", 1)
24
+ machine_name = machine_name.strip()
25
+ machine_val = machine_val.strip()
26
+
27
+ if not machine_val.isdigit() or int(machine_val) <= 0:
28
+ raise ValueError(f"Invalid GPU count '{machine_val}'. Must be a positive integer.")
29
+
30
+ machine_num = int(machine_val)
31
+ return machine_name, machine_num
32
+
33
+
34
+ def _construct_available_gpus(machine_options: Dict[str, str]) -> Set[str]:
35
+ # returns available gpus:count
36
+ available_gpus = set()
37
+ for v in machine_options.values():
38
+ if "_X_" in v:
39
+ gpu_type_num = v.replace("_X_", ":")
40
+ available_gpus.add(gpu_type_num)
41
+ else:
42
+ available_gpus.add(v)
43
+ return available_gpus
44
+
45
+
46
+ def _get_machine_from_gpus(gpus: str) -> Machine:
47
+ machine_name = gpus
48
+ machine_num = 1
49
+
50
+ if ":" in gpus:
51
+ machine_name, machine_num = _split_gpus_spec(gpus)
52
+
53
+ machine_options = {
54
+ m.name.lower(): m.name for m in Machine.__dict__.values() if isinstance(m, Machine) and m._include_in_cli
55
+ }
56
+
57
+ if machine_num == 1:
58
+ # e.g. gpus=L4 or gpus=L4:1
59
+ gpu_key = machine_name.lower()
60
+ try:
61
+ return machine_options[gpu_key]
62
+ except KeyError:
63
+ available = ", ".join(_construct_available_gpus(machine_options))
64
+ raise ValueError(f"Invalid GPU type '{machine_name}'. Available options: {available}") from None
65
+
66
+ # Else: e.g. gpus=L4:4
67
+ gpu_key = f"{machine_name.lower()}_x_{machine_num}"
68
+ try:
69
+ return machine_options[gpu_key]
70
+ except KeyError:
71
+ available = ", ".join(_construct_available_gpus(machine_options))
72
+ raise ValueError(f"Invalid GPU configuration '{gpus}'. Available options: {available}") from None
73
+
74
+
75
+ def _get_base_studio_id(studio_type: Optional[str]) -> Optional[str]:
76
+ base_studios = BaseStudio()
77
+ base_studios = base_studios.list()
78
+ template_id = None
79
+
80
+ if base_studios and len(base_studios):
81
+ # if not specified by user, use the first existing template studio
82
+ template_id = base_studios[0].id
83
+ # else, try to match the provided studio_type to base studio name
84
+ if studio_type:
85
+ normalized_studio_type = studio_type.lower().replace(" ", "-")
86
+ match = next(
87
+ (s for s in base_studios if s.name.lower().replace(" ", "-") == normalized_studio_type),
88
+ None,
89
+ )
90
+ if match:
91
+ template_id = match.id
92
+
93
+ return template_id
94
+
19
95
 
20
96
  @click.command("connect")
21
97
  @click.argument("name", required=False)
@@ -30,13 +106,32 @@ from lightning_sdk.utils.names import random_unique_name
30
106
  help="The cloud account to create the studio on. Defaults to teamspace default.",
31
107
  type=click.STRING,
32
108
  )
33
- @click.option("--gpus", help="The number of GPUs to start the studio on. ", type=click.INT)
109
+ @click.option(
110
+ "--machine",
111
+ help="The machine type to start the studio on. Defaults to CPU-4",
112
+ type=click.Choice(m.name for m in Machine.__dict__.values() if isinstance(m, Machine) and m._include_in_cli),
113
+ )
114
+ @click.option(
115
+ "--gpus",
116
+ help="The number and type of GPUs to start the studio on (format: TYPE:COUNT, e.g. L4:4)",
117
+ type=click.STRING,
118
+ )
119
+ @click.option(
120
+ "--studio-type",
121
+ help="The base studio template name to use for creating the studio. "
122
+ "Must be lowercase and hyphenated (use '-' instead of spaces). "
123
+ "Run 'lightning base-studio list' to see all available templates. "
124
+ "Defaults to the first available template.",
125
+ type=click.STRING,
126
+ )
34
127
  def connect_studio(
35
128
  name: Optional[str] = None,
36
129
  teamspace: Optional[str] = None,
37
130
  cloud_provider: Optional[str] = None,
38
131
  cloud_account: Optional[str] = None,
39
- gpus: Optional[int] = None,
132
+ machine: Optional[str] = None,
133
+ gpus: Optional[str] = None,
134
+ studio_type: Optional[str] = None,
40
135
  ) -> None:
41
136
  """Connect to a Studio.
42
137
 
@@ -53,6 +148,9 @@ def connect_studio(
53
148
 
54
149
  name = name or random_unique_name()
55
150
 
151
+ # check for available base studios
152
+ template_id = _get_base_studio_id(studio_type)
153
+
56
154
  try:
57
155
  studio = Studio(
58
156
  name=name,
@@ -60,35 +158,32 @@ def connect_studio(
60
158
  create_ok=True,
61
159
  cloud_provider=cloud_provider,
62
160
  cloud_account=cloud_account,
161
+ studio_type=template_id,
63
162
  )
64
163
  except (RuntimeError, ValueError, ApiException):
65
164
  raise ValueError(f"Could not create Studio: '{name}'") from None
66
165
 
67
166
  click.echo(f"Connecting to Studio '{studio_name_link(studio)}' ...")
68
167
 
69
- machine = "CPU"
70
168
  Studio.show_progress = True
71
- if gpus:
72
- # TODO: handle something like gpus=4:L4
73
- pass
169
+
170
+ if machine and gpus:
171
+ raise click.UsageError("Options --machine and --gpu are mutually exclusive. Provide only one.")
172
+ elif gpus:
173
+ machine = _get_machine_from_gpus(gpus.strip())
174
+ elif not machine:
175
+ machine = DEFAULT_MACHINE
74
176
 
75
177
  save_studio_to_config(studio)
76
- studio.start(machine, interruptible=True)
178
+ # by default, interruptible is False
179
+ studio.start(machine=machine, interruptible=False)
77
180
 
78
- ssh_private_key_path = _configure_ssh_internal()
181
+ ssh_private_key_path = configure_ssh_internal()
79
182
 
183
+ ssh_option = "-o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -o LogLevel=ERROR"
80
184
  try:
81
- ssh_command = (
82
- f"ssh -i {ssh_private_key_path} -o UserKnownHostsFile=/dev/null s_{studio._studio.id}@ssh.lightning.ai"
83
- )
185
+ ssh_command = f"ssh -i {ssh_private_key_path} {ssh_option} s_{studio._studio.id}@ssh.lightning.ai"
84
186
  subprocess.run(ssh_command.split())
85
187
  except Exception as ex:
86
188
  print(f"Failed to establish SSH connection: {ex}")
87
189
  sys.exit(1)
88
-
89
-
90
- def _configure_ssh_internal() -> str:
91
- """Internal function to configure SSH without Click decorators."""
92
- auth = Auth()
93
- auth.authenticate()
94
- return download_ssh_keys(auth.api_key, force_download=False)
@@ -6,10 +6,9 @@ from typing import List, Optional
6
6
  import click
7
7
 
8
8
  from lightning_sdk.cli.utils.save_to_config import save_studio_to_config
9
- from lightning_sdk.cli.utils.ssh_connection import download_ssh_keys
9
+ from lightning_sdk.cli.utils.ssh_connection import configure_ssh_internal
10
10
  from lightning_sdk.cli.utils.studio_selection import StudiosMenu
11
11
  from lightning_sdk.cli.utils.teamspace_selection import TeamspacesMenu
12
- from lightning_sdk.lightning_cloud.login import Auth
13
12
 
14
13
 
15
14
  @click.command("ssh")
@@ -39,9 +38,7 @@ def ssh_studio(name: Optional[str] = None, teamspace: Optional[str] = None, opti
39
38
 
40
39
 
41
40
  def ssh_impl(name: Optional[str], teamspace: Optional[str], option: Optional[List[str]], vm: bool) -> None:
42
- auth = Auth()
43
- auth.authenticate()
44
- ssh_private_key_path = download_ssh_keys(auth.api_key, force_download=False)
41
+ ssh_private_key_path = configure_ssh_internal()
45
42
 
46
43
  menu = TeamspacesMenu()
47
44
  resolved_teamspace = menu(teamspace=teamspace)
@@ -59,7 +56,7 @@ def ssh_impl(name: Optional[str], teamspace: Optional[str], option: Optional[Lis
59
56
  subprocess.run(ssh_command.split())
60
57
  except Exception:
61
58
  # redownload the keys to be sure they are up to date
62
- download_ssh_keys(auth.api_key, force_download=True)
59
+ ssh_private_key_path = configure_ssh_internal(force_download=True)
63
60
  try:
64
61
  subprocess.run(ssh_command.split())
65
62
  except Exception:
@@ -4,9 +4,17 @@ import uuid
4
4
  from pathlib import Path
5
5
  from typing import Optional
6
6
 
7
+ from lightning_sdk.lightning_cloud.login import Auth
7
8
  from lightning_sdk.utils.config import _DEFAULT_CONFIG_FILE_PATH
8
9
 
9
10
 
11
+ def configure_ssh_internal(force_download: bool = False) -> str:
12
+ """Internal function to configure SSH without Click decorators."""
13
+ auth = Auth()
14
+ auth.authenticate()
15
+ return download_ssh_keys(auth.api_key, force_download=force_download)
16
+
17
+
10
18
  def download_ssh_keys(
11
19
  api_key: str | None,
12
20
  force_download: bool = False,
lightning_sdk/job/job.py CHANGED
@@ -268,6 +268,11 @@ class Job(_BaseJob):
268
268
  """The machine type the job is running on."""
269
269
  return self._internal_job.machine
270
270
 
271
+ @property
272
+ def public_ip(self) -> Optional[str]:
273
+ """The public IP address of the machine the job is running on."""
274
+ return self._internal_job.public_ip
275
+
271
276
  @property
272
277
  def artifact_path(self) -> Optional[str]:
273
278
  """Path to the artifacts created by the job within the distributed teamspace filesystem."""
lightning_sdk/job/v1.py CHANGED
@@ -181,6 +181,14 @@ class _JobV1(_BaseJob):
181
181
  """Get the machine the job is running on."""
182
182
  return self.work.machine
183
183
 
184
+ @property
185
+ def public_ip(self) -> Optional[str]:
186
+ """Get the public IP of the machine the job is running on."""
187
+ try:
188
+ return self._job.status.ip_address
189
+ except AttributeError:
190
+ return None
191
+
184
192
  @property
185
193
  def name(self) -> str:
186
194
  """The name of the job."""
lightning_sdk/job/v2.py CHANGED
@@ -173,6 +173,14 @@ class _JobV2(_BaseJob):
173
173
  _get_org_id(self.teamspace),
174
174
  )
175
175
 
176
+ @property
177
+ def public_ip(self) -> Optional[str]:
178
+ """Get the public IP of the machine the job is running on."""
179
+ try:
180
+ return self._job.public_ip_address
181
+ except AttributeError:
182
+ return None
183
+
176
184
  @property
177
185
  def artifact_path(self) -> Optional[str]:
178
186
  """The path to the artifacts of the job within the distributed teamspace filesystem."""
@@ -56,6 +56,7 @@ from lightning_sdk.lightning_cloud.openapi.api.product_license_service_api impor
56
56
  from lightning_sdk.lightning_cloud.openapi.api.profiler_service_api import ProfilerServiceApi
57
57
  from lightning_sdk.lightning_cloud.openapi.api.projects_service_api import ProjectsServiceApi
58
58
  from lightning_sdk.lightning_cloud.openapi.api.quest_service_api import QuestServiceApi
59
+ from lightning_sdk.lightning_cloud.openapi.api.sdk_command_history_service_api import SDKCommandHistoryServiceApi
59
60
  from lightning_sdk.lightning_cloud.openapi.api.ssh_public_key_service_api import SSHPublicKeyServiceApi
60
61
  from lightning_sdk.lightning_cloud.openapi.api.schedules_service_api import SchedulesServiceApi
61
62
  from lightning_sdk.lightning_cloud.openapi.api.secret_service_api import SecretServiceApi
@@ -157,6 +158,8 @@ from lightning_sdk.lightning_cloud.openapi.models.id_uploads_body import IdUploa
157
158
  from lightning_sdk.lightning_cloud.openapi.models.id_visibility_body import IdVisibilityBody
158
159
  from lightning_sdk.lightning_cloud.openapi.models.id_visibility_body1 import IdVisibilityBody1
159
160
  from lightning_sdk.lightning_cloud.openapi.models.id_visibility_body2 import IdVisibilityBody2
161
+ from lightning_sdk.lightning_cloud.openapi.models.incident_id_messages_body import IncidentIdMessagesBody
162
+ from lightning_sdk.lightning_cloud.openapi.models.incidents_id_body import IncidentsIdBody
160
163
  from lightning_sdk.lightning_cloud.openapi.models.job_id_reportroutingtelemetry_body import JobIdReportroutingtelemetryBody
161
164
  from lightning_sdk.lightning_cloud.openapi.models.jobs_id_body import JobsIdBody
162
165
  from lightning_sdk.lightning_cloud.openapi.models.jobs_id_body1 import JobsIdBody1
@@ -169,6 +172,7 @@ from lightning_sdk.lightning_cloud.openapi.models.litpages_id_body import Litpag
169
172
  from lightning_sdk.lightning_cloud.openapi.models.litregistry_lit_repo_name_body import LitregistryLitRepoNameBody
170
173
  from lightning_sdk.lightning_cloud.openapi.models.loggermetrics_id_body import LoggermetricsIdBody
171
174
  from lightning_sdk.lightning_cloud.openapi.models.messages_id_body import MessagesIdBody
175
+ from lightning_sdk.lightning_cloud.openapi.models.messages_message_id_body import MessagesMessageIdBody
172
176
  from lightning_sdk.lightning_cloud.openapi.models.metrics_stream_id_loggerartifacts_body import MetricsStreamIdLoggerartifactsBody
173
177
  from lightning_sdk.lightning_cloud.openapi.models.metricsstream_create_body import MetricsstreamCreateBody
174
178
  from lightning_sdk.lightning_cloud.openapi.models.metricsstream_delete_body import MetricsstreamDeleteBody
@@ -195,6 +199,7 @@ from lightning_sdk.lightning_cloud.openapi.models.project_id_clusters_body impor
195
199
  from lightning_sdk.lightning_cloud.openapi.models.project_id_datasets_body import ProjectIdDatasetsBody
196
200
  from lightning_sdk.lightning_cloud.openapi.models.project_id_endpoints_body import ProjectIdEndpointsBody
197
201
  from lightning_sdk.lightning_cloud.openapi.models.project_id_getapp_body import ProjectIdGetappBody
202
+ from lightning_sdk.lightning_cloud.openapi.models.project_id_incidents_body import ProjectIdIncidentsBody
198
203
  from lightning_sdk.lightning_cloud.openapi.models.project_id_invite_body import ProjectIdInviteBody
199
204
  from lightning_sdk.lightning_cloud.openapi.models.project_id_jobs_body import ProjectIdJobsBody
200
205
  from lightning_sdk.lightning_cloud.openapi.models.project_id_kubernetestemplates_body import ProjectIdKubernetestemplatesBody
@@ -400,6 +405,8 @@ from lightning_sdk.lightning_cloud.openapi.models.v1_create_multi_part_upload_re
400
405
  from lightning_sdk.lightning_cloud.openapi.models.v1_create_organization_request import V1CreateOrganizationRequest
401
406
  from lightning_sdk.lightning_cloud.openapi.models.v1_create_pipeline_template_request import V1CreatePipelineTemplateRequest
402
407
  from lightning_sdk.lightning_cloud.openapi.models.v1_create_project_request import V1CreateProjectRequest
408
+ from lightning_sdk.lightning_cloud.openapi.models.v1_create_sdk_command_history_request import V1CreateSDKCommandHistoryRequest
409
+ from lightning_sdk.lightning_cloud.openapi.models.v1_create_sdk_command_history_response import V1CreateSDKCommandHistoryResponse
403
410
  from lightning_sdk.lightning_cloud.openapi.models.v1_create_ssh_public_key_request import V1CreateSSHPublicKeyRequest
404
411
  from lightning_sdk.lightning_cloud.openapi.models.v1_create_server_alert_response import V1CreateServerAlertResponse
405
412
  from lightning_sdk.lightning_cloud.openapi.models.v1_create_shared_metrics_stream_request import V1CreateSharedMetricsStreamRequest
@@ -440,6 +447,8 @@ from lightning_sdk.lightning_cloud.openapi.models.v1_delete_deployment_release_r
440
447
  from lightning_sdk.lightning_cloud.openapi.models.v1_delete_deployment_response import V1DeleteDeploymentResponse
441
448
  from lightning_sdk.lightning_cloud.openapi.models.v1_delete_endpoint_response import V1DeleteEndpointResponse
442
449
  from lightning_sdk.lightning_cloud.openapi.models.v1_delete_git_credentials_response import V1DeleteGitCredentialsResponse
450
+ from lightning_sdk.lightning_cloud.openapi.models.v1_delete_incident_message_response import V1DeleteIncidentMessageResponse
451
+ from lightning_sdk.lightning_cloud.openapi.models.v1_delete_incident_response import V1DeleteIncidentResponse
443
452
  from lightning_sdk.lightning_cloud.openapi.models.v1_delete_index_response import V1DeleteIndexResponse
444
453
  from lightning_sdk.lightning_cloud.openapi.models.v1_delete_job_response import V1DeleteJobResponse
445
454
  from lightning_sdk.lightning_cloud.openapi.models.v1_delete_kubernetes_template_response import V1DeleteKubernetesTemplateResponse
@@ -567,6 +576,7 @@ from lightning_sdk.lightning_cloud.openapi.models.v1_get_cloud_space_instance_st
567
576
  from lightning_sdk.lightning_cloud.openapi.models.v1_get_cloud_space_instance_system_metrics_aggregate_response import V1GetCloudSpaceInstanceSystemMetricsAggregateResponse
568
577
  from lightning_sdk.lightning_cloud.openapi.models.v1_get_cloud_space_required_balance_status_response import V1GetCloudSpaceRequiredBalanceStatusResponse
569
578
  from lightning_sdk.lightning_cloud.openapi.models.v1_get_cloud_space_size_response import V1GetCloudSpaceSizeResponse
579
+ from lightning_sdk.lightning_cloud.openapi.models.v1_get_cloud_space_transfer_estimate_response import V1GetCloudSpaceTransferEstimateResponse
570
580
  from lightning_sdk.lightning_cloud.openapi.models.v1_get_cluster_accelerator_demand_response import V1GetClusterAcceleratorDemandResponse
571
581
  from lightning_sdk.lightning_cloud.openapi.models.v1_get_cluster_credentials_response import V1GetClusterCredentialsResponse
572
582
  from lightning_sdk.lightning_cloud.openapi.models.v1_get_cluster_health_response import V1GetClusterHealthResponse
@@ -609,6 +619,7 @@ from lightning_sdk.lightning_cloud.openapi.models.v1_git_credentials import V1Gi
609
619
  from lightning_sdk.lightning_cloud.openapi.models.v1_google_cloud_direct_v1 import V1GoogleCloudDirectV1
610
620
  from lightning_sdk.lightning_cloud.openapi.models.v1_google_cloud_direct_v1_status import V1GoogleCloudDirectV1Status
611
621
  from lightning_sdk.lightning_cloud.openapi.models.v1_group_node_metrics import V1GroupNodeMetrics
622
+ from lightning_sdk.lightning_cloud.openapi.models.v1_group_pod_metrics import V1GroupPodMetrics
612
623
  from lightning_sdk.lightning_cloud.openapi.models.v1_guest_login_request import V1GuestLoginRequest
613
624
  from lightning_sdk.lightning_cloud.openapi.models.v1_guest_login_response import V1GuestLoginResponse
614
625
  from lightning_sdk.lightning_cloud.openapi.models.v1_guest_user import V1GuestUser
@@ -618,7 +629,9 @@ from lightning_sdk.lightning_cloud.openapi.models.v1_health_check_http_get impor
618
629
  from lightning_sdk.lightning_cloud.openapi.models.v1_ids_logger_metrics import V1IdsLoggerMetrics
619
630
  from lightning_sdk.lightning_cloud.openapi.models.v1_image_spec import V1ImageSpec
620
631
  from lightning_sdk.lightning_cloud.openapi.models.v1_image_state import V1ImageState
632
+ from lightning_sdk.lightning_cloud.openapi.models.v1_incident import V1Incident
621
633
  from lightning_sdk.lightning_cloud.openapi.models.v1_incident_event import V1IncidentEvent
634
+ from lightning_sdk.lightning_cloud.openapi.models.v1_incident_message import V1IncidentMessage
622
635
  from lightning_sdk.lightning_cloud.openapi.models.v1_incident_severity import V1IncidentSeverity
623
636
  from lightning_sdk.lightning_cloud.openapi.models.v1_incident_type import V1IncidentType
624
637
  from lightning_sdk.lightning_cloud.openapi.models.v1_index import V1Index
@@ -641,6 +654,7 @@ from lightning_sdk.lightning_cloud.openapi.models.v1_job_timing import V1JobTimi
641
654
  from lightning_sdk.lightning_cloud.openapi.models.v1_job_type import V1JobType
642
655
  from lightning_sdk.lightning_cloud.openapi.models.v1_joinable_organization import V1JoinableOrganization
643
656
  from lightning_sdk.lightning_cloud.openapi.models.v1_k8s_incident_indexes import V1K8sIncidentIndexes
657
+ from lightning_sdk.lightning_cloud.openapi.models.v1_kai_scheduler_queue_metrics import V1KaiSchedulerQueueMetrics
644
658
  from lightning_sdk.lightning_cloud.openapi.models.v1_keep_alive_cloud_space_instance_response import V1KeepAliveCloudSpaceInstanceResponse
645
659
  from lightning_sdk.lightning_cloud.openapi.models.v1_knowledge_configuration import V1KnowledgeConfiguration
646
660
  from lightning_sdk.lightning_cloud.openapi.models.v1_kubernetes_direct_v1 import V1KubernetesDirectV1
@@ -721,11 +735,15 @@ from lightning_sdk.lightning_cloud.openapi.models.v1_list_filesystem_snowflake_r
721
735
  from lightning_sdk.lightning_cloud.openapi.models.v1_list_gallery_components_response import V1ListGalleryComponentsResponse
722
736
  from lightning_sdk.lightning_cloud.openapi.models.v1_list_gallery_lightningapps_response import V1ListGalleryLightningappsResponse
723
737
  from lightning_sdk.lightning_cloud.openapi.models.v1_list_git_credentials_response import V1ListGitCredentialsResponse
738
+ from lightning_sdk.lightning_cloud.openapi.models.v1_list_group_pod_metrics_response import V1ListGroupPodMetricsResponse
724
739
  from lightning_sdk.lightning_cloud.openapi.models.v1_list_incident_events_response import V1ListIncidentEventsResponse
740
+ from lightning_sdk.lightning_cloud.openapi.models.v1_list_incident_messages_response import V1ListIncidentMessagesResponse
741
+ from lightning_sdk.lightning_cloud.openapi.models.v1_list_incidents_response import V1ListIncidentsResponse
725
742
  from lightning_sdk.lightning_cloud.openapi.models.v1_list_job_files_response import V1ListJobFilesResponse
726
743
  from lightning_sdk.lightning_cloud.openapi.models.v1_list_job_resources_response import V1ListJobResourcesResponse
727
744
  from lightning_sdk.lightning_cloud.openapi.models.v1_list_jobs_response import V1ListJobsResponse
728
745
  from lightning_sdk.lightning_cloud.openapi.models.v1_list_joinable_organizations_response import V1ListJoinableOrganizationsResponse
746
+ from lightning_sdk.lightning_cloud.openapi.models.v1_list_kai_scheduler_queues_metrics_response import V1ListKaiSchedulerQueuesMetricsResponse
729
747
  from lightning_sdk.lightning_cloud.openapi.models.v1_list_kubernetes_templates_response import V1ListKubernetesTemplatesResponse
730
748
  from lightning_sdk.lightning_cloud.openapi.models.v1_list_lightning_run_response import V1ListLightningRunResponse
731
749
  from lightning_sdk.lightning_cloud.openapi.models.v1_list_lightningapp_instance_artifacts_response import V1ListLightningappInstanceArtifactsResponse
@@ -938,6 +956,8 @@ from lightning_sdk.lightning_cloud.openapi.models.v1_rule_condition import V1Rul
938
956
  from lightning_sdk.lightning_cloud.openapi.models.v1_rule_effect import V1RuleEffect
939
957
  from lightning_sdk.lightning_cloud.openapi.models.v1_rule_resource import V1RuleResource
940
958
  from lightning_sdk.lightning_cloud.openapi.models.v1_s3_folder_data_connection import V1S3FolderDataConnection
959
+ from lightning_sdk.lightning_cloud.openapi.models.v1_sdk_command_history_severity import V1SDKCommandHistorySeverity
960
+ from lightning_sdk.lightning_cloud.openapi.models.v1_sdk_command_history_type import V1SDKCommandHistoryType
941
961
  from lightning_sdk.lightning_cloud.openapi.models.v1_slurm_job import V1SLURMJob
942
962
  from lightning_sdk.lightning_cloud.openapi.models.v1_ssh_key_pair import V1SSHKeyPair
943
963
  from lightning_sdk.lightning_cloud.openapi.models.v1_ssh_public_key import V1SSHPublicKey
@@ -37,6 +37,7 @@ from lightning_sdk.lightning_cloud.openapi.api.product_license_service_api impor
37
37
  from lightning_sdk.lightning_cloud.openapi.api.profiler_service_api import ProfilerServiceApi
38
38
  from lightning_sdk.lightning_cloud.openapi.api.projects_service_api import ProjectsServiceApi
39
39
  from lightning_sdk.lightning_cloud.openapi.api.quest_service_api import QuestServiceApi
40
+ from lightning_sdk.lightning_cloud.openapi.api.sdk_command_history_service_api import SDKCommandHistoryServiceApi
40
41
  from lightning_sdk.lightning_cloud.openapi.api.ssh_public_key_service_api import SSHPublicKeyServiceApi
41
42
  from lightning_sdk.lightning_cloud.openapi.api.schedules_service_api import SchedulesServiceApi
42
43
  from lightning_sdk.lightning_cloud.openapi.api.secret_service_api import SecretServiceApi