lightning-sdk 2025.7.17__py3-none-any.whl → 2025.7.30rc0__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 (99) hide show
  1. lightning_sdk/__init__.py +3 -2
  2. lightning_sdk/api/cloud_account_api.py +204 -0
  3. lightning_sdk/api/deployment_api.py +11 -0
  4. lightning_sdk/api/job_api.py +82 -10
  5. lightning_sdk/api/llm_api.py +1 -1
  6. lightning_sdk/api/mmt_api.py +44 -5
  7. lightning_sdk/api/pipeline_api.py +4 -3
  8. lightning_sdk/api/studio_api.py +51 -8
  9. lightning_sdk/api/utils.py +6 -2
  10. lightning_sdk/cli/clusters_menu.py +3 -3
  11. lightning_sdk/cli/create.py +25 -11
  12. lightning_sdk/cli/deploy/_auth.py +19 -3
  13. lightning_sdk/cli/deploy/serve.py +21 -5
  14. lightning_sdk/cli/download.py +25 -1
  15. lightning_sdk/cli/entrypoint.py +4 -2
  16. lightning_sdk/cli/list.py +5 -1
  17. lightning_sdk/cli/run.py +3 -1
  18. lightning_sdk/cli/start.py +40 -8
  19. lightning_sdk/cli/switch.py +3 -1
  20. lightning_sdk/deployment/deployment.py +8 -0
  21. lightning_sdk/job/base.py +27 -3
  22. lightning_sdk/job/job.py +28 -4
  23. lightning_sdk/job/v1.py +10 -1
  24. lightning_sdk/job/v2.py +22 -2
  25. lightning_sdk/job/work.py +5 -1
  26. lightning_sdk/lightning_cloud/openapi/__init__.py +14 -1
  27. lightning_sdk/lightning_cloud/openapi/api/assistants_service_api.py +428 -0
  28. lightning_sdk/lightning_cloud/openapi/api/billing_service_api.py +153 -48
  29. lightning_sdk/lightning_cloud/openapi/api/cloudy_service_api.py +295 -0
  30. lightning_sdk/lightning_cloud/openapi/api/cluster_service_api.py +93 -0
  31. lightning_sdk/lightning_cloud/openapi/models/__init__.py +14 -1
  32. lightning_sdk/lightning_cloud/openapi/models/agentmanagedendpoints_id_body.py +27 -1
  33. lightning_sdk/lightning_cloud/openapi/models/blogposts_id_body.py +53 -1
  34. lightning_sdk/lightning_cloud/openapi/models/conversations_id_body1.py +123 -0
  35. lightning_sdk/lightning_cloud/openapi/models/messages_id_body.py +123 -0
  36. lightning_sdk/lightning_cloud/openapi/models/metricsstream_id_body.py +27 -1
  37. lightning_sdk/lightning_cloud/openapi/models/project_id_schedules_body.py +81 -3
  38. lightning_sdk/lightning_cloud/openapi/models/schedules_id_body.py +79 -1
  39. lightning_sdk/lightning_cloud/openapi/models/user_id_upgradetrigger_body.py +201 -0
  40. lightning_sdk/lightning_cloud/openapi/models/user_user_id_body.py +201 -0
  41. lightning_sdk/lightning_cloud/openapi/models/v1_billing_subscription.py +27 -1
  42. lightning_sdk/lightning_cloud/openapi/models/v1_blog_post.py +53 -1
  43. lightning_sdk/lightning_cloud/openapi/models/v1_cloudy_settings.py +227 -0
  44. lightning_sdk/lightning_cloud/openapi/models/v1_cluster_spec.py +27 -1
  45. lightning_sdk/lightning_cloud/openapi/models/v1_conversation.py +27 -1
  46. lightning_sdk/lightning_cloud/openapi/models/v1_conversation_response_chunk.py +27 -1
  47. lightning_sdk/lightning_cloud/openapi/models/v1_create_billing_upgrade_trigger_record_response.py +97 -0
  48. lightning_sdk/lightning_cloud/openapi/models/v1_create_blog_post_request.py +53 -1
  49. lightning_sdk/lightning_cloud/openapi/models/v1_create_checkout_session_request.py +27 -1
  50. lightning_sdk/lightning_cloud/openapi/models/v1_create_subscription_checkout_session_request.py +55 -3
  51. lightning_sdk/lightning_cloud/openapi/models/v1_function_call.py +149 -0
  52. lightning_sdk/lightning_cloud/openapi/models/{v1_get_clickhouse_assistant_session_daily_aggregated_response.py → v1_get_assistant_session_daily_aggregated_response.py} +22 -22
  53. lightning_sdk/lightning_cloud/openapi/models/v1_get_cluster_health_response.py +149 -0
  54. lightning_sdk/lightning_cloud/openapi/models/v1_get_user_response.py +27 -1
  55. lightning_sdk/lightning_cloud/openapi/models/v1_job_spec.py +27 -1
  56. lightning_sdk/lightning_cloud/openapi/models/v1_kubernetes_direct_v1.py +105 -1
  57. lightning_sdk/lightning_cloud/openapi/models/v1_like_status.py +104 -0
  58. lightning_sdk/lightning_cloud/openapi/models/v1_list_published_managed_endpoints_response.py +123 -0
  59. lightning_sdk/lightning_cloud/openapi/models/v1_managed_endpoint.py +27 -1
  60. lightning_sdk/lightning_cloud/openapi/models/v1_managed_model.py +95 -17
  61. lightning_sdk/lightning_cloud/openapi/models/v1_message.py +27 -1
  62. lightning_sdk/lightning_cloud/openapi/models/v1_quote_subscription_response.py +27 -1
  63. lightning_sdk/lightning_cloud/openapi/models/v1_resource_visibility.py +27 -1
  64. lightning_sdk/lightning_cloud/openapi/models/v1_response_choice.py +29 -3
  65. lightning_sdk/lightning_cloud/openapi/models/v1_schedule.py +79 -1
  66. lightning_sdk/lightning_cloud/openapi/models/v1_service_health.py +27 -1
  67. lightning_sdk/lightning_cloud/openapi/models/v1_slurm_v1.py +79 -1
  68. lightning_sdk/lightning_cloud/openapi/models/v1_slurm_v1_status.py +79 -1
  69. lightning_sdk/lightning_cloud/openapi/models/v1_tool_call.py +175 -0
  70. lightning_sdk/lightning_cloud/openapi/models/v1_update_conversation_like_response.py +149 -0
  71. lightning_sdk/lightning_cloud/openapi/models/v1_update_conversation_message_like_response.py +149 -0
  72. lightning_sdk/lightning_cloud/openapi/models/v1_user_features.py +79 -313
  73. lightning_sdk/lightning_cloud/openapi/models/v1_volume_state.py +1 -0
  74. lightning_sdk/llm/llm.py +69 -11
  75. lightning_sdk/llm/public_assistants.json +32 -8
  76. lightning_sdk/machine.py +151 -43
  77. lightning_sdk/mmt/base.py +20 -2
  78. lightning_sdk/mmt/mmt.py +25 -3
  79. lightning_sdk/mmt/v1.py +7 -1
  80. lightning_sdk/mmt/v2.py +27 -3
  81. lightning_sdk/models.py +1 -1
  82. lightning_sdk/organization.py +4 -0
  83. lightning_sdk/pipeline/pipeline.py +16 -5
  84. lightning_sdk/pipeline/printer.py +5 -3
  85. lightning_sdk/pipeline/schedule.py +844 -1
  86. lightning_sdk/pipeline/steps.py +19 -4
  87. lightning_sdk/sandbox.py +4 -1
  88. lightning_sdk/serve.py +2 -0
  89. lightning_sdk/studio.py +91 -44
  90. lightning_sdk/teamspace.py +19 -10
  91. lightning_sdk/utils/resolve.py +37 -2
  92. {lightning_sdk-2025.7.17.dist-info → lightning_sdk-2025.7.30rc0.dist-info}/METADATA +7 -5
  93. {lightning_sdk-2025.7.17.dist-info → lightning_sdk-2025.7.30rc0.dist-info}/RECORD +98 -85
  94. lightning_sdk/api/cluster_api.py +0 -119
  95. /lightning_sdk/cli/{inspect.py → inspection.py} +0 -0
  96. {lightning_sdk-2025.7.17.dist-info → lightning_sdk-2025.7.30rc0.dist-info}/LICENSE +0 -0
  97. {lightning_sdk-2025.7.17.dist-info → lightning_sdk-2025.7.30rc0.dist-info}/WHEEL +0 -0
  98. {lightning_sdk-2025.7.17.dist-info → lightning_sdk-2025.7.30rc0.dist-info}/entry_points.txt +0 -0
  99. {lightning_sdk-2025.7.17.dist-info → lightning_sdk-2025.7.30rc0.dist-info}/top_level.txt +0 -0
