lightning-sdk 0.1.58__py3-none-any.whl → 0.2.1__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 (121) hide show
  1. lightning_sdk/__init__.py +5 -3
  2. lightning_sdk/api/deployment_api.py +23 -11
  3. lightning_sdk/api/job_api.py +42 -7
  4. lightning_sdk/api/lit_container_api.py +23 -3
  5. lightning_sdk/api/mmt_api.py +46 -8
  6. lightning_sdk/api/pipeline_api.py +50 -0
  7. lightning_sdk/api/teamspace_api.py +2 -2
  8. lightning_sdk/api/utils.py +15 -5
  9. lightning_sdk/cli/ai_hub.py +30 -65
  10. lightning_sdk/cli/coloring.py +60 -0
  11. lightning_sdk/cli/configure.py +25 -40
  12. lightning_sdk/cli/connect.py +7 -20
  13. lightning_sdk/cli/create.py +83 -0
  14. lightning_sdk/cli/delete.py +72 -75
  15. lightning_sdk/cli/docker.py +22 -0
  16. lightning_sdk/cli/download.py +78 -113
  17. lightning_sdk/cli/entrypoint.py +44 -65
  18. lightning_sdk/cli/generate.py +28 -43
  19. lightning_sdk/cli/inspect.py +22 -50
  20. lightning_sdk/cli/list.py +281 -222
  21. lightning_sdk/cli/mmts_menu.py +1 -1
  22. lightning_sdk/cli/open.py +62 -0
  23. lightning_sdk/cli/run.py +430 -263
  24. lightning_sdk/cli/serve.py +128 -191
  25. lightning_sdk/cli/start.py +55 -36
  26. lightning_sdk/cli/stop.py +97 -55
  27. lightning_sdk/cli/switch.py +53 -36
  28. lightning_sdk/cli/upload.py +318 -255
  29. lightning_sdk/deployment/__init__.py +2 -0
  30. lightning_sdk/deployment/deployment.py +33 -8
  31. lightning_sdk/lightning_cloud/openapi/__init__.py +23 -0
  32. lightning_sdk/lightning_cloud/openapi/api/__init__.py +1 -0
  33. lightning_sdk/lightning_cloud/openapi/api/assistants_service_api.py +10 -6
  34. lightning_sdk/lightning_cloud/openapi/api/jobs_service_api.py +355 -4
  35. lightning_sdk/lightning_cloud/openapi/api/lit_logger_service_api.py +4 -4
  36. lightning_sdk/lightning_cloud/openapi/api/lit_registry_service_api.py +14 -2
  37. lightning_sdk/lightning_cloud/openapi/api/pipelines_service_api.py +674 -0
  38. lightning_sdk/lightning_cloud/openapi/api/storage_service_api.py +303 -4
  39. lightning_sdk/lightning_cloud/openapi/models/__init__.py +22 -0
  40. lightning_sdk/lightning_cloud/openapi/models/agents_id_body.py +17 -69
  41. lightning_sdk/lightning_cloud/openapi/models/cluster_id_capacityreservations_body.py +27 -1
  42. lightning_sdk/lightning_cloud/openapi/models/create.py +27 -1
  43. lightning_sdk/lightning_cloud/openapi/models/create_deployment_request_defines_a_spec_for_the_job_that_allows_for_autoscaling_jobs.py +53 -1
  44. lightning_sdk/lightning_cloud/openapi/models/deployments_id_body.py +105 -1
  45. lightning_sdk/lightning_cloud/openapi/models/id_visibility_body1.py +1 -27
  46. lightning_sdk/lightning_cloud/openapi/models/id_visibility_body2.py +149 -0
  47. lightning_sdk/lightning_cloud/openapi/models/org_id_memberships_body.py +27 -1
  48. lightning_sdk/lightning_cloud/openapi/models/orgs_id_body.py +157 -1
  49. lightning_sdk/lightning_cloud/openapi/models/pipelines_id_body.py +461 -0
  50. lightning_sdk/lightning_cloud/openapi/models/project_id_pipelines_body.py +227 -0
  51. lightning_sdk/lightning_cloud/openapi/models/projects_id_body.py +157 -1
  52. lightning_sdk/lightning_cloud/openapi/models/slurm_jobs_body.py +79 -1
  53. lightning_sdk/lightning_cloud/openapi/models/uploads_upload_id_body.py +1 -27
  54. lightning_sdk/lightning_cloud/openapi/models/uploads_upload_id_body1.py +175 -0
  55. lightning_sdk/lightning_cloud/openapi/models/v1_agent_job.py +79 -1
  56. lightning_sdk/lightning_cloud/openapi/models/v1_assistant.py +17 -69
  57. lightning_sdk/lightning_cloud/openapi/models/v1_capacity_block_offering.py +27 -1
  58. lightning_sdk/lightning_cloud/openapi/models/v1_cloud_space_artifact_event_type.py +1 -1
  59. lightning_sdk/lightning_cloud/openapi/models/v1_cluster_accelerator.py +131 -1
  60. lightning_sdk/lightning_cloud/openapi/models/v1_cluster_capacity_reservation.py +79 -1
  61. lightning_sdk/lightning_cloud/openapi/models/v1_cluster_security_options.py +27 -1
  62. lightning_sdk/lightning_cloud/openapi/models/v1_complete_upload_temporary_artifact_request.py +175 -0
  63. lightning_sdk/lightning_cloud/openapi/models/v1_create_deployment_request.py +461 -0
  64. lightning_sdk/lightning_cloud/openapi/models/v1_create_deployment_template_request.py +27 -1
  65. lightning_sdk/lightning_cloud/openapi/models/v1_create_job_request.py +201 -0
  66. lightning_sdk/lightning_cloud/openapi/models/v1_create_managed_endpoint_response.py +149 -0
  67. lightning_sdk/lightning_cloud/openapi/models/v1_create_multi_machine_job_request.py +253 -0
  68. lightning_sdk/lightning_cloud/openapi/models/v1_data_connection.py +27 -1
  69. lightning_sdk/lightning_cloud/openapi/models/v1_delete_pipeline_response.py +149 -0
  70. lightning_sdk/lightning_cloud/openapi/models/v1_deployment.py +105 -1
  71. lightning_sdk/lightning_cloud/openapi/models/v1_deployment_details.py +175 -0
  72. lightning_sdk/lightning_cloud/openapi/models/v1_deployment_template.py +53 -1
  73. lightning_sdk/lightning_cloud/openapi/models/v1_filestore_data_connection.py +201 -0
  74. lightning_sdk/lightning_cloud/openapi/models/v1_filesystem_job.py +53 -1
  75. lightning_sdk/lightning_cloud/openapi/models/v1_filesystem_mmt.py +53 -1
  76. lightning_sdk/lightning_cloud/openapi/models/v1_find_capacity_block_offering_response.py +29 -3
  77. lightning_sdk/lightning_cloud/openapi/models/v1_job.py +133 -3
  78. lightning_sdk/lightning_cloud/openapi/models/v1_job_artifacts_type.py +103 -0
  79. lightning_sdk/lightning_cloud/openapi/models/v1_job_spec.py +53 -1
  80. lightning_sdk/lightning_cloud/openapi/models/v1_job_timing.py +27 -1
  81. lightning_sdk/lightning_cloud/openapi/models/v1_list_pipelines_response.py +123 -0
  82. lightning_sdk/lightning_cloud/openapi/models/v1_lit_registry_artifact.py +27 -1
  83. lightning_sdk/lightning_cloud/openapi/models/v1_lit_repository.py +29 -1
  84. lightning_sdk/lightning_cloud/openapi/models/v1_managed_model.py +27 -1
  85. lightning_sdk/lightning_cloud/openapi/models/v1_multi_machine_job.py +27 -1
  86. lightning_sdk/lightning_cloud/openapi/models/v1_multi_machine_job_state.py +2 -0
  87. lightning_sdk/lightning_cloud/openapi/models/v1_organization.py +209 -1
  88. lightning_sdk/lightning_cloud/openapi/models/v1_pipeline.py +513 -0
  89. lightning_sdk/lightning_cloud/openapi/models/v1_pipeline_schedule.py +149 -0
  90. lightning_sdk/lightning_cloud/openapi/models/v1_pipeline_step.py +253 -0
  91. lightning_sdk/lightning_cloud/openapi/models/v1_pipeline_step_status.py +331 -0
  92. lightning_sdk/lightning_cloud/openapi/models/v1_pipeline_step_type.py +104 -0
  93. lightning_sdk/lightning_cloud/openapi/models/v1_project_settings.py +157 -1
  94. lightning_sdk/lightning_cloud/openapi/models/v1_restart_timing.py +27 -1
  95. lightning_sdk/lightning_cloud/openapi/models/v1_rule_resource.py +1 -0
  96. lightning_sdk/lightning_cloud/openapi/models/v1_shared_filesystem.py +201 -0
  97. lightning_sdk/lightning_cloud/openapi/models/v1_slurm_job.py +27 -1
  98. lightning_sdk/lightning_cloud/openapi/models/v1_update_job_visibility_response.py +97 -0
  99. lightning_sdk/lightning_cloud/openapi/models/v1_upload_temporary_artifact_request.py +123 -0
  100. lightning_sdk/lightning_cloud/openapi/models/v1_user_features.py +95 -355
  101. lightning_sdk/lightning_cloud/openapi/models/validate.py +27 -1
  102. lightning_sdk/lightning_cloud/rest_client.py +4 -2
  103. lightning_sdk/machine.py +25 -1
  104. lightning_sdk/models.py +18 -12
  105. lightning_sdk/pipeline/__init__.py +4 -0
  106. lightning_sdk/pipeline/pipeline.py +109 -0
  107. lightning_sdk/pipeline/types.py +268 -0
  108. lightning_sdk/pipeline/utils.py +69 -0
  109. lightning_sdk/plugin.py +9 -10
  110. lightning_sdk/serve.py +134 -0
  111. lightning_sdk/services/utilities.py +2 -2
  112. lightning_sdk/studio.py +5 -1
  113. lightning_sdk/teamspace.py +1 -1
  114. lightning_sdk/utils/resolve.py +12 -1
  115. {lightning_sdk-0.1.58.dist-info → lightning_sdk-0.2.1.dist-info}/METADATA +6 -8
  116. {lightning_sdk-0.1.58.dist-info → lightning_sdk-0.2.1.dist-info}/RECORD +120 -88
  117. lightning_sdk/cli/legacy.py +0 -135
  118. {lightning_sdk-0.1.58.dist-info → lightning_sdk-0.2.1.dist-info}/LICENSE +0 -0
  119. {lightning_sdk-0.1.58.dist-info → lightning_sdk-0.2.1.dist-info}/WHEEL +0 -0
  120. {lightning_sdk-0.1.58.dist-info → lightning_sdk-0.2.1.dist-info}/entry_points.txt +0 -0
  121. {lightning_sdk-0.1.58.dist-info → lightning_sdk-0.2.1.dist-info}/top_level.txt +0 -0
