lightning-sdk 0.2.5__py3-none-any.whl → 0.2.7__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/ai_hub_api.py +1 -0
- lightning_sdk/api/lit_container_api.py +84 -24
- lightning_sdk/api/teamspace_api.py +8 -9
- lightning_sdk/api/utils.py +0 -1
- lightning_sdk/cli/docker.py +1 -1
- lightning_sdk/cli/download.py +10 -2
- lightning_sdk/cli/serve.py +26 -19
- lightning_sdk/cli/upload.py +41 -6
- lightning_sdk/lightning_cloud/openapi/__init__.py +16 -0
- lightning_sdk/lightning_cloud/openapi/api/cloud_space_environment_template_service_api.py +9 -9
- lightning_sdk/lightning_cloud/openapi/api/cloud_space_service_api.py +202 -0
- lightning_sdk/lightning_cloud/openapi/api/cluster_service_api.py +105 -0
- lightning_sdk/lightning_cloud/openapi/api/lit_registry_service_api.py +15 -3
- lightning_sdk/lightning_cloud/openapi/models/__init__.py +16 -0
- lightning_sdk/lightning_cloud/openapi/models/alerts_config_billing.py +175 -0
- lightning_sdk/lightning_cloud/openapi/models/alerts_config_studios.py +149 -0
- lightning_sdk/lightning_cloud/openapi/models/environmenttemplates_id_body.py +27 -1
- lightning_sdk/lightning_cloud/openapi/models/externalv1_cloud_space_instance_status.py +27 -1
- lightning_sdk/lightning_cloud/openapi/models/externalv1_cluster.py +27 -1
- lightning_sdk/lightning_cloud/openapi/models/orgs_id_body.py +53 -1
- lightning_sdk/lightning_cloud/openapi/models/project_id_cloudspaces_body.py +27 -1
- lightning_sdk/lightning_cloud/openapi/models/projects_id_body.py +27 -1
- lightning_sdk/lightning_cloud/openapi/models/server_id_alerts_body.py +201 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_alert_method.py +102 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_alerts_config.py +149 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_cloud_space_cold_start_metrics.py +617 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_cloud_space_environment_template.py +27 -1
- lightning_sdk/lightning_cloud/openapi/models/v1_cloud_space_environment_template_config.py +123 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_cluster_security_options.py +27 -1
- lightning_sdk/lightning_cloud/openapi/models/v1_cluster_spec.py +131 -1
- lightning_sdk/lightning_cloud/openapi/models/v1_conversation_response_chunk.py +29 -3
- lightning_sdk/lightning_cloud/openapi/models/v1_create_cloud_space_environment_template_request.py +27 -1
- lightning_sdk/lightning_cloud/openapi/models/v1_create_project_request.py +27 -1
- lightning_sdk/lightning_cloud/openapi/models/v1_create_server_alert_response.py +97 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_data_connection.py +27 -1
- lightning_sdk/lightning_cloud/openapi/models/v1_google_cloud_direct_v1.py +81 -3
- lightning_sdk/lightning_cloud/openapi/models/v1_lambda_labs_direct_v1.py +1 -29
- lightning_sdk/lightning_cloud/openapi/models/v1_list_cloud_space_cold_start_metrics_response.py +123 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_list_lit_registry_repository_image_artifact_versions_response.py +27 -1
- lightning_sdk/lightning_cloud/openapi/models/v1_message.py +29 -3
- lightning_sdk/lightning_cloud/openapi/models/v1_metadata.py +27 -1
- lightning_sdk/lightning_cloud/openapi/models/v1_organization.py +53 -1
- lightning_sdk/lightning_cloud/openapi/models/v1_project_settings.py +27 -1
- lightning_sdk/lightning_cloud/openapi/models/v1_report_cloud_space_instance_stop_at_response.py +97 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_reservation_details.py +201 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_rule_resource.py +1 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_server_alert.py +201 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_server_alert_phase.py +104 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_server_alert_severity.py +103 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_server_alert_type.py +105 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_subnet_spec.py +149 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_user_features.py +131 -79
- lightning_sdk/lightning_cloud/openapi/models/v1_voltage_park_direct_v1.py +29 -29
- lightning_sdk/lightning_cloud/openapi/models/v1_vultr_direct_v1.py +1 -27
- lightning_sdk/lit_container.py +19 -4
- lightning_sdk/models.py +1 -1
- lightning_sdk/serve.py +86 -15
- lightning_sdk/teamspace.py +32 -18
- {lightning_sdk-0.2.5.dist-info → lightning_sdk-0.2.7.dist-info}/METADATA +1 -1
- {lightning_sdk-0.2.5.dist-info → lightning_sdk-0.2.7.dist-info}/RECORD +65 -49
- {lightning_sdk-0.2.5.dist-info → lightning_sdk-0.2.7.dist-info}/LICENSE +0 -0
- {lightning_sdk-0.2.5.dist-info → lightning_sdk-0.2.7.dist-info}/WHEEL +0 -0
- {lightning_sdk-0.2.5.dist-info → lightning_sdk-0.2.7.dist-info}/entry_points.txt +0 -0
- {lightning_sdk-0.2.5.dist-info → lightning_sdk-0.2.7.dist-info}/top_level.txt +0 -0
lightning_sdk/__init__.py
CHANGED
lightning_sdk/api/ai_hub_api.py
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import inspect
|
|
2
2
|
import time
|
|
3
|
-
from typing import Any, Callable, Dict, Generator, Iterator, List
|
|
3
|
+
from typing import Any, Callable, Dict, Generator, Iterator, List, Optional
|
|
4
4
|
|
|
5
5
|
import docker
|
|
6
6
|
import requests
|
|
7
|
+
from rich.console import Console
|
|
7
8
|
|
|
8
9
|
from lightning_sdk.api.utils import _get_registry_url
|
|
9
10
|
from lightning_sdk.lightning_cloud.env import LIGHTNING_CLOUD_URL
|
|
@@ -21,6 +22,21 @@ class DockerPushError(Exception):
|
|
|
21
22
|
pass
|
|
22
23
|
|
|
23
24
|
|
|
25
|
+
class DockerNotRunningError(Exception):
|
|
26
|
+
def __init__(self, message: str = "Failed to connect to Docker") -> None:
|
|
27
|
+
self.message = message
|
|
28
|
+
super().__init__(self.message)
|
|
29
|
+
|
|
30
|
+
def print_help(self) -> None:
|
|
31
|
+
console = Console()
|
|
32
|
+
console.print("[bold red]Docker Error: Failed to connect to Docker. Is it running?[/bold red]")
|
|
33
|
+
console.print("[yellow]Troubleshooting:[/yellow]")
|
|
34
|
+
console.print("1. Check if Docker daemon is running")
|
|
35
|
+
console.print("2. Verify your user has proper permissions")
|
|
36
|
+
console.print("3. Try restarting Docker service")
|
|
37
|
+
console.print("4. Read more here: https://docs.docker.com/engine/daemon/start/")
|
|
38
|
+
|
|
39
|
+
|
|
24
40
|
def retry_on_lcr_auth_failure(func: Callable) -> Callable:
|
|
25
41
|
def generator_wrapper(self: "LitContainerApi", *args: Any, **kwargs: Any) -> Callable:
|
|
26
42
|
try:
|
|
@@ -54,9 +70,7 @@ class LitContainerApi:
|
|
|
54
70
|
self._docker_client.ping()
|
|
55
71
|
self._docker_auth_config = {}
|
|
56
72
|
except docker.errors.DockerException:
|
|
57
|
-
raise
|
|
58
|
-
"Failed to connect to Docker, follow these steps to start it: https://docs.docker.com/engine/daemon/start/"
|
|
59
|
-
) from None
|
|
73
|
+
raise DockerNotRunningError() from None
|
|
60
74
|
|
|
61
75
|
def authenticate(self, reauth: bool = False) -> bool:
|
|
62
76
|
resp = None
|
|
@@ -85,45 +99,79 @@ class LitContainerApi:
|
|
|
85
99
|
print(f"Authentication error: {e} resp: {resp}")
|
|
86
100
|
return False
|
|
87
101
|
|
|
88
|
-
def list_containers(self, project_id: str) -> List:
|
|
89
|
-
project
|
|
102
|
+
def list_containers(self, project_id: str, cloud_account: Optional[str] = None) -> List:
|
|
103
|
+
"""Lists containers of the project ID.
|
|
104
|
+
|
|
105
|
+
:param project_id: The non-human readable project ID used internally to identify projects.
|
|
106
|
+
:return:
|
|
107
|
+
"""
|
|
108
|
+
project = self._client.lit_registry_service_get_lit_project_registry(
|
|
109
|
+
project_id, cluster_id=cloud_account
|
|
110
|
+
) # cloud account on the CLI is cluster_id
|
|
90
111
|
return project.repositories
|
|
91
112
|
|
|
92
113
|
def delete_container(self, project_id: str, container: str) -> V1DeleteLitRepositoryResponse:
|
|
114
|
+
"""Deletes the container from LitCR. Garbage collection will come in and do the final sweep of the blob.
|
|
115
|
+
|
|
116
|
+
:param project_id: The non-human readable project ID used internally to identify projects.
|
|
117
|
+
:param container: The name of the docker container a user wants to push up, ie, nginx, vllm, etc
|
|
118
|
+
:return:
|
|
119
|
+
"""
|
|
93
120
|
try:
|
|
94
121
|
return self._client.lit_registry_service_delete_lit_repository(project_id, container)
|
|
95
122
|
except Exception as e:
|
|
96
123
|
raise ValueError(f"Could not delete container {container} from project {project_id}: {e!s}") from e
|
|
97
124
|
|
|
98
125
|
@retry_on_lcr_auth_failure
|
|
99
|
-
def upload_container(
|
|
126
|
+
def upload_container(
|
|
127
|
+
self, container: str, teamspace: Teamspace, tag: str, cloud_account: str, platform: str
|
|
128
|
+
) -> Generator[dict, None, None]:
|
|
129
|
+
"""Upload container will push the container to LitCR.
|
|
130
|
+
|
|
131
|
+
It uses docker push API to interact with docker daemon which will then push the container to a storage
|
|
132
|
+
location defined by teamspace + cloud_account. Will retry pushes if not authenticated or if push errors happen
|
|
133
|
+
|
|
134
|
+
:param container: The name of the docker container a user wants to push up, ie, nginx, vllm, etc
|
|
135
|
+
:param teamspace: The teamspace he container is going to appear in. This is <OWNER_ID>/<TEAMSPACE_NAME>
|
|
136
|
+
:param tag: The container tag, default will latest.
|
|
137
|
+
:param cloud_account: If empty will be pushed to Lightning SaaS storage. Otherwise, this will be cluster_id.
|
|
138
|
+
Named cloud-account in the CLI options.
|
|
139
|
+
:param platform: If empty will be linux/amd64. This is important because our entire deployment infra runs on
|
|
140
|
+
linux/amd64. Will show user a warning otherwise.
|
|
141
|
+
:return: Generator[dict, None, None]
|
|
142
|
+
"""
|
|
100
143
|
try:
|
|
101
|
-
self._docker_client.images.get(container)
|
|
144
|
+
self._docker_client.images.get(f"{container}:{tag}")
|
|
102
145
|
except docker.errors.ImageNotFound:
|
|
103
146
|
try:
|
|
104
|
-
self._docker_client.images.pull(container, tag)
|
|
105
|
-
self._docker_client.images.get(container)
|
|
147
|
+
self._docker_client.images.pull(repository=container, tag=tag, platform=platform)
|
|
148
|
+
self._docker_client.images.get(f"{container}:{tag}")
|
|
149
|
+
except docker.errors.ImageNotFound as e:
|
|
150
|
+
raise ValueError(f"Container {container}:{tag} does not exist") from e
|
|
106
151
|
except docker.errors.APIError as e:
|
|
107
152
|
raise ValueError(f"Could not pull container {container}") from e
|
|
108
|
-
except docker.errors.ImageNotFound as e:
|
|
109
|
-
raise ValueError(f"Container {container} does not exist") from e
|
|
110
153
|
except Exception as e:
|
|
111
|
-
raise ValueError(f"Unable to upload {container}") from e
|
|
154
|
+
raise ValueError(f"Unable to upload {container}:{tag}") from e
|
|
112
155
|
|
|
113
156
|
registry_url = _get_registry_url()
|
|
114
157
|
container_basename = container.split("/")[-1]
|
|
115
|
-
repository =
|
|
116
|
-
|
|
158
|
+
repository = (
|
|
159
|
+
f"{registry_url}/lit-container{f'-{cloud_account}' if cloud_account is not None else ''}/"
|
|
160
|
+
f"{teamspace.owner.name}/{teamspace.name}/{container_basename}"
|
|
161
|
+
)
|
|
162
|
+
tagged = self._docker_client.api.tag(f"{container}:{tag}", repository, tag)
|
|
117
163
|
if not tagged:
|
|
118
|
-
raise ValueError(f"Could not tag container {container} with {repository}:{tag}")
|
|
119
|
-
yield from self._push_with_retry(repository)
|
|
164
|
+
raise ValueError(f"Could not tag container {container}:{tag} with {repository}:{tag}")
|
|
165
|
+
yield from self._push_with_retry(repository, tag=tag)
|
|
166
|
+
|
|
120
167
|
yield {
|
|
121
168
|
"finish": True,
|
|
122
|
-
"url": f"{LIGHTNING_CLOUD_URL}/{teamspace.owner.name}/{teamspace.name}/containers/{container_basename}"
|
|
169
|
+
"url": f"{LIGHTNING_CLOUD_URL}/{teamspace.owner.name}/{teamspace.name}/containers/{container_basename}"
|
|
170
|
+
f"{f'?clusterId={cloud_account}' if cloud_account is not None else ''}",
|
|
123
171
|
"repository": repository,
|
|
124
172
|
}
|
|
125
173
|
|
|
126
|
-
def _push_with_retry(self, repository: str, max_retries: int = 3) -> Iterator[Dict[str, Any]]:
|
|
174
|
+
def _push_with_retry(self, repository: str, tag: str, max_retries: int = 3) -> Iterator[Dict[str, Any]]:
|
|
127
175
|
def is_auth_error(error_msg: str) -> bool:
|
|
128
176
|
auth_errors = ["unauthorized", "authentication required", "unauth"]
|
|
129
177
|
return any(err in error_msg.lower() for err in auth_errors)
|
|
@@ -141,7 +189,7 @@ class LitContainerApi:
|
|
|
141
189
|
time.sleep(2)
|
|
142
190
|
|
|
143
191
|
lines = self._docker_client.api.push(
|
|
144
|
-
repository, stream=True, decode=True, auth_config=self._docker_auth_config
|
|
192
|
+
repository, tag=tag, stream=True, decode=True, auth_config=self._docker_auth_config
|
|
145
193
|
)
|
|
146
194
|
for line in lines:
|
|
147
195
|
if isinstance(line, dict) and "error" in line:
|
|
@@ -149,7 +197,7 @@ class LitContainerApi:
|
|
|
149
197
|
if is_auth_error(error) or is_timeout_error(error):
|
|
150
198
|
if attempt < max_retries - 1:
|
|
151
199
|
break
|
|
152
|
-
raise DockerPushError(f"Max retries reached: {error}")
|
|
200
|
+
raise DockerPushError(f"Max retries reached while pushing: {error}")
|
|
153
201
|
raise DockerPushError(f"Push error: {error}")
|
|
154
202
|
yield line
|
|
155
203
|
else:
|
|
@@ -158,14 +206,26 @@ class LitContainerApi:
|
|
|
158
206
|
except docker.errors.APIError as e:
|
|
159
207
|
if (is_auth_error(str(e)) or is_timeout_error(str(e))) and attempt < max_retries - 1:
|
|
160
208
|
continue
|
|
161
|
-
raise DockerPushError(
|
|
209
|
+
raise DockerPushError("Pushing the container failed") from e
|
|
162
210
|
|
|
163
211
|
raise DockerPushError("Max push retries reached")
|
|
164
212
|
|
|
165
213
|
@retry_on_lcr_auth_failure
|
|
166
|
-
def download_container(
|
|
214
|
+
def download_container(
|
|
215
|
+
self, container: str, teamspace: Teamspace, tag: str, cloud_account: Optional[str] = None
|
|
216
|
+
) -> Generator[str, None, None]:
|
|
217
|
+
"""Will download container from LitCR. Optionally from a BYOC cluster.
|
|
218
|
+
|
|
219
|
+
:param container: The name of the container to download
|
|
220
|
+
:param teamspace: The teamspace containing the container
|
|
221
|
+
:param tag: The tag of the container to download
|
|
222
|
+
:return: Generator yielding download status
|
|
223
|
+
"""
|
|
167
224
|
registry_url = _get_registry_url()
|
|
168
|
-
repository =
|
|
225
|
+
repository = (
|
|
226
|
+
f"{registry_url}/lit-container{f'-{cloud_account}' if cloud_account is not None else ''}/"
|
|
227
|
+
f"{teamspace.owner.name}/{teamspace.name}/{container}"
|
|
228
|
+
)
|
|
169
229
|
try:
|
|
170
230
|
self._docker_client.images.pull(repository, tag=tag, auth_config=self._docker_auth_config)
|
|
171
231
|
except requests.exceptions.HTTPError as e:
|
|
@@ -215,16 +215,15 @@ class TeamspaceApi:
|
|
|
215
215
|
version: str,
|
|
216
216
|
local_path: Path,
|
|
217
217
|
remote_path: str,
|
|
218
|
-
cloud_account: str,
|
|
219
218
|
teamspace_id: str,
|
|
220
219
|
progress_bar: bool = True,
|
|
221
220
|
) -> None:
|
|
221
|
+
"""Upload a file to the model store."""
|
|
222
222
|
uploader = _ModelFileUploader(
|
|
223
223
|
client=self._client,
|
|
224
224
|
model_id=model_id,
|
|
225
225
|
version=version,
|
|
226
226
|
teamspace_id=teamspace_id,
|
|
227
|
-
cloud_account=cloud_account,
|
|
228
227
|
file_path=str(local_path),
|
|
229
228
|
remote_path=str(remote_path),
|
|
230
229
|
progress_bar=progress_bar,
|
|
@@ -235,20 +234,20 @@ class TeamspaceApi:
|
|
|
235
234
|
self,
|
|
236
235
|
model_id: str,
|
|
237
236
|
version: str,
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
cloud_account: str,
|
|
237
|
+
file_paths: List[Path],
|
|
238
|
+
remote_paths: List[str],
|
|
241
239
|
teamspace_id: str,
|
|
242
240
|
progress_bar: bool = True,
|
|
243
241
|
) -> None:
|
|
244
|
-
|
|
245
|
-
|
|
242
|
+
"""Upload files to the model store."""
|
|
243
|
+
main_pbar = tqdm(total=len(file_paths), desc="Uploading files...", position=0) if progress_bar else None
|
|
244
|
+
assert len(file_paths) == len(remote_paths), "File paths and remote paths must have the same length"
|
|
245
|
+
for filepath, remote_path in zip(file_paths, remote_paths):
|
|
246
246
|
self.upload_model_file(
|
|
247
247
|
model_id=model_id,
|
|
248
248
|
version=version,
|
|
249
249
|
local_path=filepath,
|
|
250
|
-
remote_path=
|
|
251
|
-
cloud_account=cloud_account,
|
|
250
|
+
remote_path=remote_path,
|
|
252
251
|
teamspace_id=teamspace_id,
|
|
253
252
|
progress_bar=progress_bar, # TODO: Global progress bar
|
|
254
253
|
)
|
lightning_sdk/api/utils.py
CHANGED
lightning_sdk/cli/docker.py
CHANGED
|
@@ -19,4 +19,4 @@ def api(server_filename: str, port: int = 8000, gpu: bool = False, tag: str = "l
|
|
|
19
19
|
|
|
20
20
|
|
|
21
21
|
def _api(server_filename: str, port: int = 8000, gpu: bool = False, tag: str = "litserve-model") -> str:
|
|
22
|
-
return _LitServeDeployer().dockerize_api(server_filename=server_filename, port=port, gpu=gpu, tag=tag)
|
|
22
|
+
return _LitServeDeployer(None, None).dockerize_api(server_filename=server_filename, port=port, gpu=gpu, tag=tag)
|
lightning_sdk/cli/download.py
CHANGED
|
@@ -143,7 +143,15 @@ def file(path: str = "", studio: Optional[str] = None, local_path: str = ".") ->
|
|
|
143
143
|
@click.argument("container")
|
|
144
144
|
@click.option("--teamspace", default=None, help="The name of the teamspace to download the container from")
|
|
145
145
|
@click.option("--tag", default="latest", show_default=True, help="The tag of the container to download.")
|
|
146
|
-
|
|
146
|
+
@click.option(
|
|
147
|
+
"--cloud-account",
|
|
148
|
+
"--cloud_account", # The UI will present the above variant, using this as a secondary to be consistent w/ models
|
|
149
|
+
default=None,
|
|
150
|
+
help="The name of the cloud account to download the Container from.",
|
|
151
|
+
)
|
|
152
|
+
def download_container(
|
|
153
|
+
container: str, teamspace: Optional[str] = None, tag: str = "latest", cloud_account: Optional[str] = None
|
|
154
|
+
) -> None:
|
|
147
155
|
"""Download a docker container from a teamspace.
|
|
148
156
|
|
|
149
157
|
Example:
|
|
@@ -156,7 +164,7 @@ def download_container(container: str, teamspace: Optional[str] = None, tag: str
|
|
|
156
164
|
resolved_teamspace = menu._resolve_teamspace(teamspace)
|
|
157
165
|
with console.status("Downloading container..."):
|
|
158
166
|
api = LitContainerApi()
|
|
159
|
-
api.download_container(container, resolved_teamspace, tag)
|
|
167
|
+
api.download_container(container, resolved_teamspace, tag, cloud_account)
|
|
160
168
|
console.print("Container downloaded successfully", style="green")
|
|
161
169
|
|
|
162
170
|
|
lightning_sdk/cli/serve.py
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import os
|
|
2
2
|
import subprocess
|
|
3
|
+
from datetime import datetime
|
|
3
4
|
from pathlib import Path
|
|
4
5
|
from typing import Optional, Union
|
|
5
6
|
|
|
@@ -9,11 +10,9 @@ from rich.progress import Progress, SpinnerColumn, TextColumn, TimeElapsedColumn
|
|
|
9
10
|
from rich.prompt import Confirm
|
|
10
11
|
|
|
11
12
|
from lightning_sdk import Machine, Teamspace
|
|
12
|
-
from lightning_sdk.api.deployment_api import DeploymentApi
|
|
13
13
|
from lightning_sdk.api.lit_container_api import LitContainerApi
|
|
14
|
-
from lightning_sdk.cli.exceptions import StudioCliError
|
|
15
14
|
from lightning_sdk.cli.teamspace_menu import _TeamspacesMenu
|
|
16
|
-
from lightning_sdk.serve import _LitServeDeployer
|
|
15
|
+
from lightning_sdk.serve import _LitServeDeployer, authenticate
|
|
17
16
|
|
|
18
17
|
_MACHINE_VALUES = tuple([machine.name for machine in Machine.__dict__.values() if isinstance(machine, Machine)])
|
|
19
18
|
|
|
@@ -109,7 +108,7 @@ def api(
|
|
|
109
108
|
script_path: str,
|
|
110
109
|
easy: bool,
|
|
111
110
|
cloud: bool,
|
|
112
|
-
name: str,
|
|
111
|
+
name: Optional[str],
|
|
113
112
|
non_interactive: bool,
|
|
114
113
|
machine: str,
|
|
115
114
|
interruptible: bool,
|
|
@@ -137,6 +136,7 @@ def api(
|
|
|
137
136
|
user=user,
|
|
138
137
|
cloud_account=cloud_account,
|
|
139
138
|
port=port,
|
|
139
|
+
replicas=replicas,
|
|
140
140
|
min_replica=min_replica,
|
|
141
141
|
max_replica=max_replica,
|
|
142
142
|
include_credentials=not no_credentials,
|
|
@@ -172,6 +172,10 @@ def api_impl(
|
|
|
172
172
|
|
|
173
173
|
_LitServeDeployer.generate_client() if easy else None
|
|
174
174
|
|
|
175
|
+
if not repository:
|
|
176
|
+
timestr = datetime.now().strftime("%b-%d-%H_%M")
|
|
177
|
+
repository = f"litserve-{timestr}".lower()
|
|
178
|
+
|
|
175
179
|
if cloud:
|
|
176
180
|
repository = repository or "litserve-model"
|
|
177
181
|
machine = Machine.from_str(machine)
|
|
@@ -223,6 +227,14 @@ def _handle_cloud(
|
|
|
223
227
|
replicas: Optional[int] = 1,
|
|
224
228
|
include_credentials: Optional[bool] = True,
|
|
225
229
|
) -> None:
|
|
230
|
+
deployment_name = os.path.basename(repository)
|
|
231
|
+
tag = tag if tag else "latest"
|
|
232
|
+
|
|
233
|
+
if non_interactive:
|
|
234
|
+
console.print("[italic]non-interactive[/italic] mode enabled, skipping confirmation prompts", style="blue")
|
|
235
|
+
|
|
236
|
+
# Authenticate with LitServe affiliate
|
|
237
|
+
authenticate()
|
|
226
238
|
if teamspace is None:
|
|
227
239
|
menu = _TeamspacesMenu()
|
|
228
240
|
resolved_teamspace = menu._resolve_teamspace(teamspace)
|
|
@@ -230,11 +242,8 @@ def _handle_cloud(
|
|
|
230
242
|
resolved_teamspace = Teamspace(name=teamspace, org=org, user=user)
|
|
231
243
|
|
|
232
244
|
port = port or 8000
|
|
233
|
-
ls_deployer = _LitServeDeployer()
|
|
245
|
+
ls_deployer = _LitServeDeployer(name=deployment_name, teamspace=resolved_teamspace)
|
|
234
246
|
path = ls_deployer.dockerize_api(script_path, port=port, gpu=not machine.is_cpu(), tag=tag, print_success=False)
|
|
235
|
-
console.clear()
|
|
236
|
-
if non_interactive:
|
|
237
|
-
console.print("[italic]non-interactive[/italic] mode enabled, skipping confirmation prompts", style="blue")
|
|
238
247
|
|
|
239
248
|
console.print(f"\nPlease review the Dockerfile at [u]{path}[/u] and make sure it is correct.", style="bold")
|
|
240
249
|
correct_dockerfile = True if non_interactive else Confirm.ask("Is the Dockerfile correct?", default=True)
|
|
@@ -242,14 +251,9 @@ def _handle_cloud(
|
|
|
242
251
|
console.print("Please fix the Dockerfile and try again.", style="red")
|
|
243
252
|
return
|
|
244
253
|
|
|
245
|
-
|
|
246
|
-
|
|
254
|
+
# list containers to create the project if it doesn't exist
|
|
247
255
|
lit_cr = LitContainerApi()
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
ls_deployer.authenticate()
|
|
251
|
-
if DeploymentApi().get_deployment_by_name(deployment_name, resolved_teamspace.id):
|
|
252
|
-
raise StudioCliError(f"Deployment {deployment_name} already exists. Please choose a different name.") from None
|
|
256
|
+
lit_cr.list_containers(resolved_teamspace.id, cloud_account=cloud_account)
|
|
253
257
|
|
|
254
258
|
with Progress(
|
|
255
259
|
SpinnerColumn(),
|
|
@@ -259,18 +263,21 @@ def _handle_cloud(
|
|
|
259
263
|
transient=True,
|
|
260
264
|
) as progress:
|
|
261
265
|
try:
|
|
266
|
+
# TODO: @aniketmaurya improve the console prints here
|
|
262
267
|
ls_deployer.build_container(path, repository, tag, console, progress)
|
|
263
|
-
push_status = ls_deployer.push_container(
|
|
268
|
+
push_status = ls_deployer.push_container(
|
|
269
|
+
repository, tag, resolved_teamspace, lit_cr, progress, cloud_account=cloud_account
|
|
270
|
+
)
|
|
264
271
|
except Exception as e:
|
|
265
272
|
console.print(f"❌ Deployment failed: {e}", style="red")
|
|
266
273
|
return
|
|
267
274
|
console.print(f"\n✅ Image pushed to {repository}:{tag}")
|
|
268
275
|
console.print(f"🔗 You can access the container at: [i]{push_status.get('url')}[/i]")
|
|
269
|
-
|
|
276
|
+
image = push_status.get("repository")
|
|
270
277
|
|
|
271
|
-
deployment_status = ls_deployer.
|
|
278
|
+
deployment_status = ls_deployer.run_on_cloud(
|
|
272
279
|
deployment_name=deployment_name,
|
|
273
|
-
image=
|
|
280
|
+
image=image,
|
|
274
281
|
teamspace=resolved_teamspace,
|
|
275
282
|
metric=None,
|
|
276
283
|
machine=machine,
|
lightning_sdk/cli/upload.py
CHANGED
|
@@ -11,11 +11,12 @@ from rich.progress import Progress, SpinnerColumn, TextColumn, TimeElapsedColumn
|
|
|
11
11
|
from simple_term_menu import TerminalMenu
|
|
12
12
|
from tqdm import tqdm
|
|
13
13
|
|
|
14
|
-
from lightning_sdk.api.lit_container_api import LCRAuthFailedError, LitContainerApi
|
|
14
|
+
from lightning_sdk.api.lit_container_api import DockerNotRunningError, LCRAuthFailedError, LitContainerApi
|
|
15
15
|
from lightning_sdk.api.utils import _get_cloud_url
|
|
16
16
|
from lightning_sdk.cli.exceptions import StudioCliError
|
|
17
17
|
from lightning_sdk.cli.studios_menu import _StudiosMenu
|
|
18
18
|
from lightning_sdk.cli.teamspace_menu import _TeamspacesMenu
|
|
19
|
+
from lightning_sdk.constants import _LIGHTNING_DEBUG
|
|
19
20
|
from lightning_sdk.models import upload_model as _upload_model
|
|
20
21
|
from lightning_sdk.studio import Studio
|
|
21
22
|
from lightning_sdk.utils.resolve import _get_authed_user, skip_studio_init
|
|
@@ -116,11 +117,28 @@ def file(path: str, studio: Optional[str] = None, remote_path: Optional[str] = N
|
|
|
116
117
|
"If not specified, tries to infer from the environment (e.g. when run from within a Studio.)"
|
|
117
118
|
),
|
|
118
119
|
)
|
|
119
|
-
|
|
120
|
+
@click.option(
|
|
121
|
+
"--cloud-account",
|
|
122
|
+
"--cloud_account", # The UI will present the above variant, using this as a secondary to be consistent w/ models
|
|
123
|
+
default=None,
|
|
124
|
+
help="The name of the cloud account to store the Container in.",
|
|
125
|
+
)
|
|
126
|
+
@click.option(
|
|
127
|
+
"--platform",
|
|
128
|
+
"--platform",
|
|
129
|
+
default="linux/amd64",
|
|
130
|
+
help="This is the platform the container pulled and push to Lightning AI will run on.",
|
|
131
|
+
)
|
|
132
|
+
def upload_container(
|
|
133
|
+
container: str,
|
|
134
|
+
tag: str = "latest",
|
|
135
|
+
teamspace: Optional[str] = None,
|
|
136
|
+
cloud_account: Optional[str] = None,
|
|
137
|
+
platform: Optional[str] = "linux/amd64",
|
|
138
|
+
) -> None:
|
|
120
139
|
"""Upload a container to Lightning AI's container registry."""
|
|
121
140
|
menu = _TeamspacesMenu()
|
|
122
141
|
teamspace = menu._resolve_teamspace(teamspace)
|
|
123
|
-
api = LitContainerApi()
|
|
124
142
|
console = Console()
|
|
125
143
|
with Progress(
|
|
126
144
|
SpinnerColumn(),
|
|
@@ -129,8 +147,13 @@ def upload_container(container: str, tag: str = "latest", teamspace: Optional[st
|
|
|
129
147
|
console=console,
|
|
130
148
|
transient=False,
|
|
131
149
|
) as progress:
|
|
132
|
-
push_task = progress.add_task("Pushing Docker image", total=None)
|
|
133
150
|
try:
|
|
151
|
+
if platform != "linux/amd64":
|
|
152
|
+
console.print(
|
|
153
|
+
"[yellow]Warning: The platform you selected (" + platform + ") may not deploy successfully[/yellow]"
|
|
154
|
+
)
|
|
155
|
+
api = LitContainerApi()
|
|
156
|
+
push_task = progress.add_task("Pushing Docker image", total=None)
|
|
134
157
|
console.print("Authenticating with Lightning Container Registry...")
|
|
135
158
|
try:
|
|
136
159
|
api.authenticate()
|
|
@@ -139,15 +162,27 @@ def upload_container(container: str, tag: str = "latest", teamspace: Optional[st
|
|
|
139
162
|
# let the push with retry take control of auth moving forward
|
|
140
163
|
pass
|
|
141
164
|
|
|
142
|
-
lines = api.upload_container(container, teamspace, tag)
|
|
165
|
+
lines = api.upload_container(container, teamspace, tag, cloud_account, platform)
|
|
143
166
|
_print_docker_push(lines, console, progress, push_task)
|
|
167
|
+
except DockerNotRunningError as e:
|
|
168
|
+
e.print_help()
|
|
169
|
+
return
|
|
144
170
|
except LCRAuthFailedError:
|
|
145
171
|
console.print("Re-authenticating with Lightning Container Registry...")
|
|
146
172
|
if not api.authenticate(reauth=True):
|
|
147
173
|
raise StudioCliError("Failed to authenticate with Lightning Container Registry") from None
|
|
148
174
|
console.print("Authenticated with Lightning Container Registry", style="green")
|
|
149
|
-
lines = api.upload_container(container, teamspace, tag)
|
|
175
|
+
lines = api.upload_container(container, teamspace, tag, cloud_account, platform)
|
|
150
176
|
_print_docker_push(lines, console, progress, push_task)
|
|
177
|
+
except Exception as e:
|
|
178
|
+
if _LIGHTNING_DEBUG:
|
|
179
|
+
print(e)
|
|
180
|
+
if e.__cause__:
|
|
181
|
+
print(e.__cause__)
|
|
182
|
+
|
|
183
|
+
progress.update(push_task, description=f"[bold red]Error: {e!s}[/]")
|
|
184
|
+
progress.stop()
|
|
185
|
+
return
|
|
151
186
|
progress.update(push_task, description="[green]Container pushed![/green]")
|
|
152
187
|
|
|
153
188
|
|
|
@@ -66,6 +66,8 @@ from lightning_sdk.lightning_cloud.openapi.configuration import Configuration
|
|
|
66
66
|
from lightning_sdk.lightning_cloud.openapi.models.affiliatelinks_id_body import AffiliatelinksIdBody
|
|
67
67
|
from lightning_sdk.lightning_cloud.openapi.models.agentmanagedendpoints_id_body import AgentmanagedendpointsIdBody
|
|
68
68
|
from lightning_sdk.lightning_cloud.openapi.models.agents_id_body import AgentsIdBody
|
|
69
|
+
from lightning_sdk.lightning_cloud.openapi.models.alerts_config_billing import AlertsConfigBilling
|
|
70
|
+
from lightning_sdk.lightning_cloud.openapi.models.alerts_config_studios import AlertsConfigStudios
|
|
69
71
|
from lightning_sdk.lightning_cloud.openapi.models.app_id_works_body import AppIdWorksBody
|
|
70
72
|
from lightning_sdk.lightning_cloud.openapi.models.appinstances_id_body import AppinstancesIdBody
|
|
71
73
|
from lightning_sdk.lightning_cloud.openapi.models.approveautojoindomain_domain_body import ApproveautojoindomainDomainBody
|
|
@@ -196,6 +198,7 @@ from lightning_sdk.lightning_cloud.openapi.models.rpc_status import RpcStatus
|
|
|
196
198
|
from lightning_sdk.lightning_cloud.openapi.models.schedules_id_body import SchedulesIdBody
|
|
197
199
|
from lightning_sdk.lightning_cloud.openapi.models.secrets_id_body import SecretsIdBody
|
|
198
200
|
from lightning_sdk.lightning_cloud.openapi.models.secrets_id_body1 import SecretsIdBody1
|
|
201
|
+
from lightning_sdk.lightning_cloud.openapi.models.server_id_alerts_body import ServerIdAlertsBody
|
|
199
202
|
from lightning_sdk.lightning_cloud.openapi.models.servers_server_id_body import ServersServerIdBody
|
|
200
203
|
from lightning_sdk.lightning_cloud.openapi.models.service_artifact_artifact_kind import ServiceArtifactArtifactKind
|
|
201
204
|
from lightning_sdk.lightning_cloud.openapi.models.service_health_service_status import ServiceHealthServiceStatus
|
|
@@ -232,6 +235,8 @@ from lightning_sdk.lightning_cloud.openapi.models.v1_agent_job import V1AgentJob
|
|
|
232
235
|
from lightning_sdk.lightning_cloud.openapi.models.v1_agent_job_artifact import V1AgentJobArtifact
|
|
233
236
|
from lightning_sdk.lightning_cloud.openapi.models.v1_agent_upload_multipart_url import V1AgentUploadMultipartUrl
|
|
234
237
|
from lightning_sdk.lightning_cloud.openapi.models.v1_agent_upload_part_response import V1AgentUploadPartResponse
|
|
238
|
+
from lightning_sdk.lightning_cloud.openapi.models.v1_alert_method import V1AlertMethod
|
|
239
|
+
from lightning_sdk.lightning_cloud.openapi.models.v1_alerts_config import V1AlertsConfig
|
|
235
240
|
from lightning_sdk.lightning_cloud.openapi.models.v1_api_pricing_spec import V1ApiPricingSpec
|
|
236
241
|
from lightning_sdk.lightning_cloud.openapi.models.v1_app_type import V1AppType
|
|
237
242
|
from lightning_sdk.lightning_cloud.openapi.models.v1_append_logger_metrics_response import V1AppendLoggerMetricsResponse
|
|
@@ -271,8 +276,10 @@ from lightning_sdk.lightning_cloud.openapi.models.v1_cloud_space_artifact_event
|
|
|
271
276
|
from lightning_sdk.lightning_cloud.openapi.models.v1_cloud_space_artifact_event_type import V1CloudSpaceArtifactEventType
|
|
272
277
|
from lightning_sdk.lightning_cloud.openapi.models.v1_cloud_space_code_version import V1CloudSpaceCodeVersion
|
|
273
278
|
from lightning_sdk.lightning_cloud.openapi.models.v1_cloud_space_code_version_status import V1CloudSpaceCodeVersionStatus
|
|
279
|
+
from lightning_sdk.lightning_cloud.openapi.models.v1_cloud_space_cold_start_metrics import V1CloudSpaceColdStartMetrics
|
|
274
280
|
from lightning_sdk.lightning_cloud.openapi.models.v1_cloud_space_engagement_response import V1CloudSpaceEngagementResponse
|
|
275
281
|
from lightning_sdk.lightning_cloud.openapi.models.v1_cloud_space_environment_template import V1CloudSpaceEnvironmentTemplate
|
|
282
|
+
from lightning_sdk.lightning_cloud.openapi.models.v1_cloud_space_environment_template_config import V1CloudSpaceEnvironmentTemplateConfig
|
|
276
283
|
from lightning_sdk.lightning_cloud.openapi.models.v1_cloud_space_instance_collab_status import V1CloudSpaceInstanceCollabStatus
|
|
277
284
|
from lightning_sdk.lightning_cloud.openapi.models.v1_cloud_space_instance_config import V1CloudSpaceInstanceConfig
|
|
278
285
|
from lightning_sdk.lightning_cloud.openapi.models.v1_cloud_space_instance_startup_status import V1CloudSpaceInstanceStartupStatus
|
|
@@ -346,6 +353,7 @@ from lightning_sdk.lightning_cloud.openapi.models.v1_create_organization_request
|
|
|
346
353
|
from lightning_sdk.lightning_cloud.openapi.models.v1_create_pipeline_template_request import V1CreatePipelineTemplateRequest
|
|
347
354
|
from lightning_sdk.lightning_cloud.openapi.models.v1_create_project_request import V1CreateProjectRequest
|
|
348
355
|
from lightning_sdk.lightning_cloud.openapi.models.v1_create_ssh_public_key_request import V1CreateSSHPublicKeyRequest
|
|
356
|
+
from lightning_sdk.lightning_cloud.openapi.models.v1_create_server_alert_response import V1CreateServerAlertResponse
|
|
349
357
|
from lightning_sdk.lightning_cloud.openapi.models.v1_create_shared_metrics_stream_request import V1CreateSharedMetricsStreamRequest
|
|
350
358
|
from lightning_sdk.lightning_cloud.openapi.models.v1_create_shared_metrics_stream_response import V1CreateSharedMetricsStreamResponse
|
|
351
359
|
from lightning_sdk.lightning_cloud.openapi.models.v1_create_snowflake_connection_response import V1CreateSnowflakeConnectionResponse
|
|
@@ -571,6 +579,7 @@ from lightning_sdk.lightning_cloud.openapi.models.v1_list_agent_job_artifacts_re
|
|
|
571
579
|
from lightning_sdk.lightning_cloud.openapi.models.v1_list_agent_jobs_response import V1ListAgentJobsResponse
|
|
572
580
|
from lightning_sdk.lightning_cloud.openapi.models.v1_list_assistants_response import V1ListAssistantsResponse
|
|
573
581
|
from lightning_sdk.lightning_cloud.openapi.models.v1_list_cloud_space_apps_response import V1ListCloudSpaceAppsResponse
|
|
582
|
+
from lightning_sdk.lightning_cloud.openapi.models.v1_list_cloud_space_cold_start_metrics_response import V1ListCloudSpaceColdStartMetricsResponse
|
|
574
583
|
from lightning_sdk.lightning_cloud.openapi.models.v1_list_cloud_space_environment_templates_response import V1ListCloudSpaceEnvironmentTemplatesResponse
|
|
575
584
|
from lightning_sdk.lightning_cloud.openapi.models.v1_list_cloud_space_instances_response import V1ListCloudSpaceInstancesResponse
|
|
576
585
|
from lightning_sdk.lightning_cloud.openapi.models.v1_list_cloud_space_publications_response import V1ListCloudSpacePublicationsResponse
|
|
@@ -765,11 +774,13 @@ from lightning_sdk.lightning_cloud.openapi.models.v1_refresh_request import V1Re
|
|
|
765
774
|
from lightning_sdk.lightning_cloud.openapi.models.v1_refresh_response import V1RefreshResponse
|
|
766
775
|
from lightning_sdk.lightning_cloud.openapi.models.v1_region_state import V1RegionState
|
|
767
776
|
from lightning_sdk.lightning_cloud.openapi.models.v1_regional_load_balancer import V1RegionalLoadBalancer
|
|
777
|
+
from lightning_sdk.lightning_cloud.openapi.models.v1_report_cloud_space_instance_stop_at_response import V1ReportCloudSpaceInstanceStopAtResponse
|
|
768
778
|
from lightning_sdk.lightning_cloud.openapi.models.v1_report_logs_activity_response import V1ReportLogsActivityResponse
|
|
769
779
|
from lightning_sdk.lightning_cloud.openapi.models.v1_report_restart_timings_response import V1ReportRestartTimingsResponse
|
|
770
780
|
from lightning_sdk.lightning_cloud.openapi.models.v1_request_cluster_access_request import V1RequestClusterAccessRequest
|
|
771
781
|
from lightning_sdk.lightning_cloud.openapi.models.v1_request_cluster_access_response import V1RequestClusterAccessResponse
|
|
772
782
|
from lightning_sdk.lightning_cloud.openapi.models.v1_request_verification_code_response import V1RequestVerificationCodeResponse
|
|
783
|
+
from lightning_sdk.lightning_cloud.openapi.models.v1_reservation_details import V1ReservationDetails
|
|
773
784
|
from lightning_sdk.lightning_cloud.openapi.models.v1_resource_tag import V1ResourceTag
|
|
774
785
|
from lightning_sdk.lightning_cloud.openapi.models.v1_resource_visibility import V1ResourceVisibility
|
|
775
786
|
from lightning_sdk.lightning_cloud.openapi.models.v1_resources import V1Resources
|
|
@@ -797,6 +808,10 @@ from lightning_sdk.lightning_cloud.openapi.models.v1_search_users_response impor
|
|
|
797
808
|
from lightning_sdk.lightning_cloud.openapi.models.v1_secret import V1Secret
|
|
798
809
|
from lightning_sdk.lightning_cloud.openapi.models.v1_secret_type import V1SecretType
|
|
799
810
|
from lightning_sdk.lightning_cloud.openapi.models.v1_select import V1Select
|
|
811
|
+
from lightning_sdk.lightning_cloud.openapi.models.v1_server_alert import V1ServerAlert
|
|
812
|
+
from lightning_sdk.lightning_cloud.openapi.models.v1_server_alert_phase import V1ServerAlertPhase
|
|
813
|
+
from lightning_sdk.lightning_cloud.openapi.models.v1_server_alert_severity import V1ServerAlertSeverity
|
|
814
|
+
from lightning_sdk.lightning_cloud.openapi.models.v1_server_alert_type import V1ServerAlertType
|
|
800
815
|
from lightning_sdk.lightning_cloud.openapi.models.v1_server_check_in_response import V1ServerCheckInResponse
|
|
801
816
|
from lightning_sdk.lightning_cloud.openapi.models.v1_service_artifact import V1ServiceArtifact
|
|
802
817
|
from lightning_sdk.lightning_cloud.openapi.models.v1_service_execution import V1ServiceExecution
|
|
@@ -821,6 +836,7 @@ from lightning_sdk.lightning_cloud.openapi.models.v1_storage_asset_type import V
|
|
|
821
836
|
from lightning_sdk.lightning_cloud.openapi.models.v1_storage_system_metrics import V1StorageSystemMetrics
|
|
822
837
|
from lightning_sdk.lightning_cloud.openapi.models.v1_studio_job import V1StudioJob
|
|
823
838
|
from lightning_sdk.lightning_cloud.openapi.models.v1_studio_job_app import V1StudioJobApp
|
|
839
|
+
from lightning_sdk.lightning_cloud.openapi.models.v1_subnet_spec import V1SubnetSpec
|
|
824
840
|
from lightning_sdk.lightning_cloud.openapi.models.v1_switch_cloud_space_instance_response import V1SwitchCloudSpaceInstanceResponse
|
|
825
841
|
from lightning_sdk.lightning_cloud.openapi.models.v1_system_info import V1SystemInfo
|
|
826
842
|
from lightning_sdk.lightning_cloud.openapi.models.v1_system_metrics import V1SystemMetrics
|
|
@@ -334,12 +334,12 @@ class CloudSpaceEnvironmentTemplateServiceApi(object):
|
|
|
334
334
|
_request_timeout=params.get('_request_timeout'),
|
|
335
335
|
collection_formats=collection_formats)
|
|
336
336
|
|
|
337
|
-
def
|
|
338
|
-
"""
|
|
337
|
+
def cloud_space_environment_template_service_list_cloud_space_environment_templates(self, **kwargs) -> 'V1ListCloudSpaceEnvironmentTemplatesResponse': # noqa: E501
|
|
338
|
+
"""cloud_space_environment_template_service_list_cloud_space_environment_templates # noqa: E501
|
|
339
339
|
|
|
340
340
|
This method makes a synchronous HTTP request by default. To make an
|
|
341
341
|
asynchronous HTTP request, please pass async_req=True
|
|
342
|
-
>>> thread = api.
|
|
342
|
+
>>> thread = api.cloud_space_environment_template_service_list_cloud_space_environment_templates(async_req=True)
|
|
343
343
|
>>> result = thread.get()
|
|
344
344
|
|
|
345
345
|
:param async_req bool
|
|
@@ -352,17 +352,17 @@ class CloudSpaceEnvironmentTemplateServiceApi(object):
|
|
|
352
352
|
"""
|
|
353
353
|
kwargs['_return_http_data_only'] = True
|
|
354
354
|
if kwargs.get('async_req'):
|
|
355
|
-
return self.
|
|
355
|
+
return self.cloud_space_environment_template_service_list_cloud_space_environment_templates_with_http_info(**kwargs) # noqa: E501
|
|
356
356
|
else:
|
|
357
|
-
(data) = self.
|
|
357
|
+
(data) = self.cloud_space_environment_template_service_list_cloud_space_environment_templates_with_http_info(**kwargs) # noqa: E501
|
|
358
358
|
return data
|
|
359
359
|
|
|
360
|
-
def
|
|
361
|
-
"""
|
|
360
|
+
def cloud_space_environment_template_service_list_cloud_space_environment_templates_with_http_info(self, **kwargs) -> 'V1ListCloudSpaceEnvironmentTemplatesResponse': # noqa: E501
|
|
361
|
+
"""cloud_space_environment_template_service_list_cloud_space_environment_templates # noqa: E501
|
|
362
362
|
|
|
363
363
|
This method makes a synchronous HTTP request by default. To make an
|
|
364
364
|
asynchronous HTTP request, please pass async_req=True
|
|
365
|
-
>>> thread = api.
|
|
365
|
+
>>> thread = api.cloud_space_environment_template_service_list_cloud_space_environment_templates_with_http_info(async_req=True)
|
|
366
366
|
>>> result = thread.get()
|
|
367
367
|
|
|
368
368
|
:param async_req bool
|
|
@@ -385,7 +385,7 @@ class CloudSpaceEnvironmentTemplateServiceApi(object):
|
|
|
385
385
|
if key not in all_params:
|
|
386
386
|
raise TypeError(
|
|
387
387
|
"Got an unexpected keyword argument '%s'"
|
|
388
|
-
" to method
|
|
388
|
+
" to method cloud_space_environment_template_service_list_cloud_space_environment_templates" % key
|
|
389
389
|
)
|
|
390
390
|
params[key] = val
|
|
391
391
|
del params['kwargs']
|