peak-sdk 1.4.0__py3-none-any.whl → 1.6.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/_metadata.py +58 -3
- peak/_version.py +1 -1
- peak/cli/cli.py +4 -2
- peak/cli/helpers.py +2 -0
- peak/cli/press/blocks/specs.py +2 -2
- peak/cli/press/specs.py +4 -2
- peak/cli/resources/alerts/__init__.py +35 -0
- peak/cli/resources/alerts/emails.py +360 -0
- peak/cli/resources/images.py +1 -1
- peak/cli/resources/services.py +23 -0
- peak/cli/resources/users.py +71 -0
- peak/cli/resources/workflows.py +77 -15
- peak/cli/ruff.toml +5 -3
- peak/compression.py +2 -2
- peak/exceptions.py +4 -6
- peak/handler.py +3 -5
- peak/helpers.py +35 -9
- peak/output.py +2 -2
- peak/press/apps.py +8 -16
- peak/press/blocks.py +8 -16
- peak/press/deployments.py +2 -4
- peak/press/specs.py +12 -14
- peak/resources/__init__.py +3 -2
- peak/resources/alerts.py +309 -0
- peak/resources/artifacts.py +2 -4
- peak/resources/images.py +8 -14
- peak/resources/services.py +7 -6
- peak/resources/users.py +93 -0
- peak/resources/webapps.py +3 -5
- peak/resources/workflows.py +106 -16
- peak/sample_yaml/resources/emails/send_email.yaml +15 -0
- peak/sample_yaml/resources/services/create_or_update_service.yaml +1 -0
- peak/sample_yaml/resources/services/create_service.yaml +1 -0
- peak/sample_yaml/resources/services/update_service.yaml +1 -0
- peak/sample_yaml/resources/workflows/create_or_update_workflow.yaml +28 -0
- peak/sample_yaml/resources/workflows/create_workflow.yaml +10 -0
- peak/sample_yaml/resources/workflows/patch_workflow.yaml +28 -0
- peak/sample_yaml/resources/workflows/update_workflow.yaml +28 -0
- peak/session.py +7 -4
- peak/telemetry.py +1 -1
- peak/template.py +6 -4
- peak/tools/logging/__init__.py +26 -268
- peak/tools/logging/log_level.py +35 -3
- peak/tools/logging/logger.py +389 -0
- peak/validators.py +34 -2
- {peak_sdk-1.4.0.dist-info → peak_sdk-1.6.0.dist-info}/METADATA +11 -12
- {peak_sdk-1.4.0.dist-info → peak_sdk-1.6.0.dist-info}/RECORD +50 -43
- {peak_sdk-1.4.0.dist-info → peak_sdk-1.6.0.dist-info}/WHEEL +1 -1
- {peak_sdk-1.4.0.dist-info → peak_sdk-1.6.0.dist-info}/LICENSE +0 -0
- {peak_sdk-1.4.0.dist-info → peak_sdk-1.6.0.dist-info}/entry_points.txt +0 -0
peak/resources/workflows.py
CHANGED
@@ -19,6 +19,7 @@
|
|
19
19
|
# # along with this program. If not, see <https://apache.org/licenses/LICENSE-2.0>
|
20
20
|
#
|
21
21
|
"""Workflow client module."""
|
22
|
+
|
22
23
|
from __future__ import annotations
|
23
24
|
|
24
25
|
from typing import Any, Dict, Iterator, List, Literal, Optional, overload
|
@@ -51,8 +52,7 @@ class Workflow(BaseClient):
|
|
51
52
|
name: Optional[str] = None,
|
52
53
|
*,
|
53
54
|
return_iterator: Literal[False],
|
54
|
-
) -> Dict[str, Any]:
|
55
|
-
...
|
55
|
+
) -> Dict[str, Any]: ...
|
56
56
|
|
57
57
|
@overload
|
58
58
|
def list_workflows(
|
@@ -65,8 +65,7 @@ class Workflow(BaseClient):
|
|
65
65
|
name: Optional[str] = None,
|
66
66
|
*,
|
67
67
|
return_iterator: Literal[True] = True,
|
68
|
-
) -> Iterator[Dict[str, Any]]:
|
69
|
-
...
|
68
|
+
) -> Iterator[Dict[str, Any]]: ...
|
70
69
|
|
71
70
|
def list_workflows(
|
72
71
|
self: Workflow,
|
@@ -166,10 +165,30 @@ class Workflow(BaseClient):
|
|
166
165
|
"runtimeExceeded": "number"
|
167
166
|
},
|
168
167
|
"user": "string",
|
168
|
+
},
|
169
|
+
{
|
170
|
+
"events": {
|
171
|
+
"success": "boolean",
|
172
|
+
"fail": "boolean",
|
173
|
+
"runtimeExceeded": "number"
|
174
|
+
},
|
169
175
|
"webhook": {
|
170
176
|
"name": "string(required)",
|
171
177
|
"url": "string(required)",
|
172
|
-
"payload": "string(required)"
|
178
|
+
"payload": "string(required)"
|
179
|
+
}
|
180
|
+
},
|
181
|
+
{
|
182
|
+
"events": {
|
183
|
+
"success": "boolean",
|
184
|
+
"fail": "boolean",
|
185
|
+
"runtimeExceeded": "number"
|
186
|
+
},
|
187
|
+
"email": {
|
188
|
+
"name": "string",
|
189
|
+
"recipients": {
|
190
|
+
"to": ["string"]
|
191
|
+
}
|
173
192
|
}
|
174
193
|
}
|
175
194
|
],
|
@@ -295,10 +314,30 @@ class Workflow(BaseClient):
|
|
295
314
|
"runtimeExceeded": "number"
|
296
315
|
},
|
297
316
|
"user": "string",
|
317
|
+
},
|
318
|
+
{
|
319
|
+
"events": {
|
320
|
+
"success": "boolean",
|
321
|
+
"fail": "boolean",
|
322
|
+
"runtimeExceeded": "number"
|
323
|
+
},
|
298
324
|
"webhook": {
|
299
325
|
"name": "string(required)",
|
300
326
|
"url": "string(required)",
|
301
|
-
"payload": "string(required)"
|
327
|
+
"payload": "string(required)"
|
328
|
+
}
|
329
|
+
},
|
330
|
+
{
|
331
|
+
"events": {
|
332
|
+
"success": "boolean",
|
333
|
+
"fail": "boolean",
|
334
|
+
"runtimeExceeded": "number"
|
335
|
+
},
|
336
|
+
"email": {
|
337
|
+
"name": "string",
|
338
|
+
"recipients": {
|
339
|
+
"to": ["string"]
|
340
|
+
}
|
302
341
|
}
|
303
342
|
}
|
304
343
|
],
|
@@ -382,7 +421,7 @@ class Workflow(BaseClient):
|
|
382
421
|
ForbiddenException: The user does not have permission to perform the operation.
|
383
422
|
InternalServerErrorException: The server failed to process the request.
|
384
423
|
"""
|
385
|
-
workflow_name = body
|
424
|
+
workflow_name = body.get("name", "")
|
386
425
|
response = (
|
387
426
|
{}
|
388
427
|
if not len(workflow_name)
|
@@ -463,10 +502,30 @@ class Workflow(BaseClient):
|
|
463
502
|
"runtimeExceeded": "number"
|
464
503
|
},
|
465
504
|
"user": "string",
|
505
|
+
},
|
506
|
+
{
|
507
|
+
"events": {
|
508
|
+
"success": "boolean",
|
509
|
+
"fail": "boolean",
|
510
|
+
"runtimeExceeded": "number"
|
511
|
+
},
|
466
512
|
"webhook": {
|
467
513
|
"name": "string(required)",
|
468
514
|
"url": "string(required)",
|
469
|
-
"payload": "string(required)"
|
515
|
+
"payload": "string(required)"
|
516
|
+
}
|
517
|
+
},
|
518
|
+
{
|
519
|
+
"events": {
|
520
|
+
"success": "boolean",
|
521
|
+
"fail": "boolean",
|
522
|
+
"runtimeExceeded": "number"
|
523
|
+
},
|
524
|
+
"email": {
|
525
|
+
"name": "string",
|
526
|
+
"recipients": {
|
527
|
+
"to": ["string"]
|
528
|
+
}
|
470
529
|
}
|
471
530
|
}
|
472
531
|
],
|
@@ -624,10 +683,30 @@ class Workflow(BaseClient):
|
|
624
683
|
"runtimeExceeded": "number"
|
625
684
|
},
|
626
685
|
"user": "string",
|
686
|
+
},
|
687
|
+
{
|
688
|
+
"events": {
|
689
|
+
"success": "boolean",
|
690
|
+
"fail": "boolean",
|
691
|
+
"runtimeExceeded": "number"
|
692
|
+
},
|
627
693
|
"webhook": {
|
628
694
|
"name": "string(required)",
|
629
695
|
"url": "string(required)",
|
630
|
-
"payload": "string(required)"
|
696
|
+
"payload": "string(required)"
|
697
|
+
}
|
698
|
+
},
|
699
|
+
{
|
700
|
+
"events": {
|
701
|
+
"success": "boolean",
|
702
|
+
"fail": "boolean",
|
703
|
+
"runtimeExceeded": "number"
|
704
|
+
},
|
705
|
+
"email": {
|
706
|
+
"name": "string",
|
707
|
+
"recipients": {
|
708
|
+
"to": ["string"]
|
709
|
+
}
|
631
710
|
}
|
632
711
|
}
|
633
712
|
],
|
@@ -961,12 +1040,13 @@ class Workflow(BaseClient):
|
|
961
1040
|
workflow_id: int,
|
962
1041
|
date_from: Optional[str] = None,
|
963
1042
|
date_to: Optional[str] = None,
|
1043
|
+
status: Optional[List[str]] = None,
|
1044
|
+
count: Optional[int] = None,
|
964
1045
|
page_size: Optional[int] = None,
|
965
1046
|
page_number: Optional[int] = None,
|
966
1047
|
*,
|
967
1048
|
return_iterator: Literal[False],
|
968
|
-
) -> Dict[str, Any]:
|
969
|
-
...
|
1049
|
+
) -> Dict[str, Any]: ...
|
970
1050
|
|
971
1051
|
@overload
|
972
1052
|
def list_executions(
|
@@ -974,18 +1054,21 @@ class Workflow(BaseClient):
|
|
974
1054
|
workflow_id: int,
|
975
1055
|
date_from: Optional[str] = None,
|
976
1056
|
date_to: Optional[str] = None,
|
1057
|
+
status: Optional[List[str]] = None,
|
1058
|
+
count: Optional[int] = None,
|
977
1059
|
page_size: Optional[int] = None,
|
978
1060
|
page_number: Optional[int] = None,
|
979
1061
|
*,
|
980
1062
|
return_iterator: Literal[True] = True,
|
981
|
-
) -> Iterator[Dict[str, Any]]:
|
982
|
-
...
|
1063
|
+
) -> Iterator[Dict[str, Any]]: ...
|
983
1064
|
|
984
1065
|
def list_executions(
|
985
1066
|
self: Workflow,
|
986
1067
|
workflow_id: int,
|
987
1068
|
date_from: Optional[str] = None,
|
988
1069
|
date_to: Optional[str] = None,
|
1070
|
+
status: Optional[List[str]] = None,
|
1071
|
+
count: Optional[int] = None,
|
989
1072
|
page_size: Optional[int] = None,
|
990
1073
|
page_number: Optional[int] = None,
|
991
1074
|
*,
|
@@ -1000,6 +1083,11 @@ class Workflow(BaseClient):
|
|
1000
1083
|
workflow_id (int): ID of the workflow to fetch executions.
|
1001
1084
|
date_from (str | None): The date after which the executions should be included (in ISO format). Defaults to None
|
1002
1085
|
date_to (str | None): The date till which the executions should be included (in ISO format). Defaults to None
|
1086
|
+
status (List[str] | None): The status of the executions to filter by.
|
1087
|
+
Valid values are `Success`, `Running`, `Stopped`, `Stopping` and `Failed`.
|
1088
|
+
count (int | None): Number of executions required in the provided time range or 90 days (Ordered by latest to earliest).
|
1089
|
+
For example, if 5 is provided, it will return last 5 workflow executions.
|
1090
|
+
By default, it will return all the executions.
|
1003
1091
|
page_size (int | None): Number of executions per page.
|
1004
1092
|
page_number (int | None): Page number to fetch. Only used when return_iterator is False.
|
1005
1093
|
return_iterator (bool): Whether to return an iterator object or list of executions for a specified page number, defaults to True.
|
@@ -1011,7 +1099,7 @@ class Workflow(BaseClient):
|
|
1011
1099
|
Set `return_iterator` to True if you want automatic client-side pagination, or False if you want server-side pagination.
|
1012
1100
|
|
1013
1101
|
Raises:
|
1014
|
-
BadRequestException:
|
1102
|
+
BadRequestException: The given request parameters are invalid.
|
1015
1103
|
UnauthorizedException: The credentials are invalid.
|
1016
1104
|
ForbiddenException: The user does not have permission to perform the operation.
|
1017
1105
|
NotFoundException: The given workflow does not exist.
|
@@ -1021,6 +1109,8 @@ class Workflow(BaseClient):
|
|
1021
1109
|
method, endpoint = HttpMethods.GET, f"{self.BASE_ENDPOINT}/workflows/executions/{workflow_id}"
|
1022
1110
|
|
1023
1111
|
params: Dict[str, Any] = {
|
1112
|
+
"count": count,
|
1113
|
+
"statuses": status,
|
1024
1114
|
"dateTo": date_to,
|
1025
1115
|
"dateFrom": date_from,
|
1026
1116
|
"pageSize": page_size,
|
@@ -1068,7 +1158,7 @@ class Workflow(BaseClient):
|
|
1068
1158
|
Dict[str, Any]: A dictionary containing the logs for the given execution.
|
1069
1159
|
|
1070
1160
|
Raises:
|
1071
|
-
BadRequestException:
|
1161
|
+
BadRequestException: The given request parameters are invalid.
|
1072
1162
|
UnauthorizedException: The credentials are invalid.
|
1073
1163
|
ForbiddenException: The user does not have permission to perform the operation.
|
1074
1164
|
NotFoundException: The given workflow does not exist.
|
@@ -1123,7 +1213,7 @@ class Workflow(BaseClient):
|
|
1123
1213
|
Dict[str, Any]: A dictionary containing the logs for the given execution.
|
1124
1214
|
|
1125
1215
|
Raises:
|
1126
|
-
BadRequestException:
|
1216
|
+
BadRequestException: The given request parameters are invalid.
|
1127
1217
|
UnauthorizedException: The credentials are invalid.
|
1128
1218
|
ForbiddenException: The user does not have permission to perform the operation.
|
1129
1219
|
NotFoundException: The given workflow does not exist.
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# send_email.yaml
|
2
|
+
|
3
|
+
body:
|
4
|
+
recipients:
|
5
|
+
- person1@peak.ai
|
6
|
+
- person2@peak.ai
|
7
|
+
cc:
|
8
|
+
- person3@peak.ai
|
9
|
+
bcc:
|
10
|
+
- person4@peak.ai
|
11
|
+
subject: Hello from Peak
|
12
|
+
templateName: my-email-template
|
13
|
+
templateParameters:
|
14
|
+
name: John
|
15
|
+
company: Peak
|
@@ -4,6 +4,34 @@ body:
|
|
4
4
|
name: my-new-workflow
|
5
5
|
triggers:
|
6
6
|
- webhook: true
|
7
|
+
watchers:
|
8
|
+
- user: abc@peak.ai
|
9
|
+
events:
|
10
|
+
success: false
|
11
|
+
fail: true
|
12
|
+
- webhook:
|
13
|
+
name: info
|
14
|
+
url: "https://abc.com/post"
|
15
|
+
payload: '{ "pingback-url": "https:/workflow/123" }'
|
16
|
+
events:
|
17
|
+
success: false
|
18
|
+
fail: true
|
19
|
+
runtimeExceeded: 10
|
20
|
+
- email:
|
21
|
+
name: "email-watcher-1"
|
22
|
+
recipients:
|
23
|
+
to:
|
24
|
+
- user1@peak.ai
|
25
|
+
- user2@peak.ai
|
26
|
+
events:
|
27
|
+
success: false
|
28
|
+
fail: true
|
29
|
+
runtimeExceeded: 10
|
30
|
+
retryOptions:
|
31
|
+
duration: 5
|
32
|
+
exitCodes: [1, 2]
|
33
|
+
exponentialBackoff: true
|
34
|
+
numberOfRetries: 3
|
7
35
|
tags:
|
8
36
|
- name: CLI
|
9
37
|
steps:
|
@@ -17,6 +17,16 @@ body:
|
|
17
17
|
success: false
|
18
18
|
fail: true
|
19
19
|
runtimeExceeded: 10
|
20
|
+
- email:
|
21
|
+
name: "email-watcher-1"
|
22
|
+
recipients:
|
23
|
+
to:
|
24
|
+
- user1@peak.ai
|
25
|
+
- user2@peak.ai
|
26
|
+
events:
|
27
|
+
success: false
|
28
|
+
fail: true
|
29
|
+
runtimeExceeded: 10
|
20
30
|
retryOptions:
|
21
31
|
duration: 5
|
22
32
|
exitCodes: [1, 2]
|
@@ -4,6 +4,34 @@ body:
|
|
4
4
|
name: "updated-workflow"
|
5
5
|
triggers:
|
6
6
|
- {}
|
7
|
+
watchers:
|
8
|
+
- user: abc@peak.ai
|
9
|
+
events:
|
10
|
+
success: false
|
11
|
+
fail: true
|
12
|
+
- webhook:
|
13
|
+
name: info
|
14
|
+
url: "https://abc.com/post"
|
15
|
+
payload: '{ "pingback-url": "https:/workflow/123" }'
|
16
|
+
events:
|
17
|
+
success: false
|
18
|
+
fail: true
|
19
|
+
runtimeExceeded: 10
|
20
|
+
- email:
|
21
|
+
name: "email-watcher-1"
|
22
|
+
recipients:
|
23
|
+
to:
|
24
|
+
- user1@peak.ai
|
25
|
+
- user2@peak.ai
|
26
|
+
events:
|
27
|
+
success: false
|
28
|
+
fail: true
|
29
|
+
runtimeExceeded: 10
|
30
|
+
retryOptions:
|
31
|
+
duration: 5
|
32
|
+
exitCodes: [1, 2]
|
33
|
+
exponentialBackoff: true
|
34
|
+
numberOfRetries: 3
|
7
35
|
steps:
|
8
36
|
step1:
|
9
37
|
imageId: 100
|
@@ -4,6 +4,34 @@ body:
|
|
4
4
|
name: updated-workflow
|
5
5
|
triggers:
|
6
6
|
- webhook: true
|
7
|
+
watchers:
|
8
|
+
- user: abc@peak.ai
|
9
|
+
events:
|
10
|
+
success: false
|
11
|
+
fail: true
|
12
|
+
- webhook:
|
13
|
+
name: info
|
14
|
+
url: "https://abc.com/post"
|
15
|
+
payload: '{ "pingback-url": "https:/workflow/123" }'
|
16
|
+
events:
|
17
|
+
success: false
|
18
|
+
fail: true
|
19
|
+
runtimeExceeded: 10
|
20
|
+
- email:
|
21
|
+
name: "email-watcher-1"
|
22
|
+
recipients:
|
23
|
+
to:
|
24
|
+
- user1@peak.ai
|
25
|
+
- user2@peak.ai
|
26
|
+
events:
|
27
|
+
success: false
|
28
|
+
fail: true
|
29
|
+
runtimeExceeded: 10
|
30
|
+
retryOptions:
|
31
|
+
duration: 5
|
32
|
+
exitCodes: [1, 2]
|
33
|
+
exponentialBackoff: true
|
34
|
+
numberOfRetries: 3
|
7
35
|
tags:
|
8
36
|
- name: CLI
|
9
37
|
steps:
|
peak/session.py
CHANGED
@@ -70,7 +70,7 @@ class Session:
|
|
70
70
|
|
71
71
|
Args:
|
72
72
|
auth_token (str | None): Authentication token. Both API Key and Bearer tokens are supported.
|
73
|
-
Picks up from `API_KEY` environment variable if not provided.
|
73
|
+
Picks up from `PEAK_AUTH_TOKEN` or `API_KEY` environment variable if not provided.
|
74
74
|
stage (str | None): Name of the stage where tenant is created. Default is `prod`.
|
75
75
|
"""
|
76
76
|
self.base_domain: str = ""
|
@@ -238,9 +238,12 @@ class Session:
|
|
238
238
|
self.auth_token = auth_token
|
239
239
|
return
|
240
240
|
|
241
|
-
logger.info("auth_token not given, searching for API_KEY in env variables")
|
242
|
-
if not os.environ.get("API_KEY"):
|
243
|
-
raise exceptions.MissingEnvironmentVariableException(env_var="API_KEY")
|
241
|
+
logger.info("auth_token not given, searching for 'PEAK_AUTH_TOKEN' or 'API_KEY' in env variables")
|
242
|
+
if not os.environ.get("API_KEY") and not os.environ.get("PEAK_AUTH_TOKEN"):
|
243
|
+
raise exceptions.MissingEnvironmentVariableException(env_var="PEAK_AUTH_TOKEN or API_KEY")
|
244
|
+
if os.environ.get("PEAK_AUTH_TOKEN"):
|
245
|
+
self.auth_token = os.environ["PEAK_AUTH_TOKEN"]
|
246
|
+
return
|
244
247
|
self.auth_token = os.environ["API_KEY"]
|
245
248
|
|
246
249
|
def _set_stage(self, stage: Optional[str]) -> None:
|
peak/telemetry.py
CHANGED
@@ -80,7 +80,7 @@ def telemetry(make_request: F) -> F:
|
|
80
80
|
"""
|
81
81
|
stage = Stage.PROD
|
82
82
|
if session_meta:
|
83
|
-
stage = session_meta
|
83
|
+
stage = session_meta.get("stage", Stage.PROD)
|
84
84
|
base_domain = get_base_domain(stage.value, "service")
|
85
85
|
return f"{base_domain}/resource-usage/api/v1/telemetry"
|
86
86
|
|
peak/template.py
CHANGED
@@ -38,10 +38,12 @@ from peak.helpers import remove_none_values
|
|
38
38
|
def _parse_jinja_template(template_path: Path, params: Dict[str, Any]) -> str:
|
39
39
|
"""Read, parse and render the Jinja template text."""
|
40
40
|
jinja_loader = _CustomJinjaLoader()
|
41
|
-
jinja_env =
|
42
|
-
|
43
|
-
|
44
|
-
|
41
|
+
jinja_env = (
|
42
|
+
jinja2.Environment( # TODO: show warning if variable not found in params # noqa: TD002, TD003, RUF100, FIX002
|
43
|
+
loader=jinja_loader,
|
44
|
+
autoescape=False, # noqa: S701
|
45
|
+
extensions=[_IncludeWithIndentation],
|
46
|
+
)
|
45
47
|
)
|
46
48
|
jinja_template: jinja2.Template = jinja_env.get_template(str(template_path))
|
47
49
|
return jinja_template.render(params, os_env=os.environ)
|