lightning_sdk/mmt/v1.py CHANGED
@@ -7,7 +7,7 @@ from lightning_sdk.job.work import Work
7
7
  from lightning_sdk.status import Status
8
8
 
9
9
  if TYPE_CHECKING:
10
- from lightning_sdk.machine import Machine
10
+ from lightning_sdk.machine import CloudProvider, Machine
11
11
  from lightning_sdk.organization import Organization
12
12
  from lightning_sdk.studio import Studio
13
13
  from lightning_sdk.teamspace import Teamspace
@@ -50,10 +50,12 @@ class _MMTV1(_BaseMMT):
50
50
  env: Optional[Dict[str, str]] = None,
51
51
  interruptible: bool = False,
52
52
  cloud_account: Optional[str] = None,
53
+ cloud_provider: Optional[Union["CloudProvider", str]] = None,
53
54
  image_credentials: Optional[str] = None,
54
55
  cloud_account_auth: bool = False,
55
56
  entrypoint: str = "sh -c",
56
57
  path_mappings: Optional[Dict[str, str]] = None,
58
+ max_runtime: Optional[int] = None,
57
59
  artifacts_local: Optional[str] = None,
58
60
  artifacts_remote: Optional[str] = None,
59
61
  ) -> "_MMTV1":
@@ -90,6 +92,10 @@ class _MMTV1(_BaseMMT):
90
92
  To use the pre-defined entrypoint of the provided image, set this to an empty string.
