lightning-sdk 0.1.49__py3-none-any.whl → 0.1.51__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- lightning_sdk/__init__.py +1 -1
- lightning_sdk/api/job_api.py +18 -13
- lightning_sdk/api/lit_container_api.py +41 -11
- lightning_sdk/api/mmt_api.py +18 -13
- lightning_sdk/api/utils.py +52 -0
- lightning_sdk/cli/download.py +20 -1
- lightning_sdk/cli/run.py +71 -21
- lightning_sdk/cli/serve.py +1 -5
- lightning_sdk/cli/upload.py +33 -15
- lightning_sdk/helpers.py +1 -1
- lightning_sdk/job/base.py +16 -5
- lightning_sdk/job/job.py +30 -27
- lightning_sdk/job/v1.py +9 -5
- lightning_sdk/job/v2.py +14 -14
- lightning_sdk/job/work.py +2 -2
- lightning_sdk/lightning_cloud/login.py +4 -1
- lightning_sdk/lightning_cloud/openapi/__init__.py +3 -0
- lightning_sdk/lightning_cloud/openapi/api/jobs_service_api.py +5 -1
- lightning_sdk/lightning_cloud/openapi/api/lit_registry_service_api.py +113 -0
- lightning_sdk/lightning_cloud/openapi/models/__init__.py +3 -0
- lightning_sdk/lightning_cloud/openapi/models/deployments_id_body.py +27 -1
- lightning_sdk/lightning_cloud/openapi/models/litregistry_lit_repo_name_body.py +123 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_cluster_spec.py +27 -1
- lightning_sdk/lightning_cloud/openapi/models/v1_deployment.py +27 -1
- lightning_sdk/lightning_cloud/openapi/models/v1_deployment_api.py +27 -1
- lightning_sdk/lightning_cloud/openapi/models/v1_job_spec.py +27 -1
- lightning_sdk/lightning_cloud/openapi/models/v1_path_mapping.py +175 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_update_lit_repository_response.py +97 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_user_features.py +79 -79
- lightning_sdk/lit_container.py +19 -0
- lightning_sdk/mmt/base.py +40 -30
- lightning_sdk/mmt/mmt.py +30 -26
- lightning_sdk/mmt/v1.py +6 -3
- lightning_sdk/mmt/v2.py +16 -15
- lightning_sdk/models.py +5 -4
- lightning_sdk/utils/resolve.py +7 -0
- {lightning_sdk-0.1.49.dist-info → lightning_sdk-0.1.51.dist-info}/METADATA +2 -2
- {lightning_sdk-0.1.49.dist-info → lightning_sdk-0.1.51.dist-info}/RECORD +42 -39
- {lightning_sdk-0.1.49.dist-info → lightning_sdk-0.1.51.dist-info}/LICENSE +0 -0
- {lightning_sdk-0.1.49.dist-info → lightning_sdk-0.1.51.dist-info}/WHEEL +0 -0
- {lightning_sdk-0.1.49.dist-info → lightning_sdk-0.1.51.dist-info}/entry_points.txt +0 -0
- {lightning_sdk-0.1.49.dist-info → lightning_sdk-0.1.51.dist-info}/top_level.txt +0 -0
lightning_sdk/job/base.py
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
+
import warnings
|
|
1
2
|
from abc import ABC, abstractmethod
|
|
2
3
|
from typing import TYPE_CHECKING, Any, Dict, Optional, TypedDict, Union
|
|
3
4
|
|
|
4
5
|
from lightning_sdk.api.utils import _get_cloud_url
|
|
5
|
-
from lightning_sdk.utils.resolve import _resolve_deprecated_cluster, _resolve_teamspace
|
|
6
|
+
from lightning_sdk.utils.resolve import _resolve_deprecated_cluster, _resolve_teamspace, in_studio
|
|
6
7
|
|
|
7
8
|
if TYPE_CHECKING:
|
|
8
9
|
from lightning_sdk.machine import Machine
|
|
@@ -16,7 +17,7 @@ if TYPE_CHECKING:
|
|
|
16
17
|
class MachineDict(TypedDict):
|
|
17
18
|
name: str
|
|
18
19
|
status: "Status"
|
|
19
|
-
machine: "Machine"
|
|
20
|
+
machine: Union["Machine", str]
|
|
20
21
|
|
|
21
22
|
|
|
22
23
|
class JobDict(MachineDict):
|
|
@@ -68,7 +69,7 @@ class _BaseJob(ABC):
|
|
|
68
69
|
def run(
|
|
69
70
|
cls,
|
|
70
71
|
name: str,
|
|
71
|
-
machine: "Machine",
|
|
72
|
+
machine: Union["Machine", str],
|
|
72
73
|
command: Optional[str] = None,
|
|
73
74
|
studio: Union["Studio", str, None] = None,
|
|
74
75
|
image: Optional[str] = None,
|
|
@@ -83,6 +84,7 @@ class _BaseJob(ABC):
|
|
|
83
84
|
artifacts_local: Optional[str] = None,
|
|
84
85
|
artifacts_remote: Optional[str] = None,
|
|
85
86
|
entrypoint: str = "sh -c",
|
|
87
|
+
path_mappings: Optional[Dict[str, str]] = None,
|
|
86
88
|
cluster: Optional[str] = None, # deprecated in favor of cloud_account
|
|
87
89
|
) -> "_BaseJob":
|
|
88
90
|
"""Run async workloads using a docker image or a compute environment from your studio.
|
|
@@ -121,6 +123,7 @@ class _BaseJob(ABC):
|
|
|
121
123
|
To use the pre-defined entrypoint of the provided image, set this to an empty string.
|
|
122
124
|
Only applicable when submitting docker jobs.
|
|
123
125
|
"""
|
|
126
|
+
from lightning_sdk.lightning_cloud.openapi.rest import ApiException
|
|
124
127
|
from lightning_sdk.studio import Studio
|
|
125
128
|
|
|
126
129
|
cloud_account = _resolve_deprecated_cluster(cloud_account, cluster)
|
|
@@ -175,6 +178,12 @@ class _BaseJob(ABC):
|
|
|
175
178
|
raise RuntimeError(
|
|
176
179
|
"image and studio are mutually exclusive as both define the environment to run the job in"
|
|
177
180
|
)
|
|
181
|
+
if cloud_account is None and in_studio():
|
|
182
|
+
try:
|
|
183
|
+
resolve_studio = Studio(teamspace=teamspace, user=user, org=org)
|
|
184
|
+
cloud_account = resolve_studio.cloud_account
|
|
185
|
+
except (ValueError, ApiException):
|
|
186
|
+
warnings.warn("Could not infer cloud account from studio. Using teamspace default.")
|
|
178
187
|
|
|
179
188
|
# they either need to specified both or none of them
|
|
180
189
|
if bool(artifacts_local) != bool(artifacts_remote):
|
|
@@ -200,12 +209,13 @@ class _BaseJob(ABC):
|
|
|
200
209
|
artifacts_local=artifacts_local,
|
|
201
210
|
artifacts_remote=artifacts_remote,
|
|
202
211
|
entrypoint=entrypoint,
|
|
212
|
+
path_mappings=path_mappings,
|
|
203
213
|
)
|
|
204
214
|
|
|
205
215
|
@abstractmethod
|
|
206
216
|
def _submit(
|
|
207
217
|
self,
|
|
208
|
-
machine: "Machine",
|
|
218
|
+
machine: Union["Machine", str],
|
|
209
219
|
command: Optional[str] = None,
|
|
210
220
|
studio: Optional["Studio"] = None,
|
|
211
221
|
image: Optional[str] = None,
|
|
@@ -217,6 +227,7 @@ class _BaseJob(ABC):
|
|
|
217
227
|
artifacts_local: Optional[str] = None,
|
|
218
228
|
artifacts_remote: Optional[str] = None,
|
|
219
229
|
entrypoint: str = "sh -c",
|
|
230
|
+
path_mappings: Optional[Dict[str, str]] = None,
|
|
220
231
|
) -> "_BaseJob":
|
|
221
232
|
"""Submit a new job to the Lightning AI platform.
|
|
222
233
|
|
|
@@ -271,7 +282,7 @@ class _BaseJob(ABC):
|
|
|
271
282
|
|
|
272
283
|
@property
|
|
273
284
|
@abstractmethod
|
|
274
|
-
def machine(self) -> "Machine":
|
|
285
|
+
def machine(self) -> Union["Machine", str]:
|
|
275
286
|
"""The machine type the job is running on."""
|
|
276
287
|
|
|
277
288
|
@property
|
lightning_sdk/job/job.py
CHANGED
|
@@ -89,7 +89,7 @@ class Job(_BaseJob):
|
|
|
89
89
|
def run(
|
|
90
90
|
cls,
|
|
91
91
|
name: str,
|
|
92
|
-
machine: "Machine",
|
|
92
|
+
machine: Union["Machine", str],
|
|
93
93
|
command: Optional[str] = None,
|
|
94
94
|
studio: Union["Studio", str, None] = None,
|
|
95
95
|
image: Union[str, None] = None,
|
|
@@ -101,9 +101,10 @@ class Job(_BaseJob):
|
|
|
101
101
|
interruptible: bool = False,
|
|
102
102
|
image_credentials: Optional[str] = None,
|
|
103
103
|
cloud_account_auth: bool = False,
|
|
104
|
-
artifacts_local: Optional[str] = None,
|
|
105
|
-
artifacts_remote: Optional[str] = None,
|
|
106
104
|
entrypoint: str = "sh -c",
|
|
105
|
+
path_mappings: Optional[Dict[str, str]] = None,
|
|
106
|
+
artifacts_local: Optional[str] = None, # deprecated in terms of path_mappings
|
|
107
|
+
artifacts_remote: Optional[str] = None, # deprecated in terms of path_mappings
|
|
107
108
|
cluster: Optional[str] = None, # deprecated in favor of cloud_account
|
|
108
109
|
) -> "Job":
|
|
109
110
|
"""Run async workloads using a docker image or a compute environment from your studio.
|
|
@@ -127,20 +128,19 @@ class Job(_BaseJob):
|
|
|
127
128
|
This should be the name of the respective credentials secret created on the Lightning AI platform.
|
|
128
129
|
cloud_account_auth: Whether to authenticate with the cloud account to pull the image.
|
|
129
130
|
Required if the registry is part of a cloud provider (e.g. ECR).
|
|
130
|
-
artifacts_local: The path of inside the docker container, you want to persist images from.
|
|
131
|
-
CAUTION: When setting this to "/", it will effectively erase your container.
|
|
132
|
-
Only supported for jobs with a docker image compute environment.
|
|
133
|
-
artifacts_remote: The remote storage to persist your artifacts to.
|
|
134
|
-
Should be of format <CONNECTION_TYPE>:<CONNECTION_NAME>:<PATH_WITHIN_CONNECTION>.
|
|
135
|
-
PATH_WITHIN_CONNECTION hereby is a path relative to the connection's root.
|
|
136
|
-
E.g. efs:data:some-path would result in an EFS connection named `data` and to the path `some-path`
|
|
137
|
-
within it.
|
|
138
|
-
Note that the connection needs to be added to the teamspace already in order for it to be found.
|
|
139
|
-
Only supported for jobs with a docker image compute environment.
|
|
140
131
|
entrypoint: The entrypoint of your docker container. Defaults to `sh -c` which
|
|
141
132
|
just runs the provided command in a standard shell.
|
|
142
133
|
To use the pre-defined entrypoint of the provided image, set this to an empty string.
|
|
143
134
|
Only applicable when submitting docker jobs.
|
|
135
|
+
path_mappings: Dictionary of path mappings. The keys are the path inside the container whereas the value
|
|
136
|
+
represents the data-connection name and the path inside that connection.
|
|
137
|
+
Should be of form
|
|
138
|
+
{
|
|
139
|
+
"<CONTAINER_PATH_1>": "<CONNECTION_NAME_1>:<PATH_WITHIN_CONNECTION_1>",
|
|
140
|
+
"<CONTAINER_PATH_2>": "<CONNECTION_NAME_2>"
|
|
141
|
+
}
|
|
142
|
+
If the path inside the connection is omitted it's assumed to be the root path of that connection.
|
|
143
|
+
Only applicable when submitting docker jobs.
|
|
144
144
|
"""
|
|
145
145
|
ret_val = super().run(
|
|
146
146
|
name=name,
|
|
@@ -159,6 +159,7 @@ class Job(_BaseJob):
|
|
|
159
159
|
artifacts_local=artifacts_local,
|
|
160
160
|
artifacts_remote=artifacts_remote,
|
|
161
161
|
entrypoint=entrypoint,
|
|
162
|
+
path_mappings=path_mappings,
|
|
162
163
|
cluster=cluster,
|
|
163
164
|
)
|
|
164
165
|
# required for typing with "Job"
|
|
@@ -169,7 +170,7 @@ class Job(_BaseJob):
|
|
|
169
170
|
|
|
170
171
|
def _submit(
|
|
171
172
|
self,
|
|
172
|
-
machine: "Machine",
|
|
173
|
+
machine: Union["Machine", str],
|
|
173
174
|
command: Optional[str] = None,
|
|
174
175
|
studio: Optional["Studio"] = None,
|
|
175
176
|
image: Optional[str] = None,
|
|
@@ -178,9 +179,10 @@ class Job(_BaseJob):
|
|
|
178
179
|
cloud_account: Optional[str] = None,
|
|
179
180
|
image_credentials: Optional[str] = None,
|
|
180
181
|
cloud_account_auth: bool = False,
|
|
181
|
-
artifacts_local: Optional[str] = None,
|
|
182
|
-
artifacts_remote: Optional[str] = None,
|
|
183
182
|
entrypoint: str = "sh -c",
|
|
183
|
+
path_mappings: Optional[Dict[str, str]] = None,
|
|
184
|
+
artifacts_local: Optional[str] = None, # deprecated in terms of path_mappings
|
|
185
|
+
artifacts_remote: Optional[str] = None, # deprecated in terms of path_mappings
|
|
184
186
|
) -> "Job":
|
|
185
187
|
"""Submit a new job to the Lightning AI platform.
|
|
186
188
|
|
|
@@ -199,19 +201,18 @@ class Job(_BaseJob):
|
|
|
199
201
|
This should be the name of the respective credentials secret created on the Lightning AI platform.
|
|
200
202
|
cloud_account_auth: Whether to authenticate with the cloud account to pull the image.
|
|
201
203
|
Required if the registry is part of a cloud provider (e.g. ECR).
|
|
202
|
-
artifacts_local: The path of inside the docker container, you want to persist images from.
|
|
203
|
-
CAUTION: When setting this to "/", it will effectively erase your container.
|
|
204
|
-
Only supported for jobs with a docker image compute environment.
|
|
205
|
-
artifacts_remote: The remote storage to persist your artifacts to.
|
|
206
|
-
Should be of format <CONNECTION_TYPE>:<CONNECTION_NAME>:<PATH_WITHIN_CONNECTION>.
|
|
207
|
-
PATH_WITHIN_CONNECTION hereby is a path relative to the connection's root.
|
|
208
|
-
E.g. efs:data:some-path would result in an EFS connection named `data` and to the path `some-path`
|
|
209
|
-
within it.
|
|
210
|
-
Note that the connection needs to be added to the teamspace already in order for it to be found.
|
|
211
|
-
Only supported for jobs with a docker image compute environment.
|
|
212
204
|
entrypoint: The entrypoint of your docker container. Defaults to sh -c.
|
|
213
205
|
To use the pre-defined entrypoint of the provided image, set this to an empty string.
|
|
214
206
|
Only applicable when submitting docker jobs.
|
|
207
|
+
path_mappings: Dictionary of path mappings. The keys are the path inside the container whereas the value
|
|
208
|
+
represents the data-connection name and the path inside that connection.
|
|
209
|
+
Should be of form
|
|
210
|
+
{
|
|
211
|
+
"<CONTAINER_PATH_1>": "<CONNECTION_NAME_1>:<PATH_WITHIN_CONNECTION_1>",
|
|
212
|
+
"<CONTAINER_PATH_2>": "<CONNECTION_NAME_2>"
|
|
213
|
+
}
|
|
214
|
+
If the path inside the connection is omitted it's assumed to be the root path of that connection.
|
|
215
|
+
Only applicable when submitting docker jobs.
|
|
215
216
|
"""
|
|
216
217
|
self._job = self._internal_job._submit(
|
|
217
218
|
machine=machine,
|
|
@@ -223,6 +224,8 @@ class Job(_BaseJob):
|
|
|
223
224
|
interruptible=interruptible,
|
|
224
225
|
image_credentials=image_credentials,
|
|
225
226
|
cloud_account_auth=cloud_account_auth,
|
|
227
|
+
entrypoint=entrypoint,
|
|
228
|
+
path_mappings=path_mappings,
|
|
226
229
|
artifacts_local=artifacts_local,
|
|
227
230
|
artifacts_remote=artifacts_remote,
|
|
228
231
|
)
|
|
@@ -248,7 +251,7 @@ class Job(_BaseJob):
|
|
|
248
251
|
return self._internal_job.status
|
|
249
252
|
|
|
250
253
|
@property
|
|
251
|
-
def machine(self) -> "Machine":
|
|
254
|
+
def machine(self) -> Union["Machine", str]:
|
|
252
255
|
"""The machine type the job is running on."""
|
|
253
256
|
return self._internal_job.machine
|
|
254
257
|
|
lightning_sdk/job/v1.py
CHANGED
|
@@ -44,7 +44,7 @@ class _JobV1(_BaseJob):
|
|
|
44
44
|
def run(
|
|
45
45
|
cls,
|
|
46
46
|
name: str,
|
|
47
|
-
machine: "Machine",
|
|
47
|
+
machine: Union["Machine", str],
|
|
48
48
|
command: str,
|
|
49
49
|
studio: "Studio",
|
|
50
50
|
teamspace: Union[str, "Teamspace", None] = None,
|
|
@@ -85,11 +85,12 @@ class _JobV1(_BaseJob):
|
|
|
85
85
|
image_credentials=None,
|
|
86
86
|
cloud_account_auth=False,
|
|
87
87
|
cluster=cluster,
|
|
88
|
+
path_mappings=None,
|
|
88
89
|
)
|
|
89
90
|
|
|
90
91
|
def _submit(
|
|
91
92
|
self,
|
|
92
|
-
machine: "Machine",
|
|
93
|
+
machine: Union["Machine", str],
|
|
93
94
|
command: Optional[str] = None,
|
|
94
95
|
studio: Optional["Studio"] = None,
|
|
95
96
|
image: Optional[str] = None,
|
|
@@ -101,6 +102,7 @@ class _JobV1(_BaseJob):
|
|
|
101
102
|
artifacts_local: Optional[str] = None,
|
|
102
103
|
artifacts_remote: Optional[str] = None,
|
|
103
104
|
entrypoint: str = "sh -c",
|
|
105
|
+
path_mappings: Optional[Dict[str, str]] = None,
|
|
104
106
|
) -> "_JobV1":
|
|
105
107
|
"""Submit a job to run on a machine.
|
|
106
108
|
|
|
@@ -114,12 +116,11 @@ class _JobV1(_BaseJob):
|
|
|
114
116
|
cloud_account: The cloud account to run the job on.
|
|
115
117
|
image_credentials: The image credentials for the job (not supported).
|
|
116
118
|
cloud_account_auth: Whether to use cloud account authentication for the job (not supported).
|
|
117
|
-
artifacts_local: The local path for persisting artifacts (not supported).
|
|
118
|
-
artifacts_remote: The remote path for persisting artifacts (not supported).
|
|
119
119
|
entrypoint: The entrypoint of your docker container (not supported).
|
|
120
120
|
Defaults to `sh -c` which just runs the provided command in a standard shell.
|
|
121
121
|
To use the pre-defined entrypoint of the provided image, set this to an empty string.
|
|
122
122
|
Only applicable when submitting docker jobs.
|
|
123
|
+
path_mappings: The mappings from data connection inside your container (not supported)
|
|
123
124
|
|
|
124
125
|
Returns:
|
|
125
126
|
The submitted job.
|
|
@@ -141,6 +142,9 @@ class _JobV1(_BaseJob):
|
|
|
141
142
|
if entrypoint != "sh -c":
|
|
142
143
|
raise ValueError("Specifying the entrypoint is not yet supported with jobs")
|
|
143
144
|
|
|
145
|
+
if path_mappings is not None:
|
|
146
|
+
raise ValueError("Specifying path mappings is not yet supported with jobs")
|
|
147
|
+
|
|
144
148
|
# TODO: add support for empty names (will give an empty string)
|
|
145
149
|
_submitted = self._job_api.submit_job(
|
|
146
150
|
name=self._name,
|
|
@@ -195,7 +199,7 @@ class _JobV1(_BaseJob):
|
|
|
195
199
|
return Work(_work[0].id, self, self.teamspace)
|
|
196
200
|
|
|
197
201
|
@property
|
|
198
|
-
def machine(self) -> "Machine":
|
|
202
|
+
def machine(self) -> Union["Machine", str]:
|
|
199
203
|
"""Get the machine the job is running on."""
|
|
200
204
|
return self.work.machine
|
|
201
205
|
|
lightning_sdk/job/v2.py
CHANGED
|
@@ -37,7 +37,7 @@ class _JobV2(_BaseJob):
|
|
|
37
37
|
|
|
38
38
|
def _submit(
|
|
39
39
|
self,
|
|
40
|
-
machine: "Machine",
|
|
40
|
+
machine: Union["Machine", str],
|
|
41
41
|
command: Optional[str] = None,
|
|
42
42
|
studio: Optional["Studio"] = None,
|
|
43
43
|
image: Optional[str] = None,
|
|
@@ -46,9 +46,10 @@ class _JobV2(_BaseJob):
|
|
|
46
46
|
cloud_account: Optional[str] = None,
|
|
47
47
|
image_credentials: Optional[str] = None,
|
|
48
48
|
cloud_account_auth: bool = False,
|
|
49
|
-
artifacts_local: Optional[str] = None,
|
|
50
|
-
artifacts_remote: Optional[str] = None,
|
|
51
49
|
entrypoint: str = "sh -c",
|
|
50
|
+
path_mappings: Optional[Dict[str, str]] = None,
|
|
51
|
+
artifacts_local: Optional[str] = None, # deprecated in favor of path_mappings
|
|
52
|
+
artifacts_remote: Optional[str] = None, # deprecated in favor of path_mappings
|
|
52
53
|
) -> "_JobV2":
|
|
53
54
|
"""Submit a new job to the Lightning AI platform.
|
|
54
55
|
|
|
@@ -70,16 +71,14 @@ class _JobV2(_BaseJob):
|
|
|
70
71
|
artifacts_local: The path of inside the docker container, you want to persist images from.
|
|
71
72
|
CAUTION: When setting this to "/", it will effectively erase your container.
|
|
72
73
|
Only supported for jobs with a docker image compute environment.
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
just runs the provided command in a standard shell.
|
|
82
|
-
To use the pre-defined entrypoint of the provided image, set this to an empty string.
|
|
74
|
+
path_mappings: Dictionary of path mappings. The keys are the path inside the container whereas the value
|
|
75
|
+
represents the data-connection name and the path inside that connection.
|
|
76
|
+
Should be of form
|
|
77
|
+
{
|
|
78
|
+
"<CONTAINER_PATH_1>": "<CONNECTION_NAME_1>:<PATH_WITHIN_CONNECTION_1>",
|
|
79
|
+
"<CONTAINER_PATH_2>": "<CONNECTION_NAME_2>"
|
|
80
|
+
}
|
|
81
|
+
If the path inside the connection is omitted it's assumed to be the root path of that connection.
|
|
83
82
|
Only applicable when submitting docker jobs.
|
|
84
83
|
"""
|
|
85
84
|
# Command is required if Studio is provided to know what to run
|
|
@@ -114,6 +113,7 @@ class _JobV2(_BaseJob):
|
|
|
114
113
|
artifacts_local=artifacts_local,
|
|
115
114
|
artifacts_remote=artifacts_remote,
|
|
116
115
|
entrypoint=entrypoint,
|
|
116
|
+
path_mappings=path_mappings,
|
|
117
117
|
)
|
|
118
118
|
self._job = submitted
|
|
119
119
|
self._name = submitted.name
|
|
@@ -143,7 +143,7 @@ class _JobV2(_BaseJob):
|
|
|
143
143
|
return self._job_api._job_state_to_external(self._latest_job.state)
|
|
144
144
|
|
|
145
145
|
@property
|
|
146
|
-
def machine(self) -> "Machine":
|
|
146
|
+
def machine(self) -> Union["Machine", str]:
|
|
147
147
|
"""The machine type the job is running on."""
|
|
148
148
|
# only fetch the job it it hasn't been fetched yet as machine cannot change over time
|
|
149
149
|
return self._job_api._get_job_machine_from_spec(self._guaranteed_job.spec)
|
lightning_sdk/job/work.py
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from typing import TYPE_CHECKING, Any, Optional, Protocol
|
|
1
|
+
from typing import TYPE_CHECKING, Any, Optional, Protocol, Union
|
|
2
2
|
|
|
3
3
|
from lightning_sdk.api.job_api import JobApiV1
|
|
4
4
|
|
|
@@ -51,7 +51,7 @@ class Work:
|
|
|
51
51
|
return self._job._name_filter(self._guaranteed_work.name)
|
|
52
52
|
|
|
53
53
|
@property
|
|
54
|
-
def machine(self) -> "Machine":
|
|
54
|
+
def machine(self) -> Union["Machine", str]:
|
|
55
55
|
return self._job_api.get_machine_from_work(self._guaranteed_work)
|
|
56
56
|
|
|
57
57
|
@property
|
|
@@ -168,7 +168,10 @@ class AuthServer:
|
|
|
168
168
|
ok = webbrowser.open(url)
|
|
169
169
|
if not ok:
|
|
170
170
|
# can't open a browser, authentication failed
|
|
171
|
-
|
|
171
|
+
deployment_id = os.environ.get("LIGHTNING_DEPLOYMENT_ID", None)
|
|
172
|
+
if deployment_id is not None and deployment_id != "":
|
|
173
|
+
raise RuntimeError("Failed to authenticate to Lightning. Ensure that you have selected 'Include SDK credentials' in the 'Environment' section of the deployment settings.")
|
|
174
|
+
raise RuntimeError("Failed to authenticate to Lightning. When running without access to a browser, 'LIGHTNING_USER_ID' and 'LIGHTNING_API_KEY' should be exported.")
|
|
172
175
|
|
|
173
176
|
@app.get("/login-complete")
|
|
174
177
|
async def save_token(request: Request,
|
|
@@ -133,6 +133,7 @@ from lightning_sdk.lightning_cloud.openapi.models.jobs_id_body2 import JobsIdBod
|
|
|
133
133
|
from lightning_sdk.lightning_cloud.openapi.models.jobs_id_body3 import JobsIdBody3
|
|
134
134
|
from lightning_sdk.lightning_cloud.openapi.models.litloggermetrics_id_body import LitloggermetricsIdBody
|
|
135
135
|
from lightning_sdk.lightning_cloud.openapi.models.litpages_id_body import LitpagesIdBody
|
|
136
|
+
from lightning_sdk.lightning_cloud.openapi.models.litregistry_lit_repo_name_body import LitregistryLitRepoNameBody
|
|
136
137
|
from lightning_sdk.lightning_cloud.openapi.models.loggermetrics_id_body import LoggermetricsIdBody
|
|
137
138
|
from lightning_sdk.lightning_cloud.openapi.models.metrics_stream_id_loggerartifacts_body import MetricsStreamIdLoggerartifactsBody
|
|
138
139
|
from lightning_sdk.lightning_cloud.openapi.models.metricsstream_create_body import MetricsstreamCreateBody
|
|
@@ -646,6 +647,7 @@ from lightning_sdk.lightning_cloud.openapi.models.v1_organization import V1Organ
|
|
|
646
647
|
from lightning_sdk.lightning_cloud.openapi.models.v1_owner_type import V1OwnerType
|
|
647
648
|
from lightning_sdk.lightning_cloud.openapi.models.v1_package_manager import V1PackageManager
|
|
648
649
|
from lightning_sdk.lightning_cloud.openapi.models.v1_parameterization_spec import V1ParameterizationSpec
|
|
650
|
+
from lightning_sdk.lightning_cloud.openapi.models.v1_path_mapping import V1PathMapping
|
|
649
651
|
from lightning_sdk.lightning_cloud.openapi.models.v1_path_telemetry import V1PathTelemetry
|
|
650
652
|
from lightning_sdk.lightning_cloud.openapi.models.v1_phase_type import V1PhaseType
|
|
651
653
|
from lightning_sdk.lightning_cloud.openapi.models.v1_plugin import V1Plugin
|
|
@@ -753,6 +755,7 @@ from lightning_sdk.lightning_cloud.openapi.models.v1_update_cluster_accelerators
|
|
|
753
755
|
from lightning_sdk.lightning_cloud.openapi.models.v1_update_cluster_availability_request import V1UpdateClusterAvailabilityRequest
|
|
754
756
|
from lightning_sdk.lightning_cloud.openapi.models.v1_update_index_response import V1UpdateIndexResponse
|
|
755
757
|
from lightning_sdk.lightning_cloud.openapi.models.v1_update_lit_page_response import V1UpdateLitPageResponse
|
|
758
|
+
from lightning_sdk.lightning_cloud.openapi.models.v1_update_lit_repository_response import V1UpdateLitRepositoryResponse
|
|
756
759
|
from lightning_sdk.lightning_cloud.openapi.models.v1_update_metrics_stream_visibility_response import V1UpdateMetricsStreamVisibilityResponse
|
|
757
760
|
from lightning_sdk.lightning_cloud.openapi.models.v1_update_model_visibility_response import V1UpdateModelVisibilityResponse
|
|
758
761
|
from lightning_sdk.lightning_cloud.openapi.models.v1_update_project_cluster_accelerators_response import V1UpdateProjectClusterAcceleratorsResponse
|
|
@@ -992,6 +992,7 @@ class JobsServiceApi(object):
|
|
|
992
992
|
:param str project_id: (required)
|
|
993
993
|
:param str id: (required)
|
|
994
994
|
:param str cloudspace_id:
|
|
995
|
+
:param str deployment_id:
|
|
995
996
|
:return: V1DownloadJobLogsResponse
|
|
996
997
|
If the method is called asynchronously,
|
|
997
998
|
returns the request thread.
|
|
@@ -1015,12 +1016,13 @@ class JobsServiceApi(object):
|
|
|
1015
1016
|
:param str project_id: (required)
|
|
1016
1017
|
:param str id: (required)
|
|
1017
1018
|
:param str cloudspace_id:
|
|
1019
|
+
:param str deployment_id:
|
|
1018
1020
|
:return: V1DownloadJobLogsResponse
|
|
1019
1021
|
If the method is called asynchronously,
|
|
1020
1022
|
returns the request thread.
|
|
1021
1023
|
"""
|
|
1022
1024
|
|
|
1023
|
-
all_params = ['project_id', 'id', 'cloudspace_id'] # noqa: E501
|
|
1025
|
+
all_params = ['project_id', 'id', 'cloudspace_id', 'deployment_id'] # noqa: E501
|
|
1024
1026
|
all_params.append('async_req')
|
|
1025
1027
|
all_params.append('_return_http_data_only')
|
|
1026
1028
|
all_params.append('_preload_content')
|
|
@@ -1055,6 +1057,8 @@ class JobsServiceApi(object):
|
|
|
1055
1057
|
query_params = []
|
|
1056
1058
|
if 'cloudspace_id' in params:
|
|
1057
1059
|
query_params.append(('cloudspaceId', params['cloudspace_id'])) # noqa: E501
|
|
1060
|
+
if 'deployment_id' in params:
|
|
1061
|
+
query_params.append(('deploymentId', params['deployment_id'])) # noqa: E501
|
|
1058
1062
|
|
|
1059
1063
|
header_params = {}
|
|
1060
1064
|
|
|
@@ -442,3 +442,116 @@ class LitRegistryServiceApi(object):
|
|
|
442
442
|
_preload_content=params.get('_preload_content', True),
|
|
443
443
|
_request_timeout=params.get('_request_timeout'),
|
|
444
444
|
collection_formats=collection_formats)
|
|
445
|
+
|
|
446
|
+
def lit_registry_service_update_lit_repository_metadata(self, body: 'LitregistryLitRepoNameBody', project_id: 'str', lit_repo_name: 'str', **kwargs) -> 'V1UpdateLitRepositoryResponse': # noqa: E501
|
|
447
|
+
"""lit_registry_service_update_lit_repository_metadata # noqa: E501
|
|
448
|
+
|
|
449
|
+
This method makes a synchronous HTTP request by default. To make an
|
|
450
|
+
asynchronous HTTP request, please pass async_req=True
|
|
451
|
+
>>> thread = api.lit_registry_service_update_lit_repository_metadata(body, project_id, lit_repo_name, async_req=True)
|
|
452
|
+
>>> result = thread.get()
|
|
453
|
+
|
|
454
|
+
:param async_req bool
|
|
455
|
+
:param LitregistryLitRepoNameBody body: (required)
|
|
456
|
+
:param str project_id: (required)
|
|
457
|
+
:param str lit_repo_name: (required)
|
|
458
|
+
:return: V1UpdateLitRepositoryResponse
|
|
459
|
+
If the method is called asynchronously,
|
|
460
|
+
returns the request thread.
|
|
461
|
+
"""
|
|
462
|
+
kwargs['_return_http_data_only'] = True
|
|
463
|
+
if kwargs.get('async_req'):
|
|
464
|
+
return self.lit_registry_service_update_lit_repository_metadata_with_http_info(body, project_id, lit_repo_name, **kwargs) # noqa: E501
|
|
465
|
+
else:
|
|
466
|
+
(data) = self.lit_registry_service_update_lit_repository_metadata_with_http_info(body, project_id, lit_repo_name, **kwargs) # noqa: E501
|
|
467
|
+
return data
|
|
468
|
+
|
|
469
|
+
def lit_registry_service_update_lit_repository_metadata_with_http_info(self, body: 'LitregistryLitRepoNameBody', project_id: 'str', lit_repo_name: 'str', **kwargs) -> 'V1UpdateLitRepositoryResponse': # noqa: E501
|
|
470
|
+
"""lit_registry_service_update_lit_repository_metadata # noqa: E501
|
|
471
|
+
|
|
472
|
+
This method makes a synchronous HTTP request by default. To make an
|
|
473
|
+
asynchronous HTTP request, please pass async_req=True
|
|
474
|
+
>>> thread = api.lit_registry_service_update_lit_repository_metadata_with_http_info(body, project_id, lit_repo_name, async_req=True)
|
|
475
|
+
>>> result = thread.get()
|
|
476
|
+
|
|
477
|
+
:param async_req bool
|
|
478
|
+
:param LitregistryLitRepoNameBody body: (required)
|
|
479
|
+
:param str project_id: (required)
|
|
480
|
+
:param str lit_repo_name: (required)
|
|
481
|
+
:return: V1UpdateLitRepositoryResponse
|
|
482
|
+
If the method is called asynchronously,
|
|
483
|
+
returns the request thread.
|
|
484
|
+
"""
|
|
485
|
+
|
|
486
|
+
all_params = ['body', 'project_id', 'lit_repo_name'] # noqa: E501
|
|
487
|
+
all_params.append('async_req')
|
|
488
|
+
all_params.append('_return_http_data_only')
|
|
489
|
+
all_params.append('_preload_content')
|
|
490
|
+
all_params.append('_request_timeout')
|
|
491
|
+
|
|
492
|
+
params = locals()
|
|
493
|
+
for key, val in six.iteritems(params['kwargs']):
|
|
494
|
+
if key not in all_params:
|
|
495
|
+
raise TypeError(
|
|
496
|
+
"Got an unexpected keyword argument '%s'"
|
|
497
|
+
" to method lit_registry_service_update_lit_repository_metadata" % key
|
|
498
|
+
)
|
|
499
|
+
params[key] = val
|
|
500
|
+
del params['kwargs']
|
|
501
|
+
# verify the required parameter 'body' is set
|
|
502
|
+
if ('body' not in params or
|
|
503
|
+
params['body'] is None):
|
|
504
|
+
raise ValueError("Missing the required parameter `body` when calling `lit_registry_service_update_lit_repository_metadata`") # noqa: E501
|
|
505
|
+
# verify the required parameter 'project_id' is set
|
|
506
|
+
if ('project_id' not in params or
|
|
507
|
+
params['project_id'] is None):
|
|
508
|
+
raise ValueError("Missing the required parameter `project_id` when calling `lit_registry_service_update_lit_repository_metadata`") # noqa: E501
|
|
509
|
+
# verify the required parameter 'lit_repo_name' is set
|
|
510
|
+
if ('lit_repo_name' not in params or
|
|
511
|
+
params['lit_repo_name'] is None):
|
|
512
|
+
raise ValueError("Missing the required parameter `lit_repo_name` when calling `lit_registry_service_update_lit_repository_metadata`") # noqa: E501
|
|
513
|
+
|
|
514
|
+
collection_formats = {}
|
|
515
|
+
|
|
516
|
+
path_params = {}
|
|
517
|
+
if 'project_id' in params:
|
|
518
|
+
path_params['projectId'] = params['project_id'] # noqa: E501
|
|
519
|
+
if 'lit_repo_name' in params:
|
|
520
|
+
path_params['litRepoName'] = params['lit_repo_name'] # noqa: E501
|
|
521
|
+
|
|
522
|
+
query_params = []
|
|
523
|
+
|
|
524
|
+
header_params = {}
|
|
525
|
+
|
|
526
|
+
form_params = []
|
|
527
|
+
local_var_files = {}
|
|
528
|
+
|
|
529
|
+
body_params = None
|
|
530
|
+
if 'body' in params:
|
|
531
|
+
body_params = params['body']
|
|
532
|
+
# HTTP header `Accept`
|
|
533
|
+
header_params['Accept'] = self.api_client.select_header_accept(
|
|
534
|
+
['application/json']) # noqa: E501
|
|
535
|
+
|
|
536
|
+
# HTTP header `Content-Type`
|
|
537
|
+
header_params['Content-Type'] = self.api_client.select_header_content_type( # noqa: E501
|
|
538
|
+
['application/json']) # noqa: E501
|
|
539
|
+
|
|
540
|
+
# Authentication setting
|
|
541
|
+
auth_settings = [] # noqa: E501
|
|
542
|
+
|
|
543
|
+
return self.api_client.call_api(
|
|
544
|
+
'/v1/projects/{projectId}/lit-registry/{litRepoName}', 'PUT',
|
|
545
|
+
path_params,
|
|
546
|
+
query_params,
|
|
547
|
+
header_params,
|
|
548
|
+
body=body_params,
|
|
549
|
+
post_params=form_params,
|
|
550
|
+
files=local_var_files,
|
|
551
|
+
response_type='V1UpdateLitRepositoryResponse', # noqa: E501
|
|
552
|
+
auth_settings=auth_settings,
|
|
553
|
+
async_req=params.get('async_req'),
|
|
554
|
+
_return_http_data_only=params.get('_return_http_data_only'),
|
|
555
|
+
_preload_content=params.get('_preload_content', True),
|
|
556
|
+
_request_timeout=params.get('_request_timeout'),
|
|
557
|
+
collection_formats=collection_formats)
|
|
@@ -96,6 +96,7 @@ from lightning_sdk.lightning_cloud.openapi.models.jobs_id_body2 import JobsIdBod
|
|
|
96
96
|
from lightning_sdk.lightning_cloud.openapi.models.jobs_id_body3 import JobsIdBody3
|
|
97
97
|
from lightning_sdk.lightning_cloud.openapi.models.litloggermetrics_id_body import LitloggermetricsIdBody
|
|
98
98
|
from lightning_sdk.lightning_cloud.openapi.models.litpages_id_body import LitpagesIdBody
|
|
99
|
+
from lightning_sdk.lightning_cloud.openapi.models.litregistry_lit_repo_name_body import LitregistryLitRepoNameBody
|
|
99
100
|
from lightning_sdk.lightning_cloud.openapi.models.loggermetrics_id_body import LoggermetricsIdBody
|
|
100
101
|
from lightning_sdk.lightning_cloud.openapi.models.metrics_stream_id_loggerartifacts_body import MetricsStreamIdLoggerartifactsBody
|
|
101
102
|
from lightning_sdk.lightning_cloud.openapi.models.metricsstream_create_body import MetricsstreamCreateBody
|
|
@@ -609,6 +610,7 @@ from lightning_sdk.lightning_cloud.openapi.models.v1_organization import V1Organ
|
|
|
609
610
|
from lightning_sdk.lightning_cloud.openapi.models.v1_owner_type import V1OwnerType
|
|
610
611
|
from lightning_sdk.lightning_cloud.openapi.models.v1_package_manager import V1PackageManager
|
|
611
612
|
from lightning_sdk.lightning_cloud.openapi.models.v1_parameterization_spec import V1ParameterizationSpec
|
|
613
|
+
from lightning_sdk.lightning_cloud.openapi.models.v1_path_mapping import V1PathMapping
|
|
612
614
|
from lightning_sdk.lightning_cloud.openapi.models.v1_path_telemetry import V1PathTelemetry
|
|
613
615
|
from lightning_sdk.lightning_cloud.openapi.models.v1_phase_type import V1PhaseType
|
|
614
616
|
from lightning_sdk.lightning_cloud.openapi.models.v1_plugin import V1Plugin
|
|
@@ -716,6 +718,7 @@ from lightning_sdk.lightning_cloud.openapi.models.v1_update_cluster_accelerators
|
|
|
716
718
|
from lightning_sdk.lightning_cloud.openapi.models.v1_update_cluster_availability_request import V1UpdateClusterAvailabilityRequest
|
|
717
719
|
from lightning_sdk.lightning_cloud.openapi.models.v1_update_index_response import V1UpdateIndexResponse
|
|
718
720
|
from lightning_sdk.lightning_cloud.openapi.models.v1_update_lit_page_response import V1UpdateLitPageResponse
|
|
721
|
+
from lightning_sdk.lightning_cloud.openapi.models.v1_update_lit_repository_response import V1UpdateLitRepositoryResponse
|
|
719
722
|
from lightning_sdk.lightning_cloud.openapi.models.v1_update_metrics_stream_visibility_response import V1UpdateMetricsStreamVisibilityResponse
|
|
720
723
|
from lightning_sdk.lightning_cloud.openapi.models.v1_update_model_visibility_response import V1UpdateModelVisibilityResponse
|
|
721
724
|
from lightning_sdk.lightning_cloud.openapi.models.v1_update_project_cluster_accelerators_response import V1UpdateProjectClusterAcceleratorsResponse
|
|
@@ -45,6 +45,7 @@ class DeploymentsIdBody(object):
|
|
|
45
45
|
'autoscaling': 'V1AutoscalingSpec',
|
|
46
46
|
'cloudspace_id': 'str',
|
|
47
47
|
'created_at': 'datetime',
|
|
48
|
+
'debug': 'bool',
|
|
48
49
|
'desired_state': 'V1DeploymentState',
|
|
49
50
|
'endpoint': 'V1Endpoint',
|
|
50
51
|
'is_published': 'bool',
|
|
@@ -66,6 +67,7 @@ class DeploymentsIdBody(object):
|
|
|
66
67
|
'autoscaling': 'autoscaling',
|
|
67
68
|
'cloudspace_id': 'cloudspaceId',
|
|
68
69
|
'created_at': 'createdAt',
|
|
70
|
+
'debug': 'debug',
|
|
69
71
|
'desired_state': 'desiredState',
|
|
70
72
|
'endpoint': 'endpoint',
|
|
71
73
|
'is_published': 'isPublished',
|
|
@@ -82,12 +84,13 @@ class DeploymentsIdBody(object):
|
|
|
82
84
|
'user_id': 'userId'
|
|
83
85
|
}
|
|
84
86
|
|
|
85
|
-
def __init__(self, apis: 'list[V1DeploymentAPI]' =None, autoscaling: 'V1AutoscalingSpec' =None, cloudspace_id: 'str' =None, created_at: 'datetime' =None, desired_state: 'V1DeploymentState' =None, endpoint: 'V1Endpoint' =None, is_published: 'bool' =None, name: 'str' =None, parameter_spec: 'V1ParameterizationSpec' =None, release_id: 'str' =None, replicas: 'int' =None, spec: 'V1JobSpec' =None, status: 'V1DeploymentStatus' =None, strategy: 'V1DeploymentStrategy' =None, template_id: 'str' =None, total_cost: 'float' =None, updated_at: 'datetime' =None, user_id: 'str' =None): # noqa: E501
|
|
87
|
+
def __init__(self, apis: 'list[V1DeploymentAPI]' =None, autoscaling: 'V1AutoscalingSpec' =None, cloudspace_id: 'str' =None, created_at: 'datetime' =None, debug: 'bool' =None, desired_state: 'V1DeploymentState' =None, endpoint: 'V1Endpoint' =None, is_published: 'bool' =None, name: 'str' =None, parameter_spec: 'V1ParameterizationSpec' =None, release_id: 'str' =None, replicas: 'int' =None, spec: 'V1JobSpec' =None, status: 'V1DeploymentStatus' =None, strategy: 'V1DeploymentStrategy' =None, template_id: 'str' =None, total_cost: 'float' =None, updated_at: 'datetime' =None, user_id: 'str' =None): # noqa: E501
|
|
86
88
|
"""DeploymentsIdBody - a model defined in Swagger""" # noqa: E501
|
|
87
89
|
self._apis = None
|
|
88
90
|
self._autoscaling = None
|
|
89
91
|
self._cloudspace_id = None
|
|
90
92
|
self._created_at = None
|
|
93
|
+
self._debug = None
|
|
91
94
|
self._desired_state = None
|
|
92
95
|
self._endpoint = None
|
|
93
96
|
self._is_published = None
|
|
@@ -111,6 +114,8 @@ class DeploymentsIdBody(object):
|
|
|
111
114
|
self.cloudspace_id = cloudspace_id
|
|
112
115
|
if created_at is not None:
|
|
113
116
|
self.created_at = created_at
|
|
117
|
+
if debug is not None:
|
|
118
|
+
self.debug = debug
|
|
114
119
|
if desired_state is not None:
|
|
115
120
|
self.desired_state = desired_state
|
|
116
121
|
if endpoint is not None:
|
|
@@ -224,6 +229,27 @@ class DeploymentsIdBody(object):
|
|
|
224
229
|
|
|
225
230
|
self._created_at = created_at
|
|
226
231
|
|
|
232
|
+
@property
|
|
233
|
+
def debug(self) -> 'bool':
|
|
234
|
+
"""Gets the debug of this DeploymentsIdBody. # noqa: E501
|
|
235
|
+
|
|
236
|
+
|
|
237
|
+
:return: The debug of this DeploymentsIdBody. # noqa: E501
|
|
238
|
+
:rtype: bool
|
|
239
|
+
"""
|
|
240
|
+
return self._debug
|
|
241
|
+
|
|
242
|
+
@debug.setter
|
|
243
|
+
def debug(self, debug: 'bool'):
|
|
244
|
+
"""Sets the debug of this DeploymentsIdBody.
|
|
245
|
+
|
|
246
|
+
|
|
247
|
+
:param debug: The debug of this DeploymentsIdBody. # noqa: E501
|
|
248
|
+
:type: bool
|
|
249
|
+
"""
|
|
250
|
+
|
|
251
|
+
self._debug = debug
|
|
252
|
+
|
|
227
253
|
@property
|
|
228
254
|
def desired_state(self) -> 'V1DeploymentState':
|
|
229
255
|
"""Gets the desired_state of this DeploymentsIdBody. # noqa: E501
|