lightning_sdk/serve.py ADDED
@@ -0,0 +1,134 @@
1
+ import os
2
+ import warnings
3
+ from pathlib import Path
4
+
5
+ import docker
6
+ from rich.console import Console
7
+ from rich.progress import Progress
8
+
9
+ from lightning_sdk import Teamspace
10
+ from lightning_sdk.api.lit_container_api import LitContainerApi
11
+
12
+
13
+ class _LitServeDeployer:
14
+ def __init__(self) -> None:
15
+ self._console = Console()
16
+ self._client = None
17
+
18
+ @property
19
+ def client(self) -> docker.DockerClient:
20
+ if self._client is None:
21
+ try:
22
+ self._client = docker.from_env()
23
+ self._client.ping()
24
+ except docker.errors.DockerException as e:
25
+ raise RuntimeError(f"Failed to connect to Docker daemon: {e!s}. Is Docker running?") from None
26
+ return self._client
27
+
28
+ def dockerize_api(
29
+ self, server_filename: str, port: int = 8000, gpu: bool = False, tag: str = "litserve-model"
30
+ ) -> str:
31
+ import litserve as ls
32
+ from litserve import docker_builder
33
+
34
+ console = self._console
35
+ if os.path.exists("Dockerfile"):
36
+ console.print("Dockerfile already exists. Skipping generation.")
37
+ return os.path.abspath("Dockerfile")
38
+
39
+ requirements = ""
40
+ if os.path.exists("requirements.txt"):
41
+ requirements = "-r requirements.txt"
42
+ else:
43
+ warnings.warn(
44
+ f"requirements.txt not found at {os.getcwd()}. "
45
+ f"Make sure to install the required packages in the Dockerfile.",
46
+ UserWarning,
47
+ )
48
+ current_dir = Path.cwd()
49
+ if not (current_dir / server_filename).is_file():
50
+ raise FileNotFoundError(f"Server file `{server_filename}` must be in the current directory: {os.getcwd()}")
51
+
52
+ version = ls.__version__
53
+ if gpu:
54
+ run_cmd = f"docker run --gpus all -p {port}:{port} {tag}:latest"
55
+ docker_template = docker_builder.CUDA_DOCKER_TEMPLATE
56
+ else:
57
+ run_cmd = f"docker run -p {port}:{port} {tag}:latest"
58
+ docker_template = docker_builder.DOCKERFILE_TEMPLATE
59
+ dockerfile_content = docker_template.format(
60
+ server_filename=server_filename,
61
+ port=port,
62
+ version=version,
63
+ requirements=requirements,
64
+ )
65
+ with open("Dockerfile", "w") as f:
66
+ f.write(dockerfile_content)
67
+
68
+ success_msg = f"""[bold]Dockerfile created successfully[/bold]
69
+ Update [underline]{os.path.abspath("Dockerfile")}[/underline] to add any additional dependencies or commands.
70
+
71
+ [bold]Build the container with:[/bold]
72
+ > [underline]docker build -t {tag} .[/underline]
73
+
74
+ [bold]To run the Docker container on the machine:[/bold]
75
+ > [underline]{run_cmd}[/underline]
76
+
77
+ [bold]To push the container to a registry:[/bold]
78
+ > [underline]docker push {tag}[/underline]
79
+ """
80
+ console.print(success_msg)
81
+ return os.path.abspath("Dockerfile")
82
+
83
+ def generate_client(self) -> None:
84
+ console = self._console
85
+ try:
86
+ from litserve.python_client import client_template
87
+ except ImportError:
88
+ raise ImportError(
89
+ "litserve is not installed. Please install it with `pip install lightning_sdk[serve]`"
90
+ ) from None
91
+
92
+ client_path = Path("client.py")
93
+ if client_path.exists():
94
+ console.print("Skipping client generation: client.py already exists", style="blue")
95
+ else:
96
+ try:
97
+ client_path.write_text(client_template)
98
+ console.print("✅ Client generated at client.py", style="bold green")
99
+ except OSError as e:
100
+ raise OSError(f"Failed to generate client.py: {e!s}") from None
101
+
102
+ def _build_container(self, path: str, repository: str, tag: str, console: Console, progress: Progress) -> None:
103
+ build_task = progress.add_task("Building Docker image", total=None)
104
+ build_status = self.client.api.build(
105
+ path=os.path.dirname(path), dockerfile=path, tag=f"{repository}:{tag}", decode=True, quiet=False
106
+ )
107
+ for line in build_status:
108
+ if "error" in line:
109
+ progress.stop()
110
+ console.print(f"\n[red]{line}[/red]")
111
+ return
112
+ if "stream" in line and line["stream"].strip():
113
+ console.print(line["stream"].strip(), style="bright_black")
114
+ progress.update(build_task, description="Building Docker image")
115
+
116
+ progress.update(build_task, description="[green]Build completed![/green]")
117
+
118
+ def _push_container(
119
+ self, repository: str, tag: str, teamspace: Teamspace, lit_cr: LitContainerApi, progress: Progress
120
+ ) -> None:
121
+ console = self._console
122
+ push_task = progress.add_task("Pushing to registry", total=None)
123
+ console.print("\nPushing image...", style="bold blue")
124
+ lit_cr.authenticate()
125
+ push_status = lit_cr.upload_container(repository, teamspace, tag=tag)
126
+ for line in push_status:
127
+ if "error" in line:
128
+ progress.stop()
129
+ console.print(f"\n[red]{line}[/red]")
130
+ return
131
+ if "status" in line:
132
+ console.print(line["status"], style="bright_black")
133
+ progress.update(push_task, description="Pushing to registry")
134
+ progress.update(push_task, description="[green]Push completed![/green]")
@@ -6,7 +6,7 @@ import requests
6
6
  import urllib3
