peak-sdk 1.2.1__py3-none-any.whl → 1.4.0__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.
- peak/__init__.py +1 -1
- peak/_metadata.py +43 -0
- peak/_version.py +1 -1
- peak/cli/args.py +9 -0
- peak/cli/cli.py +2 -1
- peak/cli/helpers.py +50 -1
- peak/cli/press/apps/deployments.py +6 -2
- peak/cli/press/apps/specs.py +4 -2
- peak/cli/press/blocks/deployments.py +43 -2
- peak/cli/press/blocks/specs.py +4 -4
- peak/cli/resources/services.py +632 -0
- peak/cli/resources/webapps.py +75 -14
- peak/cli/resources/workflows.py +0 -4
- peak/output.py +9 -0
- peak/press/blocks.py +105 -13
- peak/resources/__init__.py +2 -2
- peak/resources/services.py +413 -0
- peak/resources/webapps.py +13 -7
- peak/resources/workflows.py +0 -4
- peak/sample_yaml/resources/services/create_or_update_service.yaml +24 -0
- peak/sample_yaml/resources/services/create_service.yaml +24 -0
- peak/sample_yaml/resources/services/test_service.yaml +8 -0
- peak/sample_yaml/resources/services/update_service.yaml +22 -0
- peak/sample_yaml/resources/workflows/create_or_update_workflow.yaml +0 -1
- peak/sample_yaml/resources/workflows/update_workflow.yaml +0 -1
- peak/template.py +9 -1
- {peak_sdk-1.2.1.dist-info → peak_sdk-1.4.0.dist-info}/LICENSE +1 -1
- {peak_sdk-1.2.1.dist-info → peak_sdk-1.4.0.dist-info}/METADATA +2 -2
- {peak_sdk-1.2.1.dist-info → peak_sdk-1.4.0.dist-info}/RECORD +31 -25
- {peak_sdk-1.2.1.dist-info → peak_sdk-1.4.0.dist-info}/WHEEL +0 -0
- {peak_sdk-1.2.1.dist-info → peak_sdk-1.4.0.dist-info}/entry_points.txt +0 -0
@@ -0,0 +1,413 @@
|
|
1
|
+
#
|
2
|
+
# # Copyright © 2024 Peak AI Limited. or its affiliates. All Rights Reserved.
|
3
|
+
# #
|
4
|
+
# # Licensed under the Apache License, Version 2.0 (the "License"). You
|
5
|
+
# # may not use this file except in compliance with the License. A copy of
|
6
|
+
# # the License is located at:
|
7
|
+
# #
|
8
|
+
# # https://github.com/PeakBI/peak-sdk/blob/main/LICENSE
|
9
|
+
# #
|
10
|
+
# # or in the "license" file accompanying this file. This file is
|
11
|
+
# # distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
|
12
|
+
# # ANY KIND, either express or implied. See the License for the specific
|
13
|
+
# # language governing permissions and limitations under the License.
|
14
|
+
# #
|
15
|
+
# # This file is part of the peak-sdk.
|
16
|
+
# # see (https://github.com/PeakBI/peak-sdk)
|
17
|
+
# #
|
18
|
+
# # You should have received a copy of the APACHE LICENSE, VERSION 2.0
|
19
|
+
# # along with this program. If not, see <https://apache.org/licenses/LICENSE-2.0>
|
20
|
+
#
|
21
|
+
|
22
|
+
"""Service client module."""
|
23
|
+
from __future__ import annotations
|
24
|
+
|
25
|
+
from typing import Any, Dict, Iterator, List, Literal, Optional, overload
|
26
|
+
|
27
|
+
from peak.base_client import BaseClient
|
28
|
+
from peak.constants import ContentType, HttpMethods
|
29
|
+
from peak.session import Session
|
30
|
+
|
31
|
+
|
32
|
+
class Service(BaseClient):
|
33
|
+
"""Client class for interacting with services resource."""
|
34
|
+
|
35
|
+
BASE_ENDPOINT = "webapps/api/v1"
|
36
|
+
|
37
|
+
@overload
|
38
|
+
def list_services(
|
39
|
+
self,
|
40
|
+
page_size: Optional[int] = None,
|
41
|
+
page_number: Optional[int] = None,
|
42
|
+
status: Optional[List[str]] = None,
|
43
|
+
name: Optional[str] = None,
|
44
|
+
service_type: Optional[List[str]] = None,
|
45
|
+
*,
|
46
|
+
return_iterator: Literal[False],
|
47
|
+
) -> Dict[str, Any]:
|
48
|
+
...
|
49
|
+
|
50
|
+
@overload
|
51
|
+
def list_services(
|
52
|
+
self,
|
53
|
+
page_size: Optional[int] = None,
|
54
|
+
page_number: Optional[int] = None,
|
55
|
+
status: Optional[List[str]] = None,
|
56
|
+
name: Optional[str] = None,
|
57
|
+
service_type: Optional[List[str]] = None,
|
58
|
+
*,
|
59
|
+
return_iterator: Literal[True] = True,
|
60
|
+
) -> Iterator[Dict[str, Any]]:
|
61
|
+
...
|
62
|
+
|
63
|
+
def list_services(
|
64
|
+
self,
|
65
|
+
page_size: Optional[int] = None,
|
66
|
+
page_number: Optional[int] = None,
|
67
|
+
status: Optional[List[str]] = None,
|
68
|
+
name: Optional[str] = None,
|
69
|
+
service_type: Optional[List[str]] = None,
|
70
|
+
*,
|
71
|
+
return_iterator: bool = True,
|
72
|
+
) -> Iterator[Dict[str, Any]] | Dict[str, Any]:
|
73
|
+
"""Retrieve a list of services.
|
74
|
+
|
75
|
+
REFERENCE:
|
76
|
+
🔗 `API Documentation <https://service.peak.ai/webapps/api-docs/index.htm#/Services/list-service>`__
|
77
|
+
|
78
|
+
Args:
|
79
|
+
page_size (int | None): The number of services per page.
|
80
|
+
page_number (int | None): The page number to retrieve. Only used when `return_iterator` is False.
|
81
|
+
status (List[str] | None): A list of service status to filter the list by.
|
82
|
+
Valid values are `CREATING`, `DEPLOYING`, `AVAILABLE`, `DELETING`, `CREATE_FAILED`, `DELETE_FAILED`.
|
83
|
+
name (str | None): Name of the service to search for.
|
84
|
+
service_type (List[str] | None): A list of service types to filter the list by. Valid values are `api`, `web-app` and `shiny`.
|
85
|
+
return_iterator (bool): Whether to return an iterator object or list of services for a specified page number, defaults to True.
|
86
|
+
|
87
|
+
Returns:
|
88
|
+
Iterator[Dict[str, Any] | Dict[str, Any]: an iterator object which returns an element per iteration, until there are no more elements to return.
|
89
|
+
If `return_iterator` is set to False, a dictionary containing the list and pagination details is returned instead.
|
90
|
+
Set `return_iterator` to True if you want automatic client-side pagination, or False if you want server-side pagination.
|
91
|
+
|
92
|
+
Raises:
|
93
|
+
BadRequestException: The given request parameters are invalid.
|
94
|
+
UnauthorizedException: The credentials are invalid.
|
95
|
+
ForbiddenException: The user does not have permission to perform the operation.
|
96
|
+
InternalServerErrorException: The server failed to process the request.
|
97
|
+
"""
|
98
|
+
method, endpoint = HttpMethods.GET, f"{self.BASE_ENDPOINT}/webapps/"
|
99
|
+
params = {
|
100
|
+
"pageSize": page_size,
|
101
|
+
"status": status,
|
102
|
+
"searchTerm": name,
|
103
|
+
"serviceType": service_type,
|
104
|
+
"featureType": "services",
|
105
|
+
}
|
106
|
+
|
107
|
+
if return_iterator:
|
108
|
+
return self.session.create_generator_request(
|
109
|
+
endpoint,
|
110
|
+
method,
|
111
|
+
content_type=ContentType.APPLICATION_JSON,
|
112
|
+
response_key="services",
|
113
|
+
params=params,
|
114
|
+
)
|
115
|
+
|
116
|
+
return self.session.create_request( # type: ignore[no-any-return]
|
117
|
+
endpoint,
|
118
|
+
method,
|
119
|
+
content_type=ContentType.APPLICATION_JSON,
|
120
|
+
params={**params, "pageNumber": page_number},
|
121
|
+
)
|
122
|
+
|
123
|
+
def create_service(self, body: Dict[str, Any]) -> Dict[str, str]:
|
124
|
+
"""Create a new service.
|
125
|
+
|
126
|
+
REFERENCE:
|
127
|
+
🔗 `API Documentation <https://service.peak.ai/webapps/api-docs/index.htm#/Services/create-service>`__
|
128
|
+
|
129
|
+
Args:
|
130
|
+
body (Dict[str, Any]): A dictionary containing the service config. Schema can be found below.
|
131
|
+
|
132
|
+
Returns:
|
133
|
+
Dict[str, str]: Id of the new service
|
134
|
+
|
135
|
+
SCHEMA:
|
136
|
+
.. code-block:: json
|
137
|
+
|
138
|
+
{
|
139
|
+
"name": "string(required)",
|
140
|
+
"title": "string",
|
141
|
+
"serviceType": "string. Valid values are 'api', 'web-app' and 'shiny'",
|
142
|
+
"imageDetails": {
|
143
|
+
"imageId": "number(required)",
|
144
|
+
"versionId": "number"
|
145
|
+
},
|
146
|
+
"resources": {
|
147
|
+
"instanceTypeId": "number"
|
148
|
+
},
|
149
|
+
"parameters": {
|
150
|
+
"env": {
|
151
|
+
"key: string": "value: string"
|
152
|
+
},
|
153
|
+
"secrets": []
|
154
|
+
},
|
155
|
+
"description": "string",
|
156
|
+
"sessionStickiness": "boolean. Not required for 'api' service type.",
|
157
|
+
"entrypoint": "string",
|
158
|
+
"healthCheckURL": "string"
|
159
|
+
}
|
160
|
+
|
161
|
+
Raises:
|
162
|
+
BadRequestException: The given request parameters are invalid.
|
163
|
+
UnauthorizedException: The credentials are invalid.
|
164
|
+
ForbiddenException: The user does not have permission to perform the operation.
|
165
|
+
InternalServerErrorException: The server failed to process the request.
|
166
|
+
"""
|
167
|
+
method, endpoint = HttpMethods.POST, f"{self.BASE_ENDPOINT}/webapps/"
|
168
|
+
|
169
|
+
return self.session.create_request( # type: ignore[no-any-return]
|
170
|
+
endpoint,
|
171
|
+
method,
|
172
|
+
content_type=ContentType.APPLICATION_JSON,
|
173
|
+
body=body,
|
174
|
+
)
|
175
|
+
|
176
|
+
def update_service(
|
177
|
+
self,
|
178
|
+
service_id: str,
|
179
|
+
body: Dict[str, Any],
|
180
|
+
) -> Dict[str, str]:
|
181
|
+
"""Updates the existing service.
|
182
|
+
|
183
|
+
When updating the service, it will trigger a redeployment only under specific conditions.
|
184
|
+
Redeployment is triggered if you make changes to any of the following parameters: imageId, versionId, instanceTypeId, parameters, healthCheckURL, entrypoint or sessionStickiness.
|
185
|
+
However, only modifying the title or description will not trigger a redeployment.
|
186
|
+
|
187
|
+
With the help of this operation, we can just update the required fields (except name and serviceType) and keep the rest of the fields as it is.
|
188
|
+
|
189
|
+
REFERENCE:
|
190
|
+
🔗 `API Documentation <https://service.peak.ai/webapps/api-docs/index.htm#/Services/update-service>`__
|
191
|
+
|
192
|
+
Args:
|
193
|
+
service_id (str): The ID of the service to update.
|
194
|
+
body (Dict[str, Any]): A dictionary containing the service config. Schema can be found below.
|
195
|
+
|
196
|
+
Returns:
|
197
|
+
Dict[str, str]: Id of the service.
|
198
|
+
|
199
|
+
SCHEMA:
|
200
|
+
.. code-block:: json
|
201
|
+
|
202
|
+
{
|
203
|
+
"title": "string",
|
204
|
+
"imageDetails": {
|
205
|
+
"imageId": "number(required)",
|
206
|
+
"versionId": "number",
|
207
|
+
},
|
208
|
+
"resources": {
|
209
|
+
"instanceTypeId": "number"
|
210
|
+
},
|
211
|
+
"parameters": {
|
212
|
+
"env": {
|
213
|
+
"key: string": "value: string",
|
214
|
+
},
|
215
|
+
"secrets": []
|
216
|
+
},
|
217
|
+
"description": "string",
|
218
|
+
"sessionStickiness": "boolean. Not required for 'api' service type.",
|
219
|
+
"entrypoint": "string",
|
220
|
+
"healthCheckURL": "string",
|
221
|
+
}
|
222
|
+
|
223
|
+
Raises:
|
224
|
+
BadRequestException: The given request parameters are invalid.
|
225
|
+
UnauthorizedException: The credentials are invalid.
|
226
|
+
ForbiddenException: The user does not have permission to perform the operation.
|
227
|
+
NotFoundException: The given service does not exist.
|
228
|
+
UnprocessableEntityException: The server was unable to process the request.
|
229
|
+
InternalServerErrorException: The server failed to process the request.
|
230
|
+
"""
|
231
|
+
method, endpoint = HttpMethods.PATCH, f"{self.BASE_ENDPOINT}/webapps/{service_id}"
|
232
|
+
return self.session.create_request( # type: ignore[no-any-return]
|
233
|
+
endpoint,
|
234
|
+
method,
|
235
|
+
content_type=ContentType.APPLICATION_JSON,
|
236
|
+
body=body,
|
237
|
+
)
|
238
|
+
|
239
|
+
def create_or_update_service(self, body: Dict[str, Any]) -> Dict[str, str]:
|
240
|
+
"""Create a new service or updates an existing service based on service name.
|
241
|
+
|
242
|
+
When updating the service, it will trigger a redeployment only under specific conditions.
|
243
|
+
Redeployment is triggered if you make changes to any of the following parameters: imageId, versionId, instanceTypeId, parameters, healthCheckURL, entrypoint or sessionStickiness.
|
244
|
+
However, only modifying the title or description will not trigger a redeployment.
|
245
|
+
|
246
|
+
REFERENCE:
|
247
|
+
🔗 `API Documentation <https://service.peak.ai/webapps/api-docs/index.htm#/Services/create-service>`__
|
248
|
+
|
249
|
+
Args:
|
250
|
+
body (Dict[str, Any]): A dictionary containing the service config. Schema can be found below.
|
251
|
+
|
252
|
+
Returns:
|
253
|
+
Dict[str, str]: Id of the new or updated service.
|
254
|
+
|
255
|
+
SCHEMA:
|
256
|
+
.. code-block:: json
|
257
|
+
|
258
|
+
{
|
259
|
+
"name": "string(required)",
|
260
|
+
"title": "string",
|
261
|
+
"serviceType": "string. Valid values are 'api', 'web-app' and 'shiny'",
|
262
|
+
"imageDetails": {
|
263
|
+
"imageId": "number(required)",
|
264
|
+
"versionId": "number"
|
265
|
+
},
|
266
|
+
"resources": {
|
267
|
+
"instanceTypeId": "number"
|
268
|
+
},
|
269
|
+
"parameters": {
|
270
|
+
"env": {
|
271
|
+
"key: string": "value: string",
|
272
|
+
},
|
273
|
+
"secrets": []
|
274
|
+
},
|
275
|
+
"description": "string",
|
276
|
+
"sessionStickiness": "boolean. Not required for 'api' service type.",
|
277
|
+
"entrypoint": "string",
|
278
|
+
"healthCheckURL": "string",
|
279
|
+
}
|
280
|
+
|
281
|
+
|
282
|
+
Raises:
|
283
|
+
BadRequestException: The given request parameters are invalid.
|
284
|
+
UnauthorizedException: The credentials are invalid.
|
285
|
+
ForbiddenException: The user does not have permission to perform the operation.
|
286
|
+
InternalServerErrorException: The server failed to process the request.
|
287
|
+
"""
|
288
|
+
service_name = body["name"] if "name" in body else ""
|
289
|
+
response = (
|
290
|
+
{} if not len(service_name) else self.list_services(page_size=100, return_iterator=False, name=service_name)
|
291
|
+
)
|
292
|
+
filtered_services = list(
|
293
|
+
filter(lambda service: service.get("name", "") == service_name, response.get("services", [])),
|
294
|
+
)
|
295
|
+
|
296
|
+
if len(filtered_services) > 0:
|
297
|
+
service_id = filtered_services[0]["id"]
|
298
|
+
return self.update_service(service_id=service_id, body=body)
|
299
|
+
|
300
|
+
return self.create_service(body=body)
|
301
|
+
|
302
|
+
def delete_service(
|
303
|
+
self,
|
304
|
+
service_id: str,
|
305
|
+
) -> Dict[str, str]:
|
306
|
+
"""Delete a service.
|
307
|
+
|
308
|
+
REFERENCE:
|
309
|
+
🔗 `API Documentation <https://service.peak.ai/webapps/api-docs/index.htm#/Services/delete-service>`__
|
310
|
+
|
311
|
+
Args:
|
312
|
+
service_id (str): The ID of the service to delete.
|
313
|
+
|
314
|
+
Returns:
|
315
|
+
Dict[str, str]: Dictonary containing ID of the deleted service.
|
316
|
+
|
317
|
+
Raises:
|
318
|
+
UnauthorizedException: The credentials are invalid.
|
319
|
+
ForbiddenException: The user does not have permission to perform the operation.
|
320
|
+
NotFoundException: The given service does not exist.
|
321
|
+
ConflictException: If the service is in a conflicting state while deleting.
|
322
|
+
InternalServerErrorException: The server failed to process the request.
|
323
|
+
"""
|
324
|
+
method, endpoint = HttpMethods.DELETE, f"{self.BASE_ENDPOINT}/webapps/{service_id}"
|
325
|
+
|
326
|
+
return self.session.create_request( # type: ignore[no-any-return]
|
327
|
+
endpoint,
|
328
|
+
method,
|
329
|
+
content_type=ContentType.APPLICATION_JSON,
|
330
|
+
)
|
331
|
+
|
332
|
+
def describe_service(
|
333
|
+
self,
|
334
|
+
service_id: str,
|
335
|
+
) -> Dict[str, Any]:
|
336
|
+
"""Retrieve details of a specific service.
|
337
|
+
|
338
|
+
REFERENCE:
|
339
|
+
🔗 `API Documentation <https://service.peak.ai/webapps/api-docs/index.htm#/Services/get-service>`__
|
340
|
+
|
341
|
+
Args:
|
342
|
+
service_id (str): The ID of the service to fetch.
|
343
|
+
|
344
|
+
Returns:
|
345
|
+
Dict[str, Any]: Dictonary containing details of the service.
|
346
|
+
|
347
|
+
Raises:
|
348
|
+
UnauthorizedException: The credentials are invalid.
|
349
|
+
ForbiddenException: The user does not have permission to perform the operation.
|
350
|
+
NotFoundException: The given service does not exist.
|
351
|
+
UnprocessableEntityException: The server was unable to process the request.
|
352
|
+
InternalServerErrorException: The server failed to process the request.
|
353
|
+
"""
|
354
|
+
method, endpoint = HttpMethods.GET, f"{self.BASE_ENDPOINT}/webapps/{service_id}"
|
355
|
+
|
356
|
+
return self.session.create_request( # type: ignore[no-any-return]
|
357
|
+
endpoint,
|
358
|
+
method,
|
359
|
+
content_type=ContentType.APPLICATION_JSON,
|
360
|
+
)
|
361
|
+
|
362
|
+
def test_service(
|
363
|
+
self,
|
364
|
+
service_name: str,
|
365
|
+
http_method: str,
|
366
|
+
path: Optional[str] = None,
|
367
|
+
payload: Optional[Dict[str, Any]] = None,
|
368
|
+
) -> Dict[str, Any]:
|
369
|
+
"""Test an API service to verify it's health and if it is working. Make sure the service is of type "api".
|
370
|
+
|
371
|
+
REFERENCE:
|
372
|
+
🔗 `API Documentation <https://service.peak.ai/webapps/api-docs/index.htm#/Services/test-api-service>`__
|
373
|
+
|
374
|
+
Args:
|
375
|
+
service_name (str): The name of the API type service to test.
|
376
|
+
http_method (str): The HTTP method to use for the test. Valid values are 'get', 'post', 'put', 'patch' and 'delete'.
|
377
|
+
path (str, None): The path to test the service with. Default is '/'.
|
378
|
+
payload (Dict[str, Any], None): The payload to test the service with.
|
379
|
+
|
380
|
+
Returns:
|
381
|
+
Dict[str, Any]: Dictonary containing response of the test.
|
382
|
+
|
383
|
+
Raises:
|
384
|
+
UnauthorizedException: The credentials are invalid.
|
385
|
+
ForbiddenException: The user does not have permission to perform the operation.
|
386
|
+
NotFoundException: The given service does not exist.
|
387
|
+
UnprocessableEntityException: The server was unable to process the request.
|
388
|
+
InternalServerErrorException: The server failed to process the request.
|
389
|
+
"""
|
390
|
+
method, endpoint = HttpMethods.POST, f"{self.BASE_ENDPOINT}/webapps/{service_name}/test"
|
391
|
+
body = {"httpMethod": http_method, "path": path, "payload": payload}
|
392
|
+
|
393
|
+
return self.session.create_request( # type: ignore[no-any-return]
|
394
|
+
endpoint,
|
395
|
+
method,
|
396
|
+
content_type=ContentType.APPLICATION_JSON,
|
397
|
+
body=body,
|
398
|
+
)
|
399
|
+
|
400
|
+
|
401
|
+
def get_client(session: Optional[Session] = None) -> Service:
|
402
|
+
"""Returns a Service client, If no session is provided, a default session is used.
|
403
|
+
|
404
|
+
Args:
|
405
|
+
session (Optional[Session]): A Session Object. Default is None.
|
406
|
+
|
407
|
+
Returns:
|
408
|
+
Service: The service client object.
|
409
|
+
"""
|
410
|
+
return Service(session)
|
411
|
+
|
412
|
+
|
413
|
+
__all__ = ["get_client"]
|
peak/resources/webapps.py
CHANGED
@@ -19,7 +19,13 @@
|
|
19
19
|
# # along with this program. If not, see <https://apache.org/licenses/LICENSE-2.0>
|
20
20
|
#
|
21
21
|
|
22
|
-
"""Webapp client module.
|
22
|
+
"""Webapp client module.
|
23
|
+
|
24
|
+
.. warning::
|
25
|
+
The ``Webapp`` module is deprecated and will eventually be removed. It is recommended that users begin transitioning to the ``Service`` module, which offers all the features of ``Webapp`` along with the added capability of API deployment and other significant updates for enhanced functionality. Transitioning early to the ``Service`` module will ensure easier adoption of its advanced features and future updates.
|
26
|
+
|
27
|
+
For guidance on migrating to the ``Service`` module and taking full advantage of its capabilities, please refer to the ``Service`` module's documentation.
|
28
|
+
"""
|
23
29
|
from __future__ import annotations
|
24
30
|
|
25
31
|
from typing import Any, Dict, Iterator, List, Literal, Optional, overload
|
@@ -70,7 +76,7 @@ class Webapp(BaseClient):
|
|
70
76
|
"""Retrieve a list of webapps.
|
71
77
|
|
72
78
|
REFERENCE:
|
73
|
-
🔗 `API Documentation <https://service.peak.ai/webapps/api-docs/index.htm#/
|
79
|
+
🔗 `API Documentation <https://service.peak.ai/webapps/api-docs/index.htm#/Services/list-service>`__
|
74
80
|
|
75
81
|
Args:
|
76
82
|
page_size (int | None): The number of webapps per page.
|
@@ -114,7 +120,7 @@ class Webapp(BaseClient):
|
|
114
120
|
"""Create a new webapp. Only geneic (EKS-based) webapps are supported at the moment.
|
115
121
|
|
116
122
|
REFERENCE:
|
117
|
-
🔗 `API Documentation <https://service.peak.ai/webapps/api-docs/index.htm#/
|
123
|
+
🔗 `API Documentation <https://service.peak.ai/webapps/api-docs/index.htm#/Services/create-service>`__
|
118
124
|
|
119
125
|
Args:
|
120
126
|
body (Dict[str, Any]): A dictionary containing the webapp config. Schema can be found below.
|
@@ -166,7 +172,7 @@ class Webapp(BaseClient):
|
|
166
172
|
However, only modifying the title or description will not trigger a redeployment.
|
167
173
|
|
168
174
|
REFERENCE:
|
169
|
-
🔗 `API Documentation <https://service.peak.ai/webapps/api-docs/index.htm#/
|
175
|
+
🔗 `API Documentation <https://service.peak.ai/webapps/api-docs/index.htm#/Services/update-service>`__
|
170
176
|
|
171
177
|
Args:
|
172
178
|
webapp_id (str): The ID of the webapp to update.
|
@@ -215,7 +221,7 @@ class Webapp(BaseClient):
|
|
215
221
|
However, only modifying the title or description will not trigger a redeployment.
|
216
222
|
|
217
223
|
REFERENCE:
|
218
|
-
🔗 `API Documentation <https://service.peak.ai/webapps/api-docs/index.htm#/
|
224
|
+
🔗 `API Documentation <https://service.peak.ai/webapps/api-docs/index.htm#/Services/create-service>`__
|
219
225
|
|
220
226
|
Args:
|
221
227
|
body (Dict[str, Any]): A dictionary containing the webapp config. Schema can be found below.
|
@@ -268,7 +274,7 @@ class Webapp(BaseClient):
|
|
268
274
|
"""Delete a webapp.
|
269
275
|
|
270
276
|
REFERENCE:
|
271
|
-
🔗 `API Documentation <https://service.peak.ai/webapps/api-docs/index.htm#/
|
277
|
+
🔗 `API Documentation <https://service.peak.ai/webapps/api-docs/index.htm#/Services/delete-service>`__
|
272
278
|
|
273
279
|
Args:
|
274
280
|
webapp_id (str): The ID of the webapp to delete.
|
@@ -298,7 +304,7 @@ class Webapp(BaseClient):
|
|
298
304
|
"""Retrieve details of a specific webapp.
|
299
305
|
|
300
306
|
REFERENCE:
|
301
|
-
🔗 `API Documentation <https://service.peak.ai/webapps/api-docs/index.htm#/
|
307
|
+
🔗 `API Documentation <https://service.peak.ai/webapps/api-docs/index.htm#/Services/get-service>`__
|
302
308
|
|
303
309
|
Args:
|
304
310
|
webapp_id (str): The ID of the webapp to fetch.
|
peak/resources/workflows.py
CHANGED
@@ -156,7 +156,6 @@ class Workflow(BaseClient):
|
|
156
156
|
},
|
157
157
|
{
|
158
158
|
"webhook": "boolean",
|
159
|
-
"webhookPolicy": "string"
|
160
159
|
}
|
161
160
|
],
|
162
161
|
"watchers": [
|
@@ -286,7 +285,6 @@ class Workflow(BaseClient):
|
|
286
285
|
},
|
287
286
|
{
|
288
287
|
"webhook": "boolean",
|
289
|
-
"webhookPolicy": "string"
|
290
288
|
}
|
291
289
|
],
|
292
290
|
"watchers": [
|
@@ -455,7 +453,6 @@ class Workflow(BaseClient):
|
|
455
453
|
},
|
456
454
|
{
|
457
455
|
"webhook": "boolean",
|
458
|
-
"webhookPolicy": "string"
|
459
456
|
}
|
460
457
|
],
|
461
458
|
"watchers": [
|
@@ -617,7 +614,6 @@ class Workflow(BaseClient):
|
|
617
614
|
},
|
618
615
|
{
|
619
616
|
"webhook": "boolean",
|
620
|
-
"webhookPolicy": "string"
|
621
617
|
}
|
622
618
|
],
|
623
619
|
"watchers": [
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# service.yaml
|
2
|
+
|
3
|
+
body:
|
4
|
+
name: my-service
|
5
|
+
title: New service
|
6
|
+
description: This is a new service
|
7
|
+
serviceType: web-app
|
8
|
+
imageDetails:
|
9
|
+
imageId: 100
|
10
|
+
versionId: 100
|
11
|
+
resources:
|
12
|
+
instanceTypeId: 43
|
13
|
+
parameters:
|
14
|
+
env:
|
15
|
+
param1: value1
|
16
|
+
param2: value2
|
17
|
+
secrets:
|
18
|
+
- secret1
|
19
|
+
- secret2
|
20
|
+
sessionStickiness: true
|
21
|
+
entrypoint: |
|
22
|
+
python
|
23
|
+
app.py
|
24
|
+
healthCheckURL: /health
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# service.yaml
|
2
|
+
|
3
|
+
body:
|
4
|
+
name: my-service
|
5
|
+
title: New service
|
6
|
+
description: This is a new service
|
7
|
+
serviceType: web-app
|
8
|
+
imageDetails:
|
9
|
+
imageId: 100
|
10
|
+
versionId: 100
|
11
|
+
resources:
|
12
|
+
instanceTypeId: 43
|
13
|
+
parameters:
|
14
|
+
env:
|
15
|
+
param1: value1
|
16
|
+
param2: value2
|
17
|
+
secrets:
|
18
|
+
- secret1
|
19
|
+
- secret2
|
20
|
+
sessionStickiness: true
|
21
|
+
entrypoint: |
|
22
|
+
python
|
23
|
+
app.py
|
24
|
+
healthCheckURL: /health
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# service.yaml
|
2
|
+
|
3
|
+
body:
|
4
|
+
title: Updated service
|
5
|
+
description: This is an updated service
|
6
|
+
imageDetails:
|
7
|
+
imageId: 200
|
8
|
+
versionId: 200
|
9
|
+
resources:
|
10
|
+
instanceTypeId: 43
|
11
|
+
parameters:
|
12
|
+
env:
|
13
|
+
param1: value1
|
14
|
+
param2: value2
|
15
|
+
secrets:
|
16
|
+
- secret1
|
17
|
+
- secret2
|
18
|
+
sessionStickiness: true
|
19
|
+
entrypoint: |
|
20
|
+
python
|
21
|
+
app.py
|
22
|
+
healthCheckURL: /health
|
peak/template.py
CHANGED
@@ -47,7 +47,11 @@ def _parse_jinja_template(template_path: Path, params: Dict[str, Any]) -> str:
|
|
47
47
|
return jinja_template.render(params, os_env=os.environ)
|
48
48
|
|
49
49
|
|
50
|
-
def load_template(
|
50
|
+
def load_template(
|
51
|
+
file: Union[Path, str],
|
52
|
+
params: Optional[Dict[str, Any]] = None,
|
53
|
+
description: Optional[str] = None,
|
54
|
+
) -> Dict[str, Any]:
|
51
55
|
"""Load a template file through `Jinja` into a dictionary.
|
52
56
|
|
53
57
|
This function performs the following steps:
|
@@ -60,6 +64,7 @@ def load_template(file: Union[Path, str], params: Optional[Dict[str, Any]]) -> D
|
|
60
64
|
Args:
|
61
65
|
file (Union[Path, str]): Path to the templated `YAML` file to be loaded.
|
62
66
|
params (Dict[str, Any] | None, optional): Named parameters to be passed to Jinja. Defaults to `{}`.
|
67
|
+
description ([str]): The description from the file extracted and added to the payload.
|
63
68
|
|
64
69
|
Returns:
|
65
70
|
Dict[str, Any]: Dictionary containing the rendered YAML file
|
@@ -68,6 +73,9 @@ def load_template(file: Union[Path, str], params: Optional[Dict[str, Any]]) -> D
|
|
68
73
|
file = Path(file)
|
69
74
|
template: str = _parse_jinja_template(file, params)
|
70
75
|
parsed_data: Dict[str, Any] = yaml.safe_load(template)
|
76
|
+
if description:
|
77
|
+
parsed_data["body"]["metadata"]["description"] = description
|
78
|
+
|
71
79
|
return remove_none_values(parsed_data)
|
72
80
|
|
73
81
|
|
@@ -186,7 +186,7 @@
|
|
186
186
|
same "printed page" as the copyright notice for easier
|
187
187
|
identification within third-party archives.
|
188
188
|
|
189
|
-
Copyright ©
|
189
|
+
Copyright © 2024 Peak-AI
|
190
190
|
|
191
191
|
Licensed under the Apache License, Version 2.0 (the "License");
|
192
192
|
you may not use this file except in compliance with the License.
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: peak-sdk
|
3
|
-
Version: 1.
|
3
|
+
Version: 1.4.0
|
4
4
|
Summary: Python SDK for interacting with the Peak platform
|
5
5
|
Home-page: https://docs.peak.ai/sdk
|
6
6
|
License: Apache-2.0
|
@@ -28,7 +28,7 @@ Requires-Dist: pyyaml (>=6.0,<7.0)
|
|
28
28
|
Requires-Dist: requests (>=2.30,<3.0)
|
29
29
|
Requires-Dist: requests-toolbelt (>=1.0,<2.0)
|
30
30
|
Requires-Dist: shellingham (<1.5.2)
|
31
|
-
Requires-Dist: structlog (>=
|
31
|
+
Requires-Dist: structlog (>=24.1.0,<25.0.0)
|
32
32
|
Requires-Dist: typer[all] (>=0.9,<0.10)
|
33
33
|
Requires-Dist: urllib3 (<2)
|
34
34
|
Project-URL: Documentation, https://docs.peak.ai/sdk/
|