aws-durable-execution-sdk-python 1.1.2__tar.gz → 1.4.0__tar.gz
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-1.1.2 → aws_durable_execution_sdk_python-1.4.0}/.github/workflows/ci.yml +2 -2
- {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.4.0}/.github/workflows/integration-tests.yml +3 -5
- aws_durable_execution_sdk_python-1.4.0/.github/workflows/notify_slack.yml +39 -0
- {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.4.0}/.github/workflows/pypi-publish.yml +3 -3
- {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.4.0}/.github/workflows/scorecard.yml +2 -2
- {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.4.0}/.github/workflows/sync-package.yml +2 -2
- aws_durable_execution_sdk_python-1.1.2/docs/agents.md → aws_durable_execution_sdk_python-1.4.0/AGENTS.md +4 -3
- {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.4.0}/PKG-INFO +1 -1
- {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.4.0}/docs/core/logger.md +74 -0
- {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.4.0}/docs/core/map.md +33 -82
- {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.4.0}/docs/getting-started.md +2 -1
- {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.4.0}/pyproject.toml +7 -0
- {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.4.0}/src/aws_durable_execution_sdk_python/__about__.py +1 -1
- {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.4.0}/src/aws_durable_execution_sdk_python/__init__.py +7 -1
- {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.4.0}/src/aws_durable_execution_sdk_python/concurrency/executor.py +6 -0
- {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.4.0}/src/aws_durable_execution_sdk_python/concurrency/models.py +88 -17
- {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.4.0}/src/aws_durable_execution_sdk_python/context.py +26 -5
- {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.4.0}/src/aws_durable_execution_sdk_python/logger.py +1 -1
- {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.4.0}/src/aws_durable_execution_sdk_python/operation/step.py +3 -2
- {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.4.0}/src/aws_durable_execution_sdk_python/operation/wait_for_condition.py +3 -2
- {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.4.0}/src/aws_durable_execution_sdk_python/serdes.py +1 -5
- {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.4.0}/src/aws_durable_execution_sdk_python/state.py +76 -34
- {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.4.0}/tests/concurrency_test.py +192 -49
- {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.4.0}/tests/context_test.py +161 -53
- aws_durable_execution_sdk_python-1.4.0/tests/durable_executions_python_language_sdk_test.py +15 -0
- aws_durable_execution_sdk_python-1.4.0/tests/e2e/map_with_concurrent_waits_int_test.py +200 -0
- {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.4.0}/tests/logger_test.py +2 -2
- {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.4.0}/tests/operation/map_test.py +60 -6
- {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.4.0}/tests/operation/parallel_test.py +25 -6
- {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.4.0}/tests/operation/wait_for_condition_test.py +121 -1
- {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.4.0}/tests/state_test.py +274 -10
- {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.4.0}/tests/test_helpers.py +5 -2
- aws_durable_execution_sdk_python-1.1.2/tests/durable_executions_python_language_sdk_test.py +0 -6
- {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.4.0}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
- {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.4.0}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.4.0}/.github/ISSUE_TEMPLATE/documentation.yml +0 -0
- {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.4.0}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
- {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.4.0}/.github/dependabot.yml +0 -0
- {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.4.0}/.github/workflows/lintcommit.js +0 -0
- {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.4.0}/.github/workflows/test-parser.yml +0 -0
- {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.4.0}/.gitignore +0 -0
- {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.4.0}/CODE_OF_CONDUCT.md +0 -0
- {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.4.0}/CONTRIBUTING.md +0 -0
- {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.4.0}/LICENSE +0 -0
- {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.4.0}/NOTICE +0 -0
- {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.4.0}/README.md +0 -0
- {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.4.0}/docs/advanced/error-handling.md +0 -0
- {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.4.0}/docs/advanced/serialization.md +0 -0
- {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.4.0}/docs/advanced/testing-modes.md +0 -0
- {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.4.0}/docs/api-reference/.gitkeep +0 -0
- {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.4.0}/docs/architecture.md +0 -0
- {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.4.0}/docs/best-practices.md +0 -0
- {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.4.0}/docs/core/callbacks.md +0 -0
- {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.4.0}/docs/core/child-contexts.md +0 -0
- {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.4.0}/docs/core/invoke.md +0 -0
- {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.4.0}/docs/core/parallel.md +0 -0
- {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.4.0}/docs/core/steps.md +0 -0
- {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.4.0}/docs/core/wait.md +0 -0
- {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.4.0}/docs/index.md +0 -0
- {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.4.0}/docs/testing-patterns/.gitkeep +0 -0
- {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.4.0}/docs/testing-patterns/basic-tests.md +0 -0
- {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.4.0}/docs/testing-patterns/complex-workflows.md +0 -0
- {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.4.0}/docs/testing-patterns/stores.md +0 -0
- {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.4.0}/ops/__tests__/test_parse_sdk_branch.py +0 -0
- {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.4.0}/ops/ci-checks.sh +0 -0
- {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.4.0}/ops/parse_sdk_branch.py +0 -0
- {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.4.0}/src/aws_durable_execution_sdk_python/.gitignore +0 -0
- {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.4.0}/src/aws_durable_execution_sdk_python/concurrency/__init__.py +0 -0
- {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.4.0}/src/aws_durable_execution_sdk_python/config.py +0 -0
- {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.4.0}/src/aws_durable_execution_sdk_python/exceptions.py +0 -0
- {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.4.0}/src/aws_durable_execution_sdk_python/execution.py +0 -0
- {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.4.0}/src/aws_durable_execution_sdk_python/identifier.py +0 -0
- {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.4.0}/src/aws_durable_execution_sdk_python/lambda_service.py +0 -0
- {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.4.0}/src/aws_durable_execution_sdk_python/operation/__init__.py +0 -0
- {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.4.0}/src/aws_durable_execution_sdk_python/operation/base.py +0 -0
- {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.4.0}/src/aws_durable_execution_sdk_python/operation/callback.py +0 -0
- {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.4.0}/src/aws_durable_execution_sdk_python/operation/child.py +0 -0
- {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.4.0}/src/aws_durable_execution_sdk_python/operation/invoke.py +0 -0
- {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.4.0}/src/aws_durable_execution_sdk_python/operation/map.py +0 -0
- {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.4.0}/src/aws_durable_execution_sdk_python/operation/parallel.py +0 -0
- {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.4.0}/src/aws_durable_execution_sdk_python/operation/wait.py +0 -0
- {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.4.0}/src/aws_durable_execution_sdk_python/py.typed +0 -0
- {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.4.0}/src/aws_durable_execution_sdk_python/retries.py +0 -0
- {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.4.0}/src/aws_durable_execution_sdk_python/suspend.py +0 -0
- {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.4.0}/src/aws_durable_execution_sdk_python/threading.py +0 -0
- {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.4.0}/src/aws_durable_execution_sdk_python/types.py +0 -0
- {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.4.0}/src/aws_durable_execution_sdk_python/waits.py +0 -0
- {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.4.0}/tests/__init__.py +0 -0
- {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.4.0}/tests/config_test.py +0 -0
- {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.4.0}/tests/e2e/__init__.py +0 -0
- {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.4.0}/tests/e2e/checkpoint_response_int_test.py +0 -0
- {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.4.0}/tests/e2e/execution_int_test.py +0 -0
- {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.4.0}/tests/exceptions_test.py +0 -0
- {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.4.0}/tests/execution_test.py +0 -0
- {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.4.0}/tests/lambda_service_test.py +0 -0
- {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.4.0}/tests/operation/__init__.py +0 -0
- {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.4.0}/tests/operation/base_test.py +0 -0
- {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.4.0}/tests/operation/callback_test.py +0 -0
- {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.4.0}/tests/operation/child_test.py +0 -0
- {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.4.0}/tests/operation/invoke_test.py +0 -0
- {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.4.0}/tests/operation/step_test.py +0 -0
- {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.4.0}/tests/operation/wait_test.py +0 -0
- {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.4.0}/tests/retries_test.py +0 -0
- {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.4.0}/tests/serdes_test.py +0 -0
- {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.4.0}/tests/suspend_test.py +0 -0
- {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.4.0}/tests/threading_test.py +0 -0
- {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.4.0}/tests/types_test.py +0 -0
- {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.4.0}/tests/waits_test.py +0 -0
|
@@ -18,7 +18,7 @@ jobs:
|
|
|
18
18
|
steps:
|
|
19
19
|
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
|
20
20
|
- name: Use Node.js
|
|
21
|
-
uses: actions/setup-node@
|
|
21
|
+
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
|
|
22
22
|
with:
|
|
23
23
|
node-version: 22.x
|
|
24
24
|
- name: Check PR title
|
|
@@ -42,7 +42,7 @@ jobs:
|
|
|
42
42
|
python-version: ${{ matrix.python-version }}
|
|
43
43
|
- name: Install Hatch
|
|
44
44
|
run: |
|
|
45
|
-
python -m pip install hatch==1.
|
|
45
|
+
python -m pip install hatch==1.16.5
|
|
46
46
|
- name: static analysis
|
|
47
47
|
run: hatch fmt --check
|
|
48
48
|
- name: type checking
|
|
@@ -33,7 +33,6 @@ jobs:
|
|
|
33
33
|
with:
|
|
34
34
|
repository: aws/aws-durable-execution-sdk-python-testing
|
|
35
35
|
ref: ${{ steps.parse.outputs.testing_ref }}
|
|
36
|
-
token: ${{ secrets.CROSS_REPO_PAT }}
|
|
37
36
|
path: testing-sdk
|
|
38
37
|
|
|
39
38
|
- name: Set up Python ${{ matrix.python-version }}
|
|
@@ -42,7 +41,7 @@ jobs:
|
|
|
42
41
|
python-version: ${{ matrix.python-version }}
|
|
43
42
|
|
|
44
43
|
- name: Install Hatch
|
|
45
|
-
run: python -m pip install hatch==1.
|
|
44
|
+
run: python -m pip install hatch==1.16.5
|
|
46
45
|
|
|
47
46
|
- name: Setup and run Testing SDK
|
|
48
47
|
working-directory: testing-sdk
|
|
@@ -82,7 +81,6 @@ jobs:
|
|
|
82
81
|
with:
|
|
83
82
|
repository: aws/aws-durable-execution-sdk-python-testing
|
|
84
83
|
ref: ${{ steps.parse.outputs.testing_ref }}
|
|
85
|
-
token: ${{ secrets.CROSS_REPO_PAT }}
|
|
86
84
|
path: testing-sdk
|
|
87
85
|
|
|
88
86
|
- name: Set up Python 3.13
|
|
@@ -91,7 +89,7 @@ jobs:
|
|
|
91
89
|
python-version: '3.13'
|
|
92
90
|
|
|
93
91
|
- name: Configure AWS credentials
|
|
94
|
-
uses: aws-actions/configure-aws-credentials@
|
|
92
|
+
uses: aws-actions/configure-aws-credentials@8df5847569e6427dd6c4fb1cf565c83acfa8afa7 # v6.0.0
|
|
95
93
|
with:
|
|
96
94
|
role-to-assume: "${{ secrets.ACTIONS_INTEGRATION_ROLE_NAME }}"
|
|
97
95
|
role-session-name: languageSDKIntegrationTest
|
|
@@ -102,7 +100,7 @@ jobs:
|
|
|
102
100
|
env:
|
|
103
101
|
AWS_DURABLE_SDK_URL: file://${{ github.workspace }}/language-sdk
|
|
104
102
|
run: |
|
|
105
|
-
pip install hatch==1.
|
|
103
|
+
pip install hatch==1.16.5
|
|
106
104
|
python -m pip install -e .
|
|
107
105
|
|
|
108
106
|
- name: Get integration examples
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
name: Slack Notifications
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
issues:
|
|
5
|
+
types: [opened, reopened]
|
|
6
|
+
pull_request_target:
|
|
7
|
+
types: [opened, reopened]
|
|
8
|
+
|
|
9
|
+
permissions: {}
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
notify:
|
|
13
|
+
runs-on: ubuntu-latest
|
|
14
|
+
steps:
|
|
15
|
+
- name: Send issue notification to Slack
|
|
16
|
+
if: github.event_name == 'issues'
|
|
17
|
+
uses: slackapi/slack-github-action@af78098f536edbc4de71162a307590698245be95 # v3.0.1
|
|
18
|
+
with:
|
|
19
|
+
webhook: ${{ secrets.SLACK_WEBHOOK_URL_ISSUE }}
|
|
20
|
+
webhook-type: incoming-webhook
|
|
21
|
+
payload: |
|
|
22
|
+
{
|
|
23
|
+
"action": "${{ github.event.action }}",
|
|
24
|
+
"issue_url": "${{ github.event.issue.html_url }}",
|
|
25
|
+
"package_name": "${{ github.repository }}"
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
- name: Send pull request notification to Slack
|
|
29
|
+
if: github.event_name == 'pull_request_target'
|
|
30
|
+
uses: slackapi/slack-github-action@af78098f536edbc4de71162a307590698245be95 # v3.0.1
|
|
31
|
+
with:
|
|
32
|
+
webhook: ${{ secrets.SLACK_WEBHOOK_URL_PR }}
|
|
33
|
+
webhook-type: incoming-webhook
|
|
34
|
+
payload: |
|
|
35
|
+
{
|
|
36
|
+
"action": "${{ github.event.action }}",
|
|
37
|
+
"pr_url": "${{ github.event.pull_request.html_url }}",
|
|
38
|
+
"package_name": "${{ github.repository }}"
|
|
39
|
+
}
|
|
@@ -27,14 +27,14 @@ jobs:
|
|
|
27
27
|
python-version: "3.11"
|
|
28
28
|
- name: Install Hatch
|
|
29
29
|
run: |
|
|
30
|
-
python -m pip install --upgrade hatch==1.
|
|
30
|
+
python -m pip install --upgrade hatch==1.16.5
|
|
31
31
|
- name: Build release distributions
|
|
32
32
|
run: |
|
|
33
33
|
# NOTE: put your own distribution build steps here.
|
|
34
34
|
hatch build
|
|
35
35
|
|
|
36
36
|
- name: Upload distributions
|
|
37
|
-
uses: actions/upload-artifact@
|
|
37
|
+
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
|
|
38
38
|
with:
|
|
39
39
|
name: release-dists
|
|
40
40
|
path: dist/
|
|
@@ -60,7 +60,7 @@ jobs:
|
|
|
60
60
|
|
|
61
61
|
steps:
|
|
62
62
|
- name: Retrieve release distributions
|
|
63
|
-
uses: actions/download-artifact@
|
|
63
|
+
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
|
64
64
|
with:
|
|
65
65
|
name: release-dists
|
|
66
66
|
path: dist/
|
|
@@ -66,7 +66,7 @@ jobs:
|
|
|
66
66
|
# Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF
|
|
67
67
|
# format to the repository Actions tab.
|
|
68
68
|
- name: "Upload artifact"
|
|
69
|
-
uses: actions/upload-artifact@
|
|
69
|
+
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
|
|
70
70
|
with:
|
|
71
71
|
name: SARIF file
|
|
72
72
|
path: results.sarif
|
|
@@ -75,6 +75,6 @@ jobs:
|
|
|
75
75
|
# Upload the results to GitHub's code scanning dashboard (optional).
|
|
76
76
|
# Commenting out will disable upload of results to your repo's Code Scanning dashboard
|
|
77
77
|
- name: "Upload to code-scanning"
|
|
78
|
-
uses: github/codeql-action/upload-sarif@
|
|
78
|
+
uses: github/codeql-action/upload-sarif@c10b8064de6f491fea524254123dbe5e09572f13 # v4.35.1
|
|
79
79
|
with:
|
|
80
80
|
sarif_file: results.sarif
|
|
@@ -27,11 +27,11 @@ jobs:
|
|
|
27
27
|
python-version: ${{ matrix.python-version }}
|
|
28
28
|
- name: Install Hatch
|
|
29
29
|
run: |
|
|
30
|
-
python -m pip install --upgrade hatch==1.
|
|
30
|
+
python -m pip install --upgrade hatch==1.16.5
|
|
31
31
|
- name: Build distribution
|
|
32
32
|
run: hatch build
|
|
33
33
|
- name: configure aws credentials
|
|
34
|
-
uses: aws-actions/configure-aws-credentials@
|
|
34
|
+
uses: aws-actions/configure-aws-credentials@8df5847569e6427dd6c4fb1cf565c83acfa8afa7 # v6.0.0
|
|
35
35
|
with:
|
|
36
36
|
role-to-assume: "${{ secrets.ACTIONS_SYNC_ROLE_NAME }}"
|
|
37
37
|
role-session-name: gh-python
|
|
@@ -495,9 +495,10 @@ const allResults = results.getResults();
|
|
|
495
495
|
**Python:**
|
|
496
496
|
|
|
497
497
|
```python
|
|
498
|
+
from collections.abc import Sequence
|
|
498
499
|
from aws_durable_execution_sdk_python.concurrency import MapConfig, CompletionConfig
|
|
499
500
|
|
|
500
|
-
def process_item(ctx: DurableContext, item: dict, index: int) -> dict:
|
|
501
|
+
def process_item(ctx: DurableContext, item: dict, index: int, items: Sequence[dict]) -> dict:
|
|
501
502
|
return ctx.step(lambda _: process(item), name=f"process-{index}")
|
|
502
503
|
|
|
503
504
|
results = context.map(
|
|
@@ -833,7 +834,7 @@ Resources:
|
|
|
833
834
|
Type: AWS::Lambda::Function
|
|
834
835
|
Properties:
|
|
835
836
|
FunctionName: myDurableFunction
|
|
836
|
-
Runtime: nodejs22.x # or python3.
|
|
837
|
+
Runtime: nodejs22.x # or python3.14
|
|
837
838
|
Handler: index.handler
|
|
838
839
|
Role: !GetAtt DurableFunctionRole.Arn
|
|
839
840
|
Code:
|
|
@@ -894,7 +895,7 @@ Resources:
|
|
|
894
895
|
Type: AWS::Serverless::Function
|
|
895
896
|
Properties:
|
|
896
897
|
FunctionName: myDurableFunction
|
|
897
|
-
Runtime: nodejs22.x # or python3.
|
|
898
|
+
Runtime: nodejs22.x # or python3.14
|
|
898
899
|
Handler: index.handler
|
|
899
900
|
CodeUri: ./src
|
|
900
901
|
DurableConfig:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: aws-durable-execution-sdk-python
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.4.0
|
|
4
4
|
Summary: AWS Durable Execution SDK for Python
|
|
5
5
|
Project-URL: Documentation, https://github.com/aws/aws-durable-execution-sdk-python#readme
|
|
6
6
|
Project-URL: Issues, https://github.com/aws/aws-durable-execution-sdk-python/issues
|
|
@@ -14,6 +14,7 @@ The Durable Execution SDK automatically enriches your logs with execution contex
|
|
|
14
14
|
- [Integration with Powertools for AWS Lambda (Python)](#integration-with-powertools-for-aws-lambda-python)
|
|
15
15
|
- [Replay behavior and log deduplication](#replay-behavior-and-log-deduplication)
|
|
16
16
|
- [Best practices](#best-practices)
|
|
17
|
+
- [Enabling debug logging](#enabling-debug-logging)
|
|
17
18
|
- [FAQ](#faq)
|
|
18
19
|
- [Testing logger integration](#testing-logger-integration)
|
|
19
20
|
- [See also](#see-also)
|
|
@@ -485,6 +486,79 @@ context.logger.info("User authenticated", extra={"password": password})
|
|
|
485
486
|
|
|
486
487
|
[↑ Back to top](#table-of-contents)
|
|
487
488
|
|
|
489
|
+
## Enabling debug logging
|
|
490
|
+
|
|
491
|
+
The SDK logs internally using Python's standard `logging` module. To see these logs, set `ApplicationLogLevel: DEBUG` in [Advanced logging controls](https://docs.aws.amazon.com/lambda/latest/dg/monitoring-cloudwatchlogs-advanced.html).
|
|
492
|
+
|
|
493
|
+
Advanced logging controls filters logs before they reach CloudWatch. If you set DEBUG level in code but leave Advanced logging controls at INFO, your debug logs will be dropped. You must configure the level in Advanced logging controls - it auto-patches all loggers, so you don't need to configure log levels in code.
|
|
494
|
+
|
|
495
|
+
```mermaid
|
|
496
|
+
flowchart LR
|
|
497
|
+
A[Logger emits DEBUG] --> B{Advanced Logging Controls}
|
|
498
|
+
B -->|ApplicationLogLevel = DEBUG| C[CloudWatch ✓]
|
|
499
|
+
B -->|ApplicationLogLevel = INFO| D[Dropped ✗]
|
|
500
|
+
```
|
|
501
|
+
|
|
502
|
+
**Important:** DEBUG level applies to all libraries including botocore. Since the SDK uses boto3 internally, this will flood your logs with HTTP request/response details. Silence botocore in your code:
|
|
503
|
+
|
|
504
|
+
```python
|
|
505
|
+
import logging
|
|
506
|
+
|
|
507
|
+
# Silence botocore/urllib3 noise
|
|
508
|
+
logging.getLogger("botocore").setLevel(logging.WARNING)
|
|
509
|
+
logging.getLogger("urllib3").setLevel(logging.WARNING)
|
|
510
|
+
```
|
|
511
|
+
|
|
512
|
+
Configure ALC via SAM/CloudFormation:
|
|
513
|
+
|
|
514
|
+
```yaml
|
|
515
|
+
# SAM template
|
|
516
|
+
Resources:
|
|
517
|
+
MyFunction:
|
|
518
|
+
Type: AWS::Serverless::Function
|
|
519
|
+
Properties:
|
|
520
|
+
LoggingConfig:
|
|
521
|
+
LogFormat: JSON
|
|
522
|
+
ApplicationLogLevel: DEBUG
|
|
523
|
+
```
|
|
524
|
+
|
|
525
|
+
Or in the Lambda console under Configuration → Monitoring and operations tools → Logging configuration.
|
|
526
|
+
|
|
527
|
+
### Selective logging
|
|
528
|
+
|
|
529
|
+
Python loggers are hierarchical. Silencing `aws_durable_execution_sdk_python` silences all SDK modules. To keep some modules at DEBUG while silencing others:
|
|
530
|
+
|
|
531
|
+
```python
|
|
532
|
+
import logging
|
|
533
|
+
|
|
534
|
+
# Silence all SDK logs
|
|
535
|
+
logging.getLogger("aws_durable_execution_sdk_python").setLevel(logging.WARNING)
|
|
536
|
+
|
|
537
|
+
# Or silence specific modules only
|
|
538
|
+
logging.getLogger("aws_durable_execution_sdk_python.state").setLevel(logging.WARNING)
|
|
539
|
+
logging.getLogger("aws_durable_execution_sdk_python.concurrency").setLevel(logging.WARNING)
|
|
540
|
+
```
|
|
541
|
+
|
|
542
|
+
SDK logger namespaces:
|
|
543
|
+
|
|
544
|
+
| Namespace | Description |
|
|
545
|
+
|-----------|-------------|
|
|
546
|
+
| `aws_durable_execution_sdk_python` | Root - silences all SDK logs |
|
|
547
|
+
| `aws_durable_execution_sdk_python.state` | Checkpoint and replay state management |
|
|
548
|
+
| `aws_durable_execution_sdk_python.execution` | Durable execution lifecycle |
|
|
549
|
+
| `aws_durable_execution_sdk_python.context` | DurableContext operations |
|
|
550
|
+
| `aws_durable_execution_sdk_python.lambda_service` | Lambda API calls |
|
|
551
|
+
| `aws_durable_execution_sdk_python.serdes` | Serialization/deserialization |
|
|
552
|
+
| `aws_durable_execution_sdk_python.concurrency` | Parallel and map execution |
|
|
553
|
+
| `aws_durable_execution_sdk_python.operation.step` | Step operations |
|
|
554
|
+
| `aws_durable_execution_sdk_python.operation.wait` | Wait operations |
|
|
555
|
+
| `aws_durable_execution_sdk_python.operation.invoke` | Invoke operations |
|
|
556
|
+
| `aws_durable_execution_sdk_python.operation.child` | Child context operations |
|
|
557
|
+
| `aws_durable_execution_sdk_python.operation.parallel` | Parallel operations |
|
|
558
|
+
| `aws_durable_execution_sdk_python.operation.map` | Map operations |
|
|
559
|
+
|
|
560
|
+
[↑ Back to top](#table-of-contents)
|
|
561
|
+
|
|
488
562
|
## FAQ
|
|
489
563
|
|
|
490
564
|
**Q: Does logging work during replays?**
|
{aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.4.0}/docs/core/map.md
RENAMED
|
@@ -28,8 +28,6 @@
|
|
|
28
28
|
|
|
29
29
|
**Concurrency control** - Limiting how many items process simultaneously using `max_concurrency` in `MapConfig`.
|
|
30
30
|
|
|
31
|
-
**Item batching** - Grouping multiple items together for processing as a single unit to optimize efficiency.
|
|
32
|
-
|
|
33
31
|
**Completion criteria** - Rules that determine when a map operation succeeds or fails based on individual item results.
|
|
34
32
|
|
|
35
33
|
[↑ Back to top](#table-of-contents)
|
|
@@ -42,7 +40,7 @@ Use map operations to:
|
|
|
42
40
|
- Transform collections with automatic checkpointing
|
|
43
41
|
- Process lists of items in parallel
|
|
44
42
|
- Handle large datasets with resilience
|
|
45
|
-
- Control concurrency
|
|
43
|
+
- Control concurrency behavior
|
|
46
44
|
- Define custom success/failure criteria
|
|
47
45
|
|
|
48
46
|
Map operations use `context.map()` to process collections efficiently. Each item becomes an independent operation that executes in parallel with other items.
|
|
@@ -55,7 +53,6 @@ Map operations use `context.map()` to process collections efficiently. Each item
|
|
|
55
53
|
- **Independent checkpointing** - Each item's result is saved separately
|
|
56
54
|
- **Partial completion** - Completed items don't reprocess on replay
|
|
57
55
|
- **Concurrency control** - Limit simultaneous processing with `max_concurrency`
|
|
58
|
-
- **Batching support** - Group items for efficient processing
|
|
59
56
|
- **Flexible completion** - Define custom success/failure criteria
|
|
60
57
|
- **Result ordering** - Results maintain the same order as inputs
|
|
61
58
|
|
|
@@ -77,19 +74,20 @@ def square(context: DurableContext, item: int, index: int, items: list[int]) ->
|
|
|
77
74
|
return item * item
|
|
78
75
|
|
|
79
76
|
@durable_execution
|
|
80
|
-
def handler(event: dict, context: DurableContext) ->
|
|
77
|
+
def handler(event: dict, context: DurableContext) -> dict:
|
|
81
78
|
"""Process a list of items using map operations."""
|
|
82
79
|
items = [1, 2, 3, 4, 5]
|
|
83
|
-
|
|
80
|
+
|
|
84
81
|
result = context.map(items, square)
|
|
85
|
-
|
|
82
|
+
# Convert to dict for JSON serialization (BatchResult is not JSON serializable)
|
|
83
|
+
return result.to_dict()
|
|
86
84
|
```
|
|
87
85
|
|
|
88
86
|
When this function runs:
|
|
89
87
|
1. Each item is processed in parallel
|
|
90
88
|
2. The `square` function is called for each item
|
|
91
89
|
3. Each result is checkpointed independently
|
|
92
|
-
4. The function returns a
|
|
90
|
+
4. The function returns a dict with results `[1, 4, 9, 16, 25]`
|
|
93
91
|
|
|
94
92
|
If the function is interrupted after processing items 0-2, it resumes at item 3 without reprocessing the first three items.
|
|
95
93
|
|
|
@@ -102,7 +100,7 @@ If the function is interrupted after processing items 0-2, it resumes at item 3
|
|
|
102
100
|
```python
|
|
103
101
|
def map(
|
|
104
102
|
inputs: Sequence[U],
|
|
105
|
-
func: Callable[[DurableContext, U
|
|
103
|
+
func: Callable[[DurableContext, U, int, Sequence[U]], T],
|
|
106
104
|
name: str | None = None,
|
|
107
105
|
config: MapConfig | None = None,
|
|
108
106
|
) -> BatchResult[T]
|
|
@@ -113,7 +111,7 @@ def map(
|
|
|
113
111
|
- `inputs` - A sequence of items to process (list, tuple, or any sequence type).
|
|
114
112
|
- `func` - A callable that processes each item. See [Map function signature](#map-function-signature) for details.
|
|
115
113
|
- `name` (optional) - A name for the map operation, useful for debugging and testing.
|
|
116
|
-
- `config` (optional) - A `MapConfig` object to configure concurrency
|
|
114
|
+
- `config` (optional) - A `MapConfig` object to configure concurrency and completion criteria.
|
|
117
115
|
|
|
118
116
|
**Returns:** A `BatchResult[T]` containing the results from processing all items.
|
|
119
117
|
|
|
@@ -128,7 +126,7 @@ The map function receives four parameters:
|
|
|
128
126
|
```python
|
|
129
127
|
def process_item(
|
|
130
128
|
context: DurableContext,
|
|
131
|
-
item: U
|
|
129
|
+
item: U,
|
|
132
130
|
index: int,
|
|
133
131
|
items: Sequence[U]
|
|
134
132
|
) -> T:
|
|
@@ -140,7 +138,7 @@ def process_item(
|
|
|
140
138
|
**Parameters:**
|
|
141
139
|
|
|
142
140
|
- `context` - A `DurableContext` for the item's processing. Use this to call steps, waits, or other operations.
|
|
143
|
-
- `item` - The current item being processed.
|
|
141
|
+
- `item` - The current item being processed.
|
|
144
142
|
- `index` - The zero-based index of the item in the original collection.
|
|
145
143
|
- `items` - The full collection of items being processed.
|
|
146
144
|
|
|
@@ -165,10 +163,10 @@ def validate_email(
|
|
|
165
163
|
}
|
|
166
164
|
|
|
167
165
|
@durable_execution
|
|
168
|
-
def handler(event: dict, context: DurableContext) ->
|
|
166
|
+
def handler(event: dict, context: DurableContext) -> dict:
|
|
169
167
|
emails = ["jane_doe@example.com", "john_doe@example.org", "invalid"]
|
|
170
168
|
result = context.map(emails, validate_email)
|
|
171
|
-
return result
|
|
169
|
+
return result.to_dict()
|
|
172
170
|
```
|
|
173
171
|
|
|
174
172
|
[↑ Back to top](#table-of-contents)
|
|
@@ -186,7 +184,6 @@ from aws_durable_execution_sdk_python import (
|
|
|
186
184
|
from aws_durable_execution_sdk_python.config import (
|
|
187
185
|
MapConfig,
|
|
188
186
|
CompletionConfig,
|
|
189
|
-
ItemBatcher,
|
|
190
187
|
)
|
|
191
188
|
|
|
192
189
|
def process_item(context: DurableContext, item: int, index: int, items: list[int]) -> dict:
|
|
@@ -194,26 +191,23 @@ def process_item(context: DurableContext, item: int, index: int, items: list[int
|
|
|
194
191
|
return {"item": item, "squared": item * item}
|
|
195
192
|
|
|
196
193
|
@durable_execution
|
|
197
|
-
def handler(event: dict, context: DurableContext) ->
|
|
194
|
+
def handler(event: dict, context: DurableContext) -> dict:
|
|
198
195
|
items = list(range(100))
|
|
199
|
-
|
|
196
|
+
|
|
200
197
|
# Configure map operation
|
|
201
198
|
config = MapConfig(
|
|
202
199
|
max_concurrency=10, # Process 10 items at a time
|
|
203
|
-
item_batcher=ItemBatcher(max_items_per_batch=5), # Batch 5 items together
|
|
204
200
|
completion_config=CompletionConfig.all_successful(), # Require all to succeed
|
|
205
201
|
)
|
|
206
|
-
|
|
202
|
+
|
|
207
203
|
result = context.map(items, process_item, name="process_numbers", config=config)
|
|
208
|
-
return result
|
|
204
|
+
return result.to_dict()
|
|
209
205
|
```
|
|
210
206
|
|
|
211
207
|
### MapConfig parameters
|
|
212
208
|
|
|
213
209
|
**max_concurrency** - Maximum number of items to process concurrently. If `None`, all items process in parallel. Use this to control resource usage.
|
|
214
210
|
|
|
215
|
-
**item_batcher** - Configuration for batching items together. Use `ItemBatcher(max_items_per_batch=N)` to group items.
|
|
216
|
-
|
|
217
211
|
**completion_config** - Defines when the map operation succeeds or fails:
|
|
218
212
|
- `CompletionConfig()` - Default, allows any number of failures
|
|
219
213
|
- `CompletionConfig.all_successful()` - Requires all items to succeed
|
|
@@ -244,45 +238,14 @@ def fetch_data(context: DurableContext, url: str, index: int, urls: list[str]) -
|
|
|
244
238
|
return {"url": url, "data": "..."}
|
|
245
239
|
|
|
246
240
|
@durable_execution
|
|
247
|
-
def handler(event: dict, context: DurableContext) ->
|
|
241
|
+
def handler(event: dict, context: DurableContext) -> dict:
|
|
248
242
|
urls = [f"https://example.com/api/{i}" for i in range(100)]
|
|
249
|
-
|
|
243
|
+
|
|
250
244
|
# Process only 5 URLs at a time
|
|
251
245
|
config = MapConfig(max_concurrency=5)
|
|
252
|
-
|
|
253
|
-
result = context.map(urls, fetch_data, config=config)
|
|
254
|
-
return result
|
|
255
|
-
```
|
|
256
|
-
|
|
257
|
-
### Batching items
|
|
258
|
-
|
|
259
|
-
Group multiple items for efficient processing:
|
|
260
246
|
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
def process_batch(
|
|
265
|
-
context: DurableContext,
|
|
266
|
-
batch: BatchedInput[None, int],
|
|
267
|
-
index: int,
|
|
268
|
-
items: list[int]
|
|
269
|
-
) -> list[dict]:
|
|
270
|
-
"""Process a batch of items together."""
|
|
271
|
-
# Process all items in the batch together
|
|
272
|
-
return [{"item": item, "squared": item * item} for item in batch.items]
|
|
273
|
-
|
|
274
|
-
@durable_execution
|
|
275
|
-
def handler(event: dict, context: DurableContext) -> BatchResult[list[dict]]:
|
|
276
|
-
items = list(range(100))
|
|
277
|
-
|
|
278
|
-
# Process items in batches of 10
|
|
279
|
-
config = MapConfig(
|
|
280
|
-
item_batcher=ItemBatcher(max_items_per_batch=10)
|
|
281
|
-
)
|
|
282
|
-
|
|
283
|
-
result = context.map(items, process_batch, config=config)
|
|
284
|
-
return result
|
|
285
|
-
```
|
|
247
|
+
result = context.map(urls, fetch_data, config=config)
|
|
248
|
+
return result.to_dict()```
|
|
286
249
|
|
|
287
250
|
### Custom completion criteria
|
|
288
251
|
|
|
@@ -299,9 +262,9 @@ def process_item(context: DurableContext, item: int, index: int, items: list[int
|
|
|
299
262
|
return {"item": item, "processed": True}
|
|
300
263
|
|
|
301
264
|
@durable_execution
|
|
302
|
-
def handler(event: dict, context: DurableContext) ->
|
|
265
|
+
def handler(event: dict, context: DurableContext) -> dict:
|
|
303
266
|
items = list(range(20))
|
|
304
|
-
|
|
267
|
+
|
|
305
268
|
# Succeed if at least 15 items succeed, fail after 5 failures
|
|
306
269
|
config = MapConfig(
|
|
307
270
|
completion_config=CompletionConfig(
|
|
@@ -309,9 +272,9 @@ def handler(event: dict, context: DurableContext) -> BatchResult[dict]:
|
|
|
309
272
|
tolerated_failure_count=5,
|
|
310
273
|
)
|
|
311
274
|
)
|
|
312
|
-
|
|
275
|
+
|
|
313
276
|
result = context.map(items, process_item, config=config)
|
|
314
|
-
return result
|
|
277
|
+
return result.to_dict()
|
|
315
278
|
```
|
|
316
279
|
|
|
317
280
|
### Using context operations in map functions
|
|
@@ -344,11 +307,13 @@ def process_user(
|
|
|
344
307
|
return {"user_id": user_id, "notification_sent": notification["sent"]}
|
|
345
308
|
|
|
346
309
|
@durable_execution
|
|
347
|
-
def handler(event: dict, context: DurableContext) ->
|
|
310
|
+
def handler(event: dict, context: DurableContext) -> dict:
|
|
311
|
+
"""Process multiple users using context operations within map functions."""
|
|
348
312
|
user_ids = ["user_1", "user_2", "user_3"]
|
|
349
|
-
|
|
313
|
+
|
|
350
314
|
result = context.map(user_ids, process_user)
|
|
351
|
-
|
|
315
|
+
# Convert to dict for JSON serialization (BatchResult is not JSON serializable)
|
|
316
|
+
return result.to_dict()
|
|
352
317
|
```
|
|
353
318
|
|
|
354
319
|
### Filtering and transforming results
|
|
@@ -391,8 +356,6 @@ def handler(event: dict, context: DurableContext) -> list[str]:
|
|
|
391
356
|
|
|
392
357
|
**Control concurrency for external calls** - When calling external APIs, use `max_concurrency` to avoid rate limits.
|
|
393
358
|
|
|
394
|
-
**Batch for efficiency** - For small, fast operations, use `item_batcher` to reduce overhead.
|
|
395
|
-
|
|
396
359
|
**Define completion criteria** - Use `CompletionConfig` to specify when the operation should succeed or fail.
|
|
397
360
|
|
|
398
361
|
**Keep map functions focused** - Each map function should process one item. Don't mix collection iteration with item processing.
|
|
@@ -401,7 +364,7 @@ def handler(event: dict, context: DurableContext) -> list[str]:
|
|
|
401
364
|
|
|
402
365
|
**Handle errors gracefully** - Wrap error-prone code in try-except blocks or use completion criteria to tolerate failures.
|
|
403
366
|
|
|
404
|
-
**Consider collection size** - For very large collections (10,000+ items), consider
|
|
367
|
+
**Consider collection size** - For very large collections (10,000+ items), consider processing in chunks.
|
|
405
368
|
|
|
406
369
|
**Monitor memory usage** - Large collections create many checkpoints. Monitor Lambda memory usage.
|
|
407
370
|
|
|
@@ -415,23 +378,15 @@ def handler(event: dict, context: DurableContext) -> list[str]:
|
|
|
415
378
|
|
|
416
379
|
**Use max_concurrency wisely** - Too much concurrency can overwhelm external services or exhaust Lambda resources. Start conservative and increase as needed.
|
|
417
380
|
|
|
418
|
-
**Batch small operations** - If each item processes quickly (< 100ms), batching reduces overhead:
|
|
419
|
-
|
|
420
|
-
```python
|
|
421
|
-
config = MapConfig(
|
|
422
|
-
item_batcher=ItemBatcher(max_items_per_batch=10)
|
|
423
|
-
)
|
|
424
|
-
```
|
|
425
|
-
|
|
426
381
|
**Optimize map functions** - Keep map functions lightweight. Move heavy computation into steps within the map function.
|
|
427
382
|
|
|
428
383
|
**Use appropriate completion criteria** - Fail fast with `tolerated_failure_count` to avoid processing remaining items when many fail.
|
|
429
384
|
|
|
430
385
|
**Monitor checkpoint size** - Large result objects increase checkpoint size and Lambda memory usage. Return only necessary data.
|
|
431
386
|
|
|
432
|
-
**Consider memory limits** - Processing thousands of items creates many checkpoints. Monitor Lambda memory and adjust
|
|
387
|
+
**Consider memory limits** - Processing thousands of items creates many checkpoints. Monitor Lambda memory and adjust concurrency.
|
|
433
388
|
|
|
434
|
-
**Profile your workload** - Test with representative data to find optimal concurrency
|
|
389
|
+
**Profile your workload** - Test with representative data to find optimal concurrency settings.
|
|
435
390
|
|
|
436
391
|
[↑ Back to top](#table-of-contents)
|
|
437
392
|
|
|
@@ -443,7 +398,7 @@ A: Map operations process a collection of similar items using the same function.
|
|
|
443
398
|
|
|
444
399
|
**Q: How many items can I process?**
|
|
445
400
|
|
|
446
|
-
A: There's no hard limit, but consider Lambda's memory and timeout constraints. For very large collections (10,000+ items),
|
|
401
|
+
A: There's no hard limit, but consider Lambda's memory and timeout constraints. For very large collections (10,000+ items), consider processing in chunks.
|
|
447
402
|
|
|
448
403
|
**Q: Do items process in order?**
|
|
449
404
|
|
|
@@ -471,10 +426,6 @@ for item_result in batch_result.results:
|
|
|
471
426
|
|
|
472
427
|
A: Yes, you can call `context.map()` inside a map function to process nested collections.
|
|
473
428
|
|
|
474
|
-
**Q: How does batching work?**
|
|
475
|
-
|
|
476
|
-
A: When you configure `item_batcher`, multiple items are grouped together and passed as a `BatchedInput` to your map function. Process all items in `batch.items`.
|
|
477
|
-
|
|
478
429
|
**Q: What's the difference between serdes and item_serdes?**
|
|
479
430
|
|
|
480
431
|
A: `item_serdes` serializes individual item results as they complete. `serdes` serializes the entire `BatchResult` at the end. Use both for custom serialization at different levels.
|
|
@@ -168,13 +168,14 @@ pip install aws-durable-execution-sdk-python-testing
|
|
|
168
168
|
|
|
169
169
|
```python
|
|
170
170
|
import pytest
|
|
171
|
+
from aws_durable_execution_sdk_python.execution import InvocationStatus
|
|
171
172
|
from my_function import handler
|
|
172
173
|
|
|
173
174
|
@pytest.mark.durable_execution(handler=handler, lambda_function_name="my_function")
|
|
174
175
|
def test_my_function(durable_runner):
|
|
175
176
|
with durable_runner:
|
|
176
177
|
result = durable_runner.run(input={"data": "test"}, timeout=10)
|
|
177
|
-
assert result.status ==
|
|
178
|
+
assert result.status == InvocationStatus.SUCCEEDED
|
|
178
179
|
```
|
|
179
180
|
|
|
180
181
|
Run tests without AWS credentials:
|
{aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.4.0}/pyproject.toml
RENAMED
|
@@ -62,9 +62,16 @@ exclude_lines = ["no cov", "if __name__ == .__main__.:", "if TYPE_CHECKING:"]
|
|
|
62
62
|
|
|
63
63
|
[tool.ruff]
|
|
64
64
|
line-length = 88
|
|
65
|
+
target-version = "py311"
|
|
65
66
|
|
|
66
67
|
[tool.ruff.lint]
|
|
67
68
|
preview = true
|
|
69
|
+
select = ["TID252"] # Enforce absolute imports (ban relative imports)
|
|
70
|
+
|
|
71
|
+
[tool.ruff.lint.isort]
|
|
72
|
+
known-first-party = ["aws_durable_execution_sdk_python"]
|
|
73
|
+
force-single-line = false
|
|
74
|
+
lines-after-imports = 2
|
|
68
75
|
|
|
69
76
|
[tool.ruff.lint.per-file-ignores]
|
|
70
77
|
"tests/**" = [
|
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
"""AWS Lambda Durable Executions Python SDK."""
|
|
2
2
|
|
|
3
|
+
# Package metadata
|
|
4
|
+
from aws_durable_execution_sdk_python.__about__ import __version__
|
|
5
|
+
|
|
3
6
|
# Main context - used in every durable function
|
|
4
7
|
# Helper decorators - commonly used for step functions
|
|
8
|
+
# Concurrency
|
|
9
|
+
from aws_durable_execution_sdk_python.concurrency.models import BatchResult
|
|
5
10
|
from aws_durable_execution_sdk_python.context import (
|
|
6
11
|
DurableContext,
|
|
7
12
|
durable_step,
|
|
@@ -20,7 +25,7 @@ from aws_durable_execution_sdk_python.exceptions import (
|
|
|
20
25
|
from aws_durable_execution_sdk_python.execution import durable_execution
|
|
21
26
|
|
|
22
27
|
# Essential context types - passed to user functions
|
|
23
|
-
from aws_durable_execution_sdk_python.types import
|
|
28
|
+
from aws_durable_execution_sdk_python.types import StepContext
|
|
24
29
|
|
|
25
30
|
__all__ = [
|
|
26
31
|
"BatchResult",
|
|
@@ -29,6 +34,7 @@ __all__ = [
|
|
|
29
34
|
"InvocationError",
|
|
30
35
|
"StepContext",
|
|
31
36
|
"ValidationError",
|
|
37
|
+
"__version__",
|
|
32
38
|
"durable_execution",
|
|
33
39
|
"durable_step",
|
|
34
40
|
"durable_wait_for_callback",
|
|
@@ -30,6 +30,7 @@ from aws_durable_execution_sdk_python.identifier import OperationIdentifier
|
|
|
30
30
|
from aws_durable_execution_sdk_python.lambda_service import ErrorObject
|
|
31
31
|
from aws_durable_execution_sdk_python.operation.child import child_handler
|
|
32
32
|
|
|
33
|
+
|
|
33
34
|
if TYPE_CHECKING:
|
|
34
35
|
from collections.abc import Callable
|
|
35
36
|
|
|
@@ -196,6 +197,11 @@ class ConcurrentExecutor(ABC, Generic[CallableType, ResultType]):
|
|
|
196
197
|
"▶️ Executing concurrent operation, items: %d", len(self.executables)
|
|
197
198
|
)
|
|
198
199
|
|
|
200
|
+
# Early return for empty executables
|
|
201
|
+
if not self.executables:
|
|
202
|
+
logger.debug("No items to execute, returning empty result")
|
|
203
|
+
return self._create_result()
|
|
204
|
+
|
|
199
205
|
max_workers = self.max_concurrency or len(self.executables)
|
|
200
206
|
|
|
201
207
|
self.executables_with_state = [
|