7
7
 
8
8
  from lightning_sdk.api.utils import _get_cloud_url
9
- from lightning_sdk.lightning_cloud.openapi import V1Membership
9
+ from lightning_sdk.lightning_cloud.openapi import V1Membership, V1ProjectClusterBinding
10
10
  from lightning_sdk.lightning_cloud.rest_client import LightningClient
11
11
 
12
12
  _CHUNK_SIZE = 1024 * 1024
@@ -35,7 +35,7 @@ def _get_project(client: LightningClient, project_name: Optional[str] = None) ->
35
35
  raise ValueError("No valid projects found. Please reach out to lightning.ai team to create a project")
36
36
 
37
37
 
38
- def _get_cluster(client: LightningClient, project_id: str, cluster_id: Optional[str] = None) -> V1Membership:
38
+ def _get_cluster(client: LightningClient, project_id: str, cluster_id: Optional[str] = None) -> V1ProjectClusterBinding:
39
39
  """Get a project membership for the user from the backend."""
40
40
  clusters = client.projects_service_list_project_cluster_bindings(project_id=project_id)
41
41
  if cluster_id:
lightning_sdk/studio.py CHANGED
@@ -160,7 +160,11 @@ class Studio:
160
160
  status = self.status
161
161
 
162
162
  if interruptible is None:
163
- interruptible = self.teamspace.start_studions_on_interruptible
163
+ interruptible_override = os.environ.get("LIGHTNING_INTERRUPTIBLE_OVERRIDE", None)
164
+ if interruptible_override is not None:
165
+ interruptible = interruptible_override.lower() == "true"
166
+ else:
167
+ interruptible = self.teamspace.start_studios_on_interruptible
164
168
 
165
169
  if status == Status.Running:
166
170
  curr_machine = _machine_to_compute_name(self.machine) if self.machine is not None else None
@@ -115,7 +115,7 @@ class Teamspace:
115
115
  return self._teamspace.project_settings.preferred_cluster
116
116
 
117
117
  @property
118
- def start_studions_on_interruptible(self) -> bool:
118
+ def start_studios_on_interruptible(self) -> bool:
119
119
  return self._teamspace.project_settings.start_studio_on_spot_instance
120
120
 
121
121
  @property
@@ -5,10 +5,12 @@ from contextlib import contextmanager
5
5
  from typing import TYPE_CHECKING, Generator, List, Optional, Tuple, Union
6
6
 
7
7
  from lightning_sdk.api import TeamspaceApi, UserApi
8
+ from lightning_sdk.api.utils import _get_cloud_url
8
9
  from lightning_sdk.machine import Machine