91
93
  Only applicable when submitting docker jobs.
92
94
  path_mappings: The mappings from data connection inside your container (not supported)
95
+ max_runtime: the duration (in seconds) for which to allocate the machine.
96
+ Irrelevant for most machines, required for some of the top-end machines on GCP.
97
+ If in doubt, set it. Won't have an effect on machines not requiring it.
98
+ Defaults to 3h
93
99
 
94
100
  """
95
101
  raise NotImplementedError("Cannot submit new mmts with MMTV1!")
lightning_sdk/mmt/v2.py CHANGED
@@ -3,10 +3,11 @@ from typing import TYPE_CHECKING, Dict, Optional, Tuple, Union
3
3
  from lightning_sdk.api.mmt_api import MMTApiV2
4
4
  from lightning_sdk.api.utils import _get_cloud_url
5
5
  from lightning_sdk.status import Status
6
+ from lightning_sdk.utils.resolve import _get_org_id
6
7
 
7
8
  if TYPE_CHECKING:
8
9
  from lightning_sdk.job.job import Job
9
- from lightning_sdk.machine import Machine
10
+ from lightning_sdk.machine import CloudProvider, Machine
10
11
  from lightning_sdk.organization import Organization
11
12
  from lightning_sdk.studio import Studio
12
13
  from lightning_sdk.teamspace import Teamspace
@@ -49,10 +50,12 @@ class _MMTV2(_BaseMMT):
49
50
  env: Optional[Dict[str, str]] = None,
50
51
  interruptible: bool = False,
51
52
  cloud_account: Optional[str] = None,
53
+ cloud_provider: Optional[Union["CloudProvider", str]] = None,
52
54
  image_credentials: Optional[str] = None,
53
55
  cloud_account_auth: bool = False,
54
56
  entrypoint: str = "sh -c",
55
57
  path_mappings: Optional[Dict[str, str]] = None,
58
+ max_runtime: Optional[int] = None,
56
59
  artifacts_local: Optional[str] = None, # deprecated in favor of path_mappings
57
60
  artifacts_remote: Optional[str] = None, # deprecated in favor of path_mappings
58
61
  ) -> "_MMTV2":
@@ -69,7 +72,11 @@ class _MMTV2(_BaseMMT):
69
72
  interruptible: Whether the job should run on interruptible instances. They are cheaper but can be preempted.
70
73
  cloud_account: The cloud account to run the job on.
71
74
  Defaults to the studio cloud account if running with studio compute env.
72
- If not provided will fall back to the teamspaces default cloud account.
75
+ If not provided and `cloud_account_provider` is set, will resolve cluster from this, else
76
+ will fall back to the teamspaces default cloud account.
77
+ cloud_account_provider: The provider to select the cloud-account from.
78
+ If set, must be in agreement with the provider from the cloud_account (if specified).
79
+ If not specified, falls backto the teamspace default cloud account.
73
80
  image_credentials: The credentials used to pull the image. Required if the image is private.
74
81
  This should be the name of the respective credentials secret created on the Lightning AI platform.
75
82
  cloud_account_auth: Whether to authenticate with the cloud account to pull the image.
@@ -87,6 +94,10 @@ class _MMTV2(_BaseMMT):
87
94
  }
88
95
  If the path inside the connection is omitted it's assumed to be the root path of that connection.
89
96
  Only applicable when submitting docker jobs.
97
+ max_runtime: the duration (in seconds) for which to allocate the machine.
98
+ Irrelevant for most machines, required for some of the top-end machines on GCP.
99
+ If in doubt, set it. Won't have an effect on machines not requiring it.
100
+ Defaults to 3h
90
101
  """
