aws-durable-execution-sdk-python-testing 1.2.1__py3-none-any.whl → 1.3.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.
- aws_durable_execution_sdk_python_testing/__about__.py +1 -1
- aws_durable_execution_sdk_python_testing/checkpoint/core.py +171 -0
- aws_durable_execution_sdk_python_testing/checkpoint/effects.py +61 -0
- aws_durable_execution_sdk_python_testing/checkpoint/processor.py +124 -45
- aws_durable_execution_sdk_python_testing/checkpoint/processors/base.py +40 -14
- aws_durable_execution_sdk_python_testing/checkpoint/processors/callback.py +5 -2
- aws_durable_execution_sdk_python_testing/checkpoint/processors/context.py +6 -0
- aws_durable_execution_sdk_python_testing/checkpoint/processors/execution.py +4 -9
- aws_durable_execution_sdk_python_testing/checkpoint/processors/invoke.py +139 -0
- aws_durable_execution_sdk_python_testing/checkpoint/processors/step.py +15 -21
- aws_durable_execution_sdk_python_testing/checkpoint/processors/wait.py +10 -16
- aws_durable_execution_sdk_python_testing/checkpoint/transformer.py +145 -48
- aws_durable_execution_sdk_python_testing/checkpoint/validators/checkpoint.py +65 -8
- aws_durable_execution_sdk_python_testing/checkpoint/validators/operations/invoke.py +79 -18
- aws_durable_execution_sdk_python_testing/child_dispatcher.py +828 -0
- aws_durable_execution_sdk_python_testing/cli.py +48 -1
- aws_durable_execution_sdk_python_testing/client.py +21 -10
- aws_durable_execution_sdk_python_testing/clock.py +69 -0
- aws_durable_execution_sdk_python_testing/exceptions.py +14 -0
- aws_durable_execution_sdk_python_testing/execution.py +583 -49
- aws_durable_execution_sdk_python_testing/executor.py +1813 -349
- aws_durable_execution_sdk_python_testing/invoker.py +356 -85
- aws_durable_execution_sdk_python_testing/model.py +81 -73
- aws_durable_execution_sdk_python_testing/observer.py +100 -88
- aws_durable_execution_sdk_python_testing/runner.py +407 -30
- aws_durable_execution_sdk_python_testing/scheduler.py +38 -13
- aws_durable_execution_sdk_python_testing/stores/filesystem.py +10 -2
- aws_durable_execution_sdk_python_testing/stores/sqlite.py +18 -6
- aws_durable_execution_sdk_python_testing/threads.py +157 -0
- aws_durable_execution_sdk_python_testing/token.py +11 -2
- aws_durable_execution_sdk_python_testing/web/handlers.py +33 -7
- aws_durable_execution_sdk_python_testing/web/serialization.py +1 -2
- aws_durable_execution_sdk_python_testing/web/server.py +1 -1
- aws_durable_execution_sdk_python_testing/worker/__init__.py +9 -0
- aws_durable_execution_sdk_python_testing/worker/checkpoint_tasks.py +119 -0
- aws_durable_execution_sdk_python_testing/worker/execution_worker.py +117 -0
- aws_durable_execution_sdk_python_testing/worker/lane.py +118 -0
- aws_durable_execution_sdk_python_testing/worker/registry.py +124 -0
- aws_durable_execution_sdk_python_testing/worker/status.py +27 -0
- aws_durable_execution_sdk_python_testing/worker/task.py +57 -0
- {aws_durable_execution_sdk_python_testing-1.2.1.dist-info → aws_durable_execution_sdk_python_testing-1.3.0.dist-info}/METADATA +50 -58
- aws_durable_execution_sdk_python_testing-1.3.0.dist-info/RECORD +64 -0
- {aws_durable_execution_sdk_python_testing-1.2.1.dist-info → aws_durable_execution_sdk_python_testing-1.3.0.dist-info}/WHEEL +1 -1
- aws_durable_execution_sdk_python_testing/checkpoint/validators/transitions.py +0 -66
- aws_durable_execution_sdk_python_testing-1.2.1.dist-info/RECORD +0 -52
- {aws_durable_execution_sdk_python_testing-1.2.1.dist-info/licenses → aws_durable_execution_sdk_python_testing}/LICENSE +0 -0
- {aws_durable_execution_sdk_python_testing-1.2.1.dist-info/licenses → aws_durable_execution_sdk_python_testing}/NOTICE +0 -0
- {aws_durable_execution_sdk_python_testing-1.2.1.dist-info → aws_durable_execution_sdk_python_testing-1.3.0.dist-info}/entry_points.txt +0 -0
|
@@ -2,55 +2,116 @@
|
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
|
+
from typing import TYPE_CHECKING
|
|
6
|
+
|
|
5
7
|
from aws_durable_execution_sdk_python.lambda_service import (
|
|
6
8
|
Operation,
|
|
7
9
|
OperationAction,
|
|
8
|
-
OperationStatus,
|
|
9
10
|
OperationUpdate,
|
|
10
11
|
)
|
|
11
12
|
|
|
13
|
+
from aws_durable_execution_sdk_python_testing.child_dispatcher import (
|
|
14
|
+
CHAINED_INVOKE_DIFFERENT_ACCOUNT_MESSAGE,
|
|
15
|
+
CHAINED_INVOKE_DIFFERENT_REGION_MESSAGE,
|
|
16
|
+
INVALID_FUNCTION_ARN_MESSAGE_FORMAT,
|
|
17
|
+
INVALID_TENANT_ID_MESSAGE,
|
|
18
|
+
FunctionTarget,
|
|
19
|
+
is_valid_tenant_id,
|
|
20
|
+
parse_function_target,
|
|
21
|
+
)
|
|
12
22
|
from aws_durable_execution_sdk_python_testing.exceptions import (
|
|
13
23
|
InvalidParameterValueException,
|
|
14
24
|
)
|
|
15
25
|
|
|
26
|
+
if TYPE_CHECKING:
|
|
27
|
+
from aws_durable_execution_sdk_python_testing.execution import Execution
|
|
28
|
+
|
|
16
29
|
|
|
17
30
|
VALID_ACTIONS_FOR_INVOKE = frozenset(
|
|
18
31
|
[
|
|
19
32
|
OperationAction.START,
|
|
20
|
-
OperationAction.CANCEL,
|
|
21
33
|
]
|
|
22
34
|
)
|
|
23
35
|
|
|
24
36
|
|
|
25
37
|
class ChainedInvokeOperationValidator:
|
|
26
|
-
"""Validates INVOKE operation transitions.
|
|
38
|
+
"""Validates INVOKE operation transitions.
|
|
27
39
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
40
|
+
START is the only accepted action: a chained invoke completes through
|
|
41
|
+
the invoked function's terminal state, not through a handler
|
|
42
|
+
checkpoint. START also validates the options, as the service does:
|
|
43
|
+
the target must be a well-formed Lambda function name or ARN in the
|
|
44
|
+
parent's account and region, and a TenantId must satisfy the API
|
|
45
|
+
constraint.
|
|
46
|
+
"""
|
|
33
47
|
|
|
34
48
|
@staticmethod
|
|
35
|
-
def validate(
|
|
49
|
+
def validate(
|
|
50
|
+
current_state: Operation | None,
|
|
51
|
+
update: OperationUpdate,
|
|
52
|
+
execution: Execution,
|
|
53
|
+
) -> None:
|
|
36
54
|
"""Validate INVOKE operation update."""
|
|
37
55
|
match update.action:
|
|
38
56
|
case OperationAction.START:
|
|
39
57
|
if current_state is not None:
|
|
40
58
|
msg_invoke_exists: str = (
|
|
41
|
-
"Cannot start
|
|
59
|
+
"Cannot start a CHAINED_INVOKE operation that already exists."
|
|
42
60
|
)
|
|
43
61
|
|
|
44
62
|
raise InvalidParameterValueException(msg_invoke_exists)
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
63
|
+
if update.chained_invoke_options is None:
|
|
64
|
+
msg_options_required: str = (
|
|
65
|
+
"Update for CHAINED_INVOKE operation requires "
|
|
66
|
+
"ChainedInvokeOptions."
|
|
67
|
+
)
|
|
68
|
+
raise InvalidParameterValueException(msg_options_required)
|
|
69
|
+
ChainedInvokeOperationValidator._validate_target(
|
|
70
|
+
update.chained_invoke_options.function_name, execution
|
|
71
|
+
)
|
|
72
|
+
# The API model types TenantId as a string. A value of
|
|
73
|
+
# another type is a validation error, not a server error.
|
|
74
|
+
tenant_id: str | None = update.chained_invoke_options.tenant_id
|
|
75
|
+
if tenant_id is not None and (
|
|
76
|
+
not isinstance(tenant_id, str) or not is_valid_tenant_id(tenant_id)
|
|
50
77
|
):
|
|
51
|
-
|
|
52
|
-
raise InvalidParameterValueException(msg_invoke_cancel)
|
|
78
|
+
raise InvalidParameterValueException(INVALID_TENANT_ID_MESSAGE)
|
|
53
79
|
case _:
|
|
54
|
-
msg_invoke_invalid: str = "Invalid
|
|
80
|
+
msg_invoke_invalid: str = "Invalid action for CHAINED_INVOKE operation."
|
|
55
81
|
|
|
56
82
|
raise InvalidParameterValueException(msg_invoke_invalid)
|
|
83
|
+
|
|
84
|
+
@staticmethod
|
|
85
|
+
def _validate_target(function_name: str, execution: Execution) -> None:
|
|
86
|
+
"""Reject a malformed target or one in another account or region.
|
|
87
|
+
|
|
88
|
+
The region check applies only when the execution recorded a
|
|
89
|
+
region; an execution built without one skips it.
|
|
90
|
+
"""
|
|
91
|
+
# The API model requires FunctionName as a string. A missing or
|
|
92
|
+
# non-string value is a validation error, not a server error.
|
|
93
|
+
if not isinstance(function_name, str):
|
|
94
|
+
raise InvalidParameterValueException(
|
|
95
|
+
INVALID_FUNCTION_ARN_MESSAGE_FORMAT.format(function_name)
|
|
96
|
+
)
|
|
97
|
+
try:
|
|
98
|
+
target: FunctionTarget = parse_function_target(function_name)
|
|
99
|
+
except ValueError as err:
|
|
100
|
+
raise InvalidParameterValueException(
|
|
101
|
+
INVALID_FUNCTION_ARN_MESSAGE_FORMAT.format(function_name)
|
|
102
|
+
) from err
|
|
103
|
+
if (
|
|
104
|
+
target.account_id is not None
|
|
105
|
+
and target.account_id != execution.start_input.account_id
|
|
106
|
+
):
|
|
107
|
+
raise InvalidParameterValueException(
|
|
108
|
+
CHAINED_INVOKE_DIFFERENT_ACCOUNT_MESSAGE
|
|
109
|
+
)
|
|
110
|
+
if (
|
|
111
|
+
target.region is not None
|
|
112
|
+
and execution.region is not None
|
|
113
|
+
and target.region != execution.region
|
|
114
|
+
):
|
|
115
|
+
raise InvalidParameterValueException(
|
|
116
|
+
CHAINED_INVOKE_DIFFERENT_REGION_MESSAGE
|
|
117
|
+
)
|