9
10
 
10
11
  if TYPE_CHECKING:
11
12
  from lightning_sdk.organization import Organization
13
+ from lightning_sdk.studio import Studio
12
14
  from lightning_sdk.teamspace import Teamspace
13
15
  from lightning_sdk.user import User
14
16
 
@@ -179,7 +181,7 @@ def skip_studio_init() -> Generator[None, None, None]:
179
181
  def _parse_model_and_version(name: str) -> Tuple[str, str]:
180
182
  parts = name.split(":")
181
183
  if len(parts) == 1:
182
- return parts[0], "latest"
184
+ return parts[0], "default"
183
185
  if len(parts) == 2:
184
186
  return parts[0], parts[1]
185
187
  # The rest of the validation for name and version happens in the backend
@@ -194,3 +196,12 @@ def in_studio() -> bool:
194
196
  has_cloudspace_id = bool(os.getenv("LIGHTNING_CLOUD_SPACE_ID", None))
195
197
  is_interactive = os.getenv("LIGHTNING_INTERACTIVE", "false") == "true"
196
198
  return has_cloudspace_id and is_interactive
199
+
200
+
201
+ def _get_studio_url(studio: "Studio", turn_on: bool = False) -> str:
202
+ cloud_url = _get_cloud_url().replace(":443", "")
203
+ base_url = f"{cloud_url}/{studio.owner.name}/{studio.teamspace.name}/studios/{studio.name}/code"
204
+
205
+ if turn_on:
206
+ return f"{base_url}?turnOn=true"
207
+ return base_url
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: lightning_sdk
3
- Version: 0.1.58
3
+ Version: 0.2.1
4
4
  Summary: SDK to develop using Lightning AI Studios
5
5
  Author-email: Lightning-AI <justus@lightning.ai>
6
6
  License: MIT License
@@ -32,22 +32,20 @@ Requires-Python: >=3.8
32
32
  Description-Content-Type: text/markdown
33
33
  License-File: LICENSE
34
34
  Requires-Dist: backoff
35
+ Requires-Dist: click
36
+ Requires-Dist: docker
35
37
  Requires-Dist: fastapi
38
+ Requires-Dist: packaging
36
39
  Requires-Dist: pyjwt
37
- Requires-Dist: python-multipart
38
40
  Requires-Dist: requests
39
41
  Requires-Dist: rich
42
+ Requires-Dist: simple-term-menu
40
43
  Requires-Dist: six
44
+ Requires-Dist: tqdm
41
45
  Requires-Dist: urllib3
42
46
  Requires-Dist: uvicorn
43
47
  Requires-Dist: websocket-client
44
- Requires-Dist: tqdm
45
- Requires-Dist: fire
46
- Requires-Dist: simple-term-menu
47
- Requires-Dist: lightning-utilities
48
- Requires-Dist: docker
49
48
  Requires-Dist: wget
50
- Requires-Dist: click
51
49
  Provides-Extra: serve
52
50
  Requires-Dist: litserve>=0.2.5; extra == "serve"
53
51