91
102
  # Command is required if Studio is provided to know what to run
92
103
  # Image is mutually exclusive with Studio
@@ -104,6 +115,14 @@ class _MMTV2(_BaseMMT):
104
115
  studio_id = None
105
116
  if image is None:
106
117
  raise ValueError("either image or studio must be provided")
118
+
119
+ cloud_account = self._cloud_account_api.resolve_cloud_account(
120
+ self._teamspace.id,
121
+ cloud_account=cloud_account,
122
+ cloud_provider=cloud_provider,
123
+ default_cloud_account=self._teamspace.default_cloud_account,
124
+ )
125
+
107
126
  submitted = self._job_api.submit_job(
108
127
  name=self.name,
109
128
  num_machines=num_machines,
@@ -121,6 +140,7 @@ class _MMTV2(_BaseMMT):
121
140
  path_mappings=path_mappings,
122
141
  artifacts_local=artifacts_local,
123
142
  artifacts_remote=artifacts_remote,
143
+ max_runtime=max_runtime,
124
144
  )
125
145
  self._job = submitted
126
146
  self._name = submitted.name
@@ -172,7 +192,11 @@ class _MMTV2(_BaseMMT):
172
192
  @property
173
193
  def machine(self) -> Union["Machine", str]:
174
194
  """Returns the machine type this job is running on."""
175
- return self._job_api._get_job_machine_from_spec(self._guaranteed_job.spec)
195
+ return self._job_api._get_job_machine_from_spec(
196
+ self._guaranteed_job.spec,
197
+ self.teamspace.id,
198
+ _get_org_id(self.teamspace),
199
+ )
176
200
 
177
201
  def _update_internal_job(self) -> None:
178
202
  if getattr(self, "_job", None) is None:
