lightning-sdk 0.2.0__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.
- lightning_sdk/__init__.py +1 -1
- lightning_sdk/api/lit_container_api.py +16 -0
- lightning_sdk/cli/docker.py +3 -58
- lightning_sdk/cli/download.py +27 -22
- lightning_sdk/cli/serve.py +17 -53
- lightning_sdk/lightning_cloud/openapi/__init__.py +2 -0
- lightning_sdk/lightning_cloud/openapi/api/pipelines_service_api.py +5 -1
- lightning_sdk/lightning_cloud/openapi/models/__init__.py +2 -0
- lightning_sdk/lightning_cloud/openapi/models/pipelines_id_body.py +41 -15
- lightning_sdk/lightning_cloud/openapi/models/project_id_pipelines_body.py +27 -1
- lightning_sdk/lightning_cloud/openapi/models/v1_filesystem_job.py +27 -1
- lightning_sdk/lightning_cloud/openapi/models/v1_filesystem_mmt.py +27 -1
- lightning_sdk/lightning_cloud/openapi/models/v1_job_artifacts_type.py +103 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_organization.py +53 -1
- lightning_sdk/lightning_cloud/openapi/models/v1_pipeline.py +41 -15
- lightning_sdk/lightning_cloud/openapi/models/v1_pipeline_schedule.py +149 -0
- lightning_sdk/serve.py +134 -0
- {lightning_sdk-0.2.0.dist-info → lightning_sdk-0.2.1.dist-info}/METADATA +1 -1
- {lightning_sdk-0.2.0.dist-info → lightning_sdk-0.2.1.dist-info}/RECORD +23 -20
- {lightning_sdk-0.2.0.dist-info → lightning_sdk-0.2.1.dist-info}/LICENSE +0 -0
- {lightning_sdk-0.2.0.dist-info → lightning_sdk-0.2.1.dist-info}/WHEEL +0 -0
- {lightning_sdk-0.2.0.dist-info → lightning_sdk-0.2.1.dist-info}/entry_points.txt +0 -0
- {lightning_sdk-0.2.0.dist-info → lightning_sdk-0.2.1.dist-info}/top_level.txt +0 -0
|
@@ -41,6 +41,7 @@ class V1FilesystemMMT(object):
|
|
|
41
41
|
and the value is json key in definition.
|
|
42
42
|
"""
|
|
43
43
|
swagger_types = {
|
|
44
|
+
'artifacts_type': 'V1JobArtifactsType',
|
|
44
45
|
'cloud_space_id': 'str',
|
|
45
46
|
'id': 'str',
|
|
46
47
|
'jobs': 'list[V1FilesystemJob]',
|
|
@@ -48,19 +49,23 @@ class V1FilesystemMMT(object):
|
|
|
48
49
|
}
|
|
49
50
|
|
|
50
51
|
attribute_map = {
|
|
52
|
+
'artifacts_type': 'artifactsType',
|
|
51
53
|
'cloud_space_id': 'cloudSpaceId',
|
|
52
54
|
'id': 'id',
|
|
53
55
|
'jobs': 'jobs',
|
|
54
56
|
'name': 'name'
|
|
55
57
|
}
|
|
56
58
|
|
|
57
|
-
def __init__(self, cloud_space_id: 'str' =None, id: 'str' =None, jobs: 'list[V1FilesystemJob]' =None, name: 'str' =None): # noqa: E501
|
|
59
|
+
def __init__(self, artifacts_type: 'V1JobArtifactsType' =None, cloud_space_id: 'str' =None, id: 'str' =None, jobs: 'list[V1FilesystemJob]' =None, name: 'str' =None): # noqa: E501
|
|
58
60
|
"""V1FilesystemMMT - a model defined in Swagger""" # noqa: E501
|
|
61
|
+
self._artifacts_type = None
|
|
59
62
|
self._cloud_space_id = None
|
|
60
63
|
self._id = None
|
|
61
64
|
self._jobs = None
|
|
62
65
|
self._name = None
|
|
63
66
|
self.discriminator = None
|
|
67
|
+
if artifacts_type is not None:
|
|
68
|
+
self.artifacts_type = artifacts_type
|
|
64
69
|
if cloud_space_id is not None:
|
|
65
70
|
self.cloud_space_id = cloud_space_id
|
|
66
71
|
if id is not None:
|
|
@@ -70,6 +75,27 @@ class V1FilesystemMMT(object):
|
|
|
70
75
|
if name is not None:
|
|
71
76
|
self.name = name
|
|
72
77
|
|
|
78
|
+
@property
|
|
79
|
+
def artifacts_type(self) -> 'V1JobArtifactsType':
|
|
80
|
+
"""Gets the artifacts_type of this V1FilesystemMMT. # noqa: E501
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
:return: The artifacts_type of this V1FilesystemMMT. # noqa: E501
|
|
84
|
+
:rtype: V1JobArtifactsType
|
|
85
|
+
"""
|
|
86
|
+
return self._artifacts_type
|
|
87
|
+
|
|
88
|
+
@artifacts_type.setter
|
|
89
|
+
def artifacts_type(self, artifacts_type: 'V1JobArtifactsType'):
|
|
90
|
+
"""Sets the artifacts_type of this V1FilesystemMMT.
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
:param artifacts_type: The artifacts_type of this V1FilesystemMMT. # noqa: E501
|
|
94
|
+
:type: V1JobArtifactsType
|
|
95
|
+
"""
|
|
96
|
+
|
|
97
|
+
self._artifacts_type = artifacts_type
|
|
98
|
+
|
|
73
99
|
@property
|
|
74
100
|
def cloud_space_id(self) -> 'str':
|
|
75
101
|
"""Gets the cloud_space_id of this V1FilesystemMMT. # noqa: E501
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
|
|
3
|
+
"""
|
|
4
|
+
external/v1/auth_service.proto
|
|
5
|
+
|
|
6
|
+
No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) # noqa: E501
|
|
7
|
+
|
|
8
|
+
OpenAPI spec version: version not set
|
|
9
|
+
|
|
10
|
+
Generated by: https://github.com/swagger-api/swagger-codegen.git
|
|
11
|
+
|
|
12
|
+
NOTE
|
|
13
|
+
----
|
|
14
|
+
standard swagger-codegen-cli for this python client has been modified
|
|
15
|
+
by custom templates. The purpose of these templates is to include
|
|
16
|
+
typing information in the API and Model code. Please refer to the
|
|
17
|
+
main grid repository for more info
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
import pprint
|
|
21
|
+
import re # noqa: F401
|
|
22
|
+
|
|
23
|
+
from typing import TYPE_CHECKING
|
|
24
|
+
|
|
25
|
+
import six
|
|
26
|
+
|
|
27
|
+
if TYPE_CHECKING:
|
|
28
|
+
from datetime import datetime
|
|
29
|
+
from lightning_sdk.lightning_cloud.openapi.models import *
|
|
30
|
+
|
|
31
|
+
class V1JobArtifactsType(object):
|
|
32
|
+
"""NOTE: This class is auto generated by the swagger code generator program.
|
|
33
|
+
|
|
34
|
+
Do not edit the class manually.
|
|
35
|
+
"""
|
|
36
|
+
|
|
37
|
+
"""
|
|
38
|
+
allowed enum values
|
|
39
|
+
"""
|
|
40
|
+
V1 = "V1"
|
|
41
|
+
V2 = "V2"
|
|
42
|
+
"""
|
|
43
|
+
Attributes:
|
|
44
|
+
swagger_types (dict): The key is attribute name
|
|
45
|
+
and the value is attribute type.
|
|
46
|
+
attribute_map (dict): The key is attribute name
|
|
47
|
+
and the value is json key in definition.
|
|
48
|
+
"""
|
|
49
|
+
swagger_types = {
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
attribute_map = {
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
def __init__(self): # noqa: E501
|
|
56
|
+
"""V1JobArtifactsType - a model defined in Swagger""" # noqa: E501
|
|
57
|
+
self.discriminator = None
|
|
58
|
+
|
|
59
|
+
def to_dict(self) -> dict:
|
|
60
|
+
"""Returns the model properties as a dict"""
|
|
61
|
+
result = {}
|
|
62
|
+
|
|
63
|
+
for attr, _ in six.iteritems(self.swagger_types):
|
|
64
|
+
value = getattr(self, attr)
|
|
65
|
+
if isinstance(value, list):
|
|
66
|
+
result[attr] = list(map(
|
|
67
|
+
lambda x: x.to_dict() if hasattr(x, "to_dict") else x,
|
|
68
|
+
value
|
|
69
|
+
))
|
|
70
|
+
elif hasattr(value, "to_dict"):
|
|
71
|
+
result[attr] = value.to_dict()
|
|
72
|
+
elif isinstance(value, dict):
|
|
73
|
+
result[attr] = dict(map(
|
|
74
|
+
lambda item: (item[0], item[1].to_dict())
|
|
75
|
+
if hasattr(item[1], "to_dict") else item,
|
|
76
|
+
value.items()
|
|
77
|
+
))
|
|
78
|
+
else:
|
|
79
|
+
result[attr] = value
|
|
80
|
+
if issubclass(V1JobArtifactsType, dict):
|
|
81
|
+
for key, value in self.items():
|
|
82
|
+
result[key] = value
|
|
83
|
+
|
|
84
|
+
return result
|
|
85
|
+
|
|
86
|
+
def to_str(self) -> str:
|
|
87
|
+
"""Returns the string representation of the model"""
|
|
88
|
+
return pprint.pformat(self.to_dict())
|
|
89
|
+
|
|
90
|
+
def __repr__(self) -> str:
|
|
91
|
+
"""For `print` and `pprint`"""
|
|
92
|
+
return self.to_str()
|
|
93
|
+
|
|
94
|
+
def __eq__(self, other: 'V1JobArtifactsType') -> bool:
|
|
95
|
+
"""Returns true if both objects are equal"""
|
|
96
|
+
if not isinstance(other, V1JobArtifactsType):
|
|
97
|
+
return False
|
|
98
|
+
|
|
99
|
+
return self.__dict__ == other.__dict__
|
|
100
|
+
|
|
101
|
+
def __ne__(self, other: 'V1JobArtifactsType') -> bool:
|
|
102
|
+
"""Returns true if both objects are not equal"""
|
|
103
|
+
return not self == other
|
|
@@ -57,6 +57,8 @@ class V1Organization(object):
|
|
|
57
57
|
'domain': 'str',
|
|
58
58
|
'email': 'str',
|
|
59
59
|
'featured_gallery': 'bool',
|
|
60
|
+
'full_story_end_date': 'datetime',
|
|
61
|
+
'full_story_start_date': 'datetime',
|
|
60
62
|
'id': 'str',
|
|
61
63
|
'location': 'str',
|
|
62
64
|
'name': 'str',
|
|
@@ -86,6 +88,8 @@ class V1Organization(object):
|
|
|
86
88
|
'domain': 'domain',
|
|
87
89
|
'email': 'email',
|
|
88
90
|
'featured_gallery': 'featuredGallery',
|
|
91
|
+
'full_story_end_date': 'fullStoryEndDate',
|
|
92
|
+
'full_story_start_date': 'fullStoryStartDate',
|
|
89
93
|
'id': 'id',
|
|
90
94
|
'location': 'location',
|
|
91
95
|
'name': 'name',
|
|
@@ -98,7 +102,7 @@ class V1Organization(object):
|
|
|
98
102
|
'updated_at': 'updatedAt'
|
|
99
103
|
}
|
|
100
104
|
|
|
101
|
-
def __init__(self, allow_aws_saas: 'bool' =None, allow_gcp_saas: 'bool' =None, allow_guest: 'bool' =None, allow_lambda_saas: 'bool' =None, allow_member_invitations: 'bool' =None, allow_member_teamspace_creation: 'bool' =None, allow_vultr_saas: 'bool' =None, auto_invite_by_domain: 'bool' =None, auto_join_domain_validations: 'dict(str, V1AutoJoinDomainValidation)' =None, auto_join_domains: 'list[str]' =None, created_at: 'datetime' =None, description: 'str' =None, display_name: 'str' =None, domain: 'str' =None, email: 'str' =None, featured_gallery: 'bool' =None, id: 'str' =None, location: 'str' =None, name: 'str' =None, preferred_cluster: 'str' =None, preferred_deployment_provider: 'str' =None, preferred_studio_provider: 'str' =None, start_studios_on_spot_instance: 'bool' =None, teamspace_default_credits: 'float' =None, twitter_username: 'str' =None, updated_at: 'datetime' =None): # noqa: E501
|
|
105
|
+
def __init__(self, allow_aws_saas: 'bool' =None, allow_gcp_saas: 'bool' =None, allow_guest: 'bool' =None, allow_lambda_saas: 'bool' =None, allow_member_invitations: 'bool' =None, allow_member_teamspace_creation: 'bool' =None, allow_vultr_saas: 'bool' =None, auto_invite_by_domain: 'bool' =None, auto_join_domain_validations: 'dict(str, V1AutoJoinDomainValidation)' =None, auto_join_domains: 'list[str]' =None, created_at: 'datetime' =None, description: 'str' =None, display_name: 'str' =None, domain: 'str' =None, email: 'str' =None, featured_gallery: 'bool' =None, full_story_end_date: 'datetime' =None, full_story_start_date: 'datetime' =None, id: 'str' =None, location: 'str' =None, name: 'str' =None, preferred_cluster: 'str' =None, preferred_deployment_provider: 'str' =None, preferred_studio_provider: 'str' =None, start_studios_on_spot_instance: 'bool' =None, teamspace_default_credits: 'float' =None, twitter_username: 'str' =None, updated_at: 'datetime' =None): # noqa: E501
|
|
102
106
|
"""V1Organization - a model defined in Swagger""" # noqa: E501
|
|
103
107
|
self._allow_aws_saas = None
|
|
104
108
|
self._allow_gcp_saas = None
|
|
@@ -116,6 +120,8 @@ class V1Organization(object):
|
|
|
116
120
|
self._domain = None
|
|
117
121
|
self._email = None
|
|
118
122
|
self._featured_gallery = None
|
|
123
|
+
self._full_story_end_date = None
|
|
124
|
+
self._full_story_start_date = None
|
|
119
125
|
self._id = None
|
|
120
126
|
self._location = None
|
|
121
127
|
self._name = None
|
|
@@ -159,6 +165,10 @@ class V1Organization(object):
|
|
|
159
165
|
self.email = email
|
|
160
166
|
if featured_gallery is not None:
|
|
161
167
|
self.featured_gallery = featured_gallery
|
|
168
|
+
if full_story_end_date is not None:
|
|
169
|
+
self.full_story_end_date = full_story_end_date
|
|
170
|
+
if full_story_start_date is not None:
|
|
171
|
+
self.full_story_start_date = full_story_start_date
|
|
162
172
|
if id is not None:
|
|
163
173
|
self.id = id
|
|
164
174
|
if location is not None:
|
|
@@ -516,6 +526,48 @@ class V1Organization(object):
|
|
|
516
526
|
|
|
517
527
|
self._featured_gallery = featured_gallery
|
|
518
528
|
|
|
529
|
+
@property
|
|
530
|
+
def full_story_end_date(self) -> 'datetime':
|
|
531
|
+
"""Gets the full_story_end_date of this V1Organization. # noqa: E501
|
|
532
|
+
|
|
533
|
+
|
|
534
|
+
:return: The full_story_end_date of this V1Organization. # noqa: E501
|
|
535
|
+
:rtype: datetime
|
|
536
|
+
"""
|
|
537
|
+
return self._full_story_end_date
|
|
538
|
+
|
|
539
|
+
@full_story_end_date.setter
|
|
540
|
+
def full_story_end_date(self, full_story_end_date: 'datetime'):
|
|
541
|
+
"""Sets the full_story_end_date of this V1Organization.
|
|
542
|
+
|
|
543
|
+
|
|
544
|
+
:param full_story_end_date: The full_story_end_date of this V1Organization. # noqa: E501
|
|
545
|
+
:type: datetime
|
|
546
|
+
"""
|
|
547
|
+
|
|
548
|
+
self._full_story_end_date = full_story_end_date
|
|
549
|
+
|
|
550
|
+
@property
|
|
551
|
+
def full_story_start_date(self) -> 'datetime':
|
|
552
|
+
"""Gets the full_story_start_date of this V1Organization. # noqa: E501
|
|
553
|
+
|
|
554
|
+
|
|
555
|
+
:return: The full_story_start_date of this V1Organization. # noqa: E501
|
|
556
|
+
:rtype: datetime
|
|
557
|
+
"""
|
|
558
|
+
return self._full_story_start_date
|
|
559
|
+
|
|
560
|
+
@full_story_start_date.setter
|
|
561
|
+
def full_story_start_date(self, full_story_start_date: 'datetime'):
|
|
562
|
+
"""Sets the full_story_start_date of this V1Organization.
|
|
563
|
+
|
|
564
|
+
|
|
565
|
+
:param full_story_start_date: The full_story_start_date of this V1Organization. # noqa: E501
|
|
566
|
+
:type: datetime
|
|
567
|
+
"""
|
|
568
|
+
|
|
569
|
+
self._full_story_start_date = full_story_start_date
|
|
570
|
+
|
|
519
571
|
@property
|
|
520
572
|
def id(self) -> 'str':
|
|
521
573
|
"""Gets the id of this V1Organization. # noqa: E501
|
|
@@ -48,8 +48,9 @@ class V1Pipeline(object):
|
|
|
48
48
|
'id': 'str',
|
|
49
49
|
'message': 'str',
|
|
50
50
|
'name': 'str',
|
|
51
|
-
'
|
|
51
|
+
'parent_pipeline_id': 'str',
|
|
52
52
|
'project_id': 'str',
|
|
53
|
+
'schedules': 'list[V1PipelineSchedule]',
|
|
53
54
|
'shared_filesystem': 'V1SharedFilesystem',
|
|
54
55
|
'state': 'str',
|
|
55
56
|
'statuses': 'list[V1PipelineStepStatus]',
|
|
@@ -66,8 +67,9 @@ class V1Pipeline(object):
|
|
|
66
67
|
'id': 'id',
|
|
67
68
|
'message': 'message',
|
|
68
69
|
'name': 'name',
|
|
69
|
-
'
|
|
70
|
+
'parent_pipeline_id': 'parentPipelineId',
|
|
70
71
|
'project_id': 'projectId',
|
|
72
|
+
'schedules': 'schedules',
|
|
71
73
|
'shared_filesystem': 'sharedFilesystem',
|
|
72
74
|
'state': 'state',
|
|
73
75
|
'statuses': 'statuses',
|
|
@@ -76,7 +78,7 @@ class V1Pipeline(object):
|
|
|
76
78
|
'user_id': 'userId'
|
|
77
79
|
}
|
|
78
80
|
|
|
79
|
-
def __init__(self, cluster_id: 'str' =None, created_at: 'datetime' =None, display_name: 'str' =None, error: 'str' =None, id: 'str' =None, message: 'str' =None, name: 'str' =None,
|
|
81
|
+
def __init__(self, cluster_id: 'str' =None, created_at: 'datetime' =None, display_name: 'str' =None, error: 'str' =None, id: 'str' =None, message: 'str' =None, name: 'str' =None, parent_pipeline_id: 'str' =None, project_id: 'str' =None, schedules: 'list[V1PipelineSchedule]' =None, shared_filesystem: 'V1SharedFilesystem' =None, state: 'str' =None, statuses: 'list[V1PipelineStepStatus]' =None, steps: 'list[V1PipelineStep]' =None, updated_at: 'datetime' =None, user_id: 'str' =None): # noqa: E501
|
|
80
82
|
"""V1Pipeline - a model defined in Swagger""" # noqa: E501
|
|
81
83
|
self._cluster_id = None
|
|
82
84
|
self._created_at = None
|
|
@@ -85,8 +87,9 @@ class V1Pipeline(object):
|
|
|
85
87
|
self._id = None
|
|
86
88
|
self._message = None
|
|
87
89
|
self._name = None
|
|
88
|
-
self.
|
|
90
|
+
self._parent_pipeline_id = None
|
|
89
91
|
self._project_id = None
|
|
92
|
+
self._schedules = None
|
|
90
93
|
self._shared_filesystem = None
|
|
91
94
|
self._state = None
|
|
92
95
|
self._statuses = None
|
|
@@ -108,10 +111,12 @@ class V1Pipeline(object):
|
|
|
108
111
|
self.message = message
|
|
109
112
|
if name is not None:
|
|
110
113
|
self.name = name
|
|
111
|
-
if
|
|
112
|
-
self.
|
|
114
|
+
if parent_pipeline_id is not None:
|
|
115
|
+
self.parent_pipeline_id = parent_pipeline_id
|
|
113
116
|
if project_id is not None:
|
|
114
117
|
self.project_id = project_id
|
|
118
|
+
if schedules is not None:
|
|
119
|
+
self.schedules = schedules
|
|
115
120
|
if shared_filesystem is not None:
|
|
116
121
|
self.shared_filesystem = shared_filesystem
|
|
117
122
|
if state is not None:
|
|
@@ -273,25 +278,25 @@ class V1Pipeline(object):
|
|
|
273
278
|
self._name = name
|
|
274
279
|
|
|
275
280
|
@property
|
|
276
|
-
def
|
|
277
|
-
"""Gets the
|
|
281
|
+
def parent_pipeline_id(self) -> 'str':
|
|
282
|
+
"""Gets the parent_pipeline_id of this V1Pipeline. # noqa: E501
|
|
278
283
|
|
|
279
284
|
|
|
280
|
-
:return: The
|
|
285
|
+
:return: The parent_pipeline_id of this V1Pipeline. # noqa: E501
|
|
281
286
|
:rtype: str
|
|
282
287
|
"""
|
|
283
|
-
return self.
|
|
288
|
+
return self._parent_pipeline_id
|
|
284
289
|
|
|
285
|
-
@
|
|
286
|
-
def
|
|
287
|
-
"""Sets the
|
|
290
|
+
@parent_pipeline_id.setter
|
|
291
|
+
def parent_pipeline_id(self, parent_pipeline_id: 'str'):
|
|
292
|
+
"""Sets the parent_pipeline_id of this V1Pipeline.
|
|
288
293
|
|
|
289
294
|
|
|
290
|
-
:param
|
|
295
|
+
:param parent_pipeline_id: The parent_pipeline_id of this V1Pipeline. # noqa: E501
|
|
291
296
|
:type: str
|
|
292
297
|
"""
|
|
293
298
|
|
|
294
|
-
self.
|
|
299
|
+
self._parent_pipeline_id = parent_pipeline_id
|
|
295
300
|
|
|
296
301
|
@property
|
|
297
302
|
def project_id(self) -> 'str':
|
|
@@ -314,6 +319,27 @@ class V1Pipeline(object):
|
|
|
314
319
|
|
|
315
320
|
self._project_id = project_id
|
|
316
321
|
|
|
322
|
+
@property
|
|
323
|
+
def schedules(self) -> 'list[V1PipelineSchedule]':
|
|
324
|
+
"""Gets the schedules of this V1Pipeline. # noqa: E501
|
|
325
|
+
|
|
326
|
+
|
|
327
|
+
:return: The schedules of this V1Pipeline. # noqa: E501
|
|
328
|
+
:rtype: list[V1PipelineSchedule]
|
|
329
|
+
"""
|
|
330
|
+
return self._schedules
|
|
331
|
+
|
|
332
|
+
@schedules.setter
|
|
333
|
+
def schedules(self, schedules: 'list[V1PipelineSchedule]'):
|
|
334
|
+
"""Sets the schedules of this V1Pipeline.
|
|
335
|
+
|
|
336
|
+
|
|
337
|
+
:param schedules: The schedules of this V1Pipeline. # noqa: E501
|
|
338
|
+
:type: list[V1PipelineSchedule]
|
|
339
|
+
"""
|
|
340
|
+
|
|
341
|
+
self._schedules = schedules
|
|
342
|
+
|
|
317
343
|
@property
|
|
318
344
|
def shared_filesystem(self) -> 'V1SharedFilesystem':
|
|
319
345
|
"""Gets the shared_filesystem of this V1Pipeline. # noqa: E501
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
|
|
3
|
+
"""
|
|
4
|
+
external/v1/auth_service.proto
|
|
5
|
+
|
|
6
|
+
No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) # noqa: E501
|
|
7
|
+
|
|
8
|
+
OpenAPI spec version: version not set
|
|
9
|
+
|
|
10
|
+
Generated by: https://github.com/swagger-api/swagger-codegen.git
|
|
11
|
+
|
|
12
|
+
NOTE
|
|
13
|
+
----
|
|
14
|
+
standard swagger-codegen-cli for this python client has been modified
|
|
15
|
+
by custom templates. The purpose of these templates is to include
|
|
16
|
+
typing information in the API and Model code. Please refer to the
|
|
17
|
+
main grid repository for more info
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
import pprint
|
|
21
|
+
import re # noqa: F401
|
|
22
|
+
|
|
23
|
+
from typing import TYPE_CHECKING
|
|
24
|
+
|
|
25
|
+
import six
|
|
26
|
+
|
|
27
|
+
if TYPE_CHECKING:
|
|
28
|
+
from datetime import datetime
|
|
29
|
+
from lightning_sdk.lightning_cloud.openapi.models import *
|
|
30
|
+
|
|
31
|
+
class V1PipelineSchedule(object):
|
|
32
|
+
"""NOTE: This class is auto generated by the swagger code generator program.
|
|
33
|
+
|
|
34
|
+
Do not edit the class manually.
|
|
35
|
+
"""
|
|
36
|
+
"""
|
|
37
|
+
Attributes:
|
|
38
|
+
swagger_types (dict): The key is attribute name
|
|
39
|
+
and the value is attribute type.
|
|
40
|
+
attribute_map (dict): The key is attribute name
|
|
41
|
+
and the value is json key in definition.
|
|
42
|
+
"""
|
|
43
|
+
swagger_types = {
|
|
44
|
+
'cron_expression': 'str',
|
|
45
|
+
'id': 'str'
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
attribute_map = {
|
|
49
|
+
'cron_expression': 'cronExpression',
|
|
50
|
+
'id': 'id'
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
def __init__(self, cron_expression: 'str' =None, id: 'str' =None): # noqa: E501
|
|
54
|
+
"""V1PipelineSchedule - a model defined in Swagger""" # noqa: E501
|
|
55
|
+
self._cron_expression = None
|
|
56
|
+
self._id = None
|
|
57
|
+
self.discriminator = None
|
|
58
|
+
if cron_expression is not None:
|
|
59
|
+
self.cron_expression = cron_expression
|
|
60
|
+
if id is not None:
|
|
61
|
+
self.id = id
|
|
62
|
+
|
|
63
|
+
@property
|
|
64
|
+
def cron_expression(self) -> 'str':
|
|
65
|
+
"""Gets the cron_expression of this V1PipelineSchedule. # noqa: E501
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
:return: The cron_expression of this V1PipelineSchedule. # noqa: E501
|
|
69
|
+
:rtype: str
|
|
70
|
+
"""
|
|
71
|
+
return self._cron_expression
|
|
72
|
+
|
|
73
|
+
@cron_expression.setter
|
|
74
|
+
def cron_expression(self, cron_expression: 'str'):
|
|
75
|
+
"""Sets the cron_expression of this V1PipelineSchedule.
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
:param cron_expression: The cron_expression of this V1PipelineSchedule. # noqa: E501
|
|
79
|
+
:type: str
|
|
80
|
+
"""
|
|
81
|
+
|
|
82
|
+
self._cron_expression = cron_expression
|
|
83
|
+
|
|
84
|
+
@property
|
|
85
|
+
def id(self) -> 'str':
|
|
86
|
+
"""Gets the id of this V1PipelineSchedule. # noqa: E501
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
:return: The id of this V1PipelineSchedule. # noqa: E501
|
|
90
|
+
:rtype: str
|
|
91
|
+
"""
|
|
92
|
+
return self._id
|
|
93
|
+
|
|
94
|
+
@id.setter
|
|
95
|
+
def id(self, id: 'str'):
|
|
96
|
+
"""Sets the id of this V1PipelineSchedule.
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
:param id: The id of this V1PipelineSchedule. # noqa: E501
|
|
100
|
+
:type: str
|
|
101
|
+
"""
|
|
102
|
+
|
|
103
|
+
self._id = id
|
|
104
|
+
|
|
105
|
+
def to_dict(self) -> dict:
|
|
106
|
+
"""Returns the model properties as a dict"""
|
|
107
|
+
result = {}
|
|
108
|
+
|
|
109
|
+
for attr, _ in six.iteritems(self.swagger_types):
|
|
110
|
+
value = getattr(self, attr)
|
|
111
|
+
if isinstance(value, list):
|
|
112
|
+
result[attr] = list(map(
|
|
113
|
+
lambda x: x.to_dict() if hasattr(x, "to_dict") else x,
|
|
114
|
+
value
|
|
115
|
+
))
|
|
116
|
+
elif hasattr(value, "to_dict"):
|
|
117
|
+
result[attr] = value.to_dict()
|
|
118
|
+
elif isinstance(value, dict):
|
|
119
|
+
result[attr] = dict(map(
|
|
120
|
+
lambda item: (item[0], item[1].to_dict())
|
|
121
|
+
if hasattr(item[1], "to_dict") else item,
|
|
122
|
+
value.items()
|
|
123
|
+
))
|
|
124
|
+
else:
|
|
125
|
+
result[attr] = value
|
|
126
|
+
if issubclass(V1PipelineSchedule, dict):
|
|
127
|
+
for key, value in self.items():
|
|
128
|
+
result[key] = value
|
|
129
|
+
|
|
130
|
+
return result
|
|
131
|
+
|
|
132
|
+
def to_str(self) -> str:
|
|
133
|
+
"""Returns the string representation of the model"""
|
|
134
|
+
return pprint.pformat(self.to_dict())
|
|
135
|
+
|
|
136
|
+
def __repr__(self) -> str:
|
|
137
|
+
"""For `print` and `pprint`"""
|
|
138
|
+
return self.to_str()
|
|
139
|
+
|
|
140
|
+
def __eq__(self, other: 'V1PipelineSchedule') -> bool:
|
|
141
|
+
"""Returns true if both objects are equal"""
|
|
142
|
+
if not isinstance(other, V1PipelineSchedule):
|
|
143
|
+
return False
|
|
144
|
+
|
|
145
|
+
return self.__dict__ == other.__dict__
|
|
146
|
+
|
|
147
|
+
def __ne__(self, other: 'V1PipelineSchedule') -> bool:
|
|
148
|
+
"""Returns true if both objects are not equal"""
|
|
149
|
+
return not self == other
|
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]")
|