lightning_sdk/models.py CHANGED
@@ -127,7 +127,7 @@ def download_model(
127
127
  return api.download_model_files(
128
128
  name=model_name,
129
129
  version=version,
130
- download_dir=Path(download_dir),
130
+ download_dir=Path(download_dir).expanduser().resolve(),
131
131
  teamspace_name=teamspace_name,
132
132
  teamspace_owner_name=teamspace_owner_name,
133
133
  progress_bar=progress_bar,
@@ -40,6 +40,10 @@ class Organization(Owner):
40
40
  """The organization's ID."""
41
41
  return self._org.id
42
42
 
43
+ @property
44
+ def default_cloud_account(self) -> Optional[str]:
45
+ return self._org.preferred_cluster or None
46
+
43
47
  def __repr__(self) -> str:
44
48
  """Returns reader friendly representation."""
45
49
  return f"Organization(name={self.name})"
@@ -1,9 +1,12 @@
1
1
  import os
2
- from typing import TYPE_CHECKING, List, Optional, Union
2
+ from typing import List, Optional, Union
3
3
 
4
+ from lightning_sdk.api.cloud_account_api import CloudAccountApi
4
5
  from lightning_sdk.api.pipeline_api import PipelineApi
6
+ from lightning_sdk.machine import CloudProvider
5
7
  from lightning_sdk.organization import Organization
6
8
  from lightning_sdk.pipeline.printer import PipelinePrinter
9
+ from lightning_sdk.pipeline.schedule import _TIMEZONES, Schedule
7
10
  from lightning_sdk.pipeline.steps import DeploymentStep, JobStep, MMTStep, _get_studio
8
11
  from lightning_sdk.pipeline.utils import prepare_steps
9
12
  from lightning_sdk.services.utilities import _get_cluster
@@ -12,9 +15,6 @@ from lightning_sdk.teamspace import Teamspace
12
15
  from lightning_sdk.user import User
13
16
  from lightning_sdk.utils.resolve import _resolve_teamspace
14
17
 
15
- if TYPE_CHECKING:
16
- from lightning_sdk.pipeline.schedule import Schedule
17
-
18
18
 
19
19
  class Pipeline:
20
20
  def __init__(
@@ -24,6 +24,7 @@ class Pipeline:
24
24
  org: Union[str, "Organization", None] = None,
25
25
  user: Union[str, "User", None] = None,
26
26
  cloud_account: Optional[str] = None,
27
+ cloud_provider: Optional[Union[CloudProvider, str]] = None,
27
28
  shared_filesystem: Optional[bool] = None,
28
29
  studio: Optional[Union[Studio, str]] = None,
29
30
  ) -> None:
@@ -45,9 +46,14 @@ class Pipeline:
45
46
  org=org,
46
47
  user=user,
47
48
  )
49
+ if self._teamspace is None:
50
+ raise RuntimeError("Could not resolve teamspace")
48
51
 
49
52
  self._pipeline_api = PipelineApi()
50
- self._cloud_account = cloud_account
53
+ self._cloud_account_api = CloudAccountApi()
54
+ self._cloud_account = self._cloud_account_api.resolve_cloud_account(
55
+ self._teamspace.id, cloud_account, cloud_provider, self._teamspace.default_cloud_account
56
+ )
51
57
  self._default_cluster = _get_cluster(
52
58
  client=self._pipeline_api._client, project_id=self._teamspace.id, cluster_id=cloud_account
53
59
  )
@@ -108,6 +114,11 @@ class Pipeline:
108
114
  if schedule.name is None:
109
115
  schedule.name = f"schedule-{schedule_idx}"
110
116
 
117
+ if schedule.timezone is not None and schedule.timezone not in _TIMEZONES:
118
+ raise ValueError(
119
+ f"The schedule {schedule.name} timezone isn't supported. Available list is {_TIMEZONES}. Found {schedule.timezone}." # noqa: E501
120
+ )
121
+
111
122
  parent_pipeline_id = None if self._pipeline is None else self._pipeline.id
112
123
 
113
124
  self._pipeline = self._pipeline_api.create_pipeline(
@@ -1,7 +1,7 @@
1
1
  import os
2
2
  from typing import Any, ClassVar, Dict, List
3
3
 
4
- from lightning_sdk.lightning_cloud.openapi.models import V1Pipeline, V1PipelineStepType
4
+ from lightning_sdk.lightning_cloud.openapi.models import V1Pipeline, V1PipelineStepType, V1Schedule
5
5
  from lightning_sdk.pipeline.utils import _get_spec
6
6
 
7
7
 
@@ -21,7 +21,7 @@ class PipelinePrinter:
21
21
  pipeline: V1Pipeline,
22
22
  teamspace: Any,
23
23
  proto_steps: List[Any],
24
- schedules: List[Any],
24
+ schedules: List[V1Schedule],
25
25
  ) -> None:
26
26
  self._name = name
27
27
  self._initial = initial
@@ -78,7 +78,9 @@ class PipelinePrinter:
78
78
  return
79
79
 
80
80
  for schedule in self._schedules:
81
- self._print(f" - '{schedule.name}' runs on cron schedule: `{schedule.cron_expression}`")
81
+ self._print(
82
+ f" - '{schedule.name}' runs on cron schedule: `{schedule.cron_expression} in timezone {schedule.timezone or 'UTC'}`" # noqa: E501
83
+ )
82
84
 
83
85
  def _print_footer(self) -> None:
84
86
  """Prints the final link and closing message."""