aws-durable-execution-sdk-python 1.1.2__tar.gz → 1.3.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.
Files changed (105) hide show
  1. {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.3.0}/.github/workflows/scorecard.yml +1 -1
  2. {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.3.0}/PKG-INFO +1 -1
  3. {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.3.0}/docs/core/logger.md +74 -0
  4. {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.3.0}/src/aws_durable_execution_sdk_python/__about__.py +1 -1
  5. {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.3.0}/src/aws_durable_execution_sdk_python/__init__.py +3 -1
  6. {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.3.0}/src/aws_durable_execution_sdk_python/context.py +21 -0
  7. {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.3.0}/src/aws_durable_execution_sdk_python/logger.py +1 -1
  8. {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.3.0}/src/aws_durable_execution_sdk_python/operation/step.py +3 -2
  9. {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.3.0}/src/aws_durable_execution_sdk_python/operation/wait_for_condition.py +3 -2
  10. {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.3.0}/src/aws_durable_execution_sdk_python/state.py +4 -4
  11. {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.3.0}/tests/context_test.py +161 -53
  12. {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.3.0}/tests/logger_test.py +2 -2
  13. {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.3.0}/tests/operation/map_test.py +25 -6
  14. {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.3.0}/tests/operation/parallel_test.py +25 -6
  15. {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.3.0}/tests/operation/wait_for_condition_test.py +121 -1
  16. {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.3.0}/tests/state_test.py +44 -1
  17. {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.3.0}/tests/test_helpers.py +5 -2
  18. {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.3.0}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
  19. {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.3.0}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  20. {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.3.0}/.github/ISSUE_TEMPLATE/documentation.yml +0 -0
  21. {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.3.0}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
  22. {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.3.0}/.github/dependabot.yml +0 -0
  23. {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.3.0}/.github/workflows/ci.yml +0 -0
  24. {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.3.0}/.github/workflows/integration-tests.yml +0 -0
  25. {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.3.0}/.github/workflows/lintcommit.js +0 -0
  26. {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.3.0}/.github/workflows/pypi-publish.yml +0 -0
  27. {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.3.0}/.github/workflows/sync-package.yml +0 -0
  28. {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.3.0}/.github/workflows/test-parser.yml +0 -0
  29. {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.3.0}/.gitignore +0 -0
  30. /aws_durable_execution_sdk_python-1.1.2/docs/agents.md → /aws_durable_execution_sdk_python-1.3.0/AGENTS.md +0 -0
  31. {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.3.0}/CODE_OF_CONDUCT.md +0 -0
  32. {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.3.0}/CONTRIBUTING.md +0 -0
  33. {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.3.0}/LICENSE +0 -0
  34. {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.3.0}/NOTICE +0 -0
  35. {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.3.0}/README.md +0 -0
  36. {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.3.0}/docs/advanced/error-handling.md +0 -0
  37. {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.3.0}/docs/advanced/serialization.md +0 -0
  38. {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.3.0}/docs/advanced/testing-modes.md +0 -0
  39. {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.3.0}/docs/api-reference/.gitkeep +0 -0
  40. {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.3.0}/docs/architecture.md +0 -0
  41. {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.3.0}/docs/best-practices.md +0 -0
  42. {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.3.0}/docs/core/callbacks.md +0 -0
  43. {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.3.0}/docs/core/child-contexts.md +0 -0
  44. {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.3.0}/docs/core/invoke.md +0 -0
  45. {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.3.0}/docs/core/map.md +0 -0
  46. {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.3.0}/docs/core/parallel.md +0 -0
  47. {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.3.0}/docs/core/steps.md +0 -0
  48. {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.3.0}/docs/core/wait.md +0 -0
  49. {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.3.0}/docs/getting-started.md +0 -0
  50. {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.3.0}/docs/index.md +0 -0
  51. {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.3.0}/docs/testing-patterns/.gitkeep +0 -0
  52. {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.3.0}/docs/testing-patterns/basic-tests.md +0 -0
  53. {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.3.0}/docs/testing-patterns/complex-workflows.md +0 -0
  54. {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.3.0}/docs/testing-patterns/stores.md +0 -0
  55. {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.3.0}/ops/__tests__/test_parse_sdk_branch.py +0 -0
  56. {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.3.0}/ops/ci-checks.sh +0 -0
  57. {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.3.0}/ops/parse_sdk_branch.py +0 -0
  58. {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.3.0}/pyproject.toml +0 -0
  59. {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.3.0}/src/aws_durable_execution_sdk_python/.gitignore +0 -0
  60. {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.3.0}/src/aws_durable_execution_sdk_python/concurrency/__init__.py +0 -0
  61. {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.3.0}/src/aws_durable_execution_sdk_python/concurrency/executor.py +0 -0
  62. {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.3.0}/src/aws_durable_execution_sdk_python/concurrency/models.py +0 -0
  63. {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.3.0}/src/aws_durable_execution_sdk_python/config.py +0 -0
  64. {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.3.0}/src/aws_durable_execution_sdk_python/exceptions.py +0 -0
  65. {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.3.0}/src/aws_durable_execution_sdk_python/execution.py +0 -0
  66. {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.3.0}/src/aws_durable_execution_sdk_python/identifier.py +0 -0
  67. {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.3.0}/src/aws_durable_execution_sdk_python/lambda_service.py +0 -0
  68. {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.3.0}/src/aws_durable_execution_sdk_python/operation/__init__.py +0 -0
  69. {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.3.0}/src/aws_durable_execution_sdk_python/operation/base.py +0 -0
  70. {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.3.0}/src/aws_durable_execution_sdk_python/operation/callback.py +0 -0
  71. {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.3.0}/src/aws_durable_execution_sdk_python/operation/child.py +0 -0
  72. {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.3.0}/src/aws_durable_execution_sdk_python/operation/invoke.py +0 -0
  73. {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.3.0}/src/aws_durable_execution_sdk_python/operation/map.py +0 -0
  74. {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.3.0}/src/aws_durable_execution_sdk_python/operation/parallel.py +0 -0
  75. {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.3.0}/src/aws_durable_execution_sdk_python/operation/wait.py +0 -0
  76. {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.3.0}/src/aws_durable_execution_sdk_python/py.typed +0 -0
  77. {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.3.0}/src/aws_durable_execution_sdk_python/retries.py +0 -0
  78. {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.3.0}/src/aws_durable_execution_sdk_python/serdes.py +0 -0
  79. {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.3.0}/src/aws_durable_execution_sdk_python/suspend.py +0 -0
  80. {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.3.0}/src/aws_durable_execution_sdk_python/threading.py +0 -0
  81. {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.3.0}/src/aws_durable_execution_sdk_python/types.py +0 -0
  82. {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.3.0}/src/aws_durable_execution_sdk_python/waits.py +0 -0
  83. {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.3.0}/tests/__init__.py +0 -0
  84. {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.3.0}/tests/concurrency_test.py +0 -0
  85. {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.3.0}/tests/config_test.py +0 -0
  86. {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.3.0}/tests/durable_executions_python_language_sdk_test.py +0 -0
  87. {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.3.0}/tests/e2e/__init__.py +0 -0
  88. {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.3.0}/tests/e2e/checkpoint_response_int_test.py +0 -0
  89. {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.3.0}/tests/e2e/execution_int_test.py +0 -0
  90. {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.3.0}/tests/exceptions_test.py +0 -0
  91. {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.3.0}/tests/execution_test.py +0 -0
  92. {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.3.0}/tests/lambda_service_test.py +0 -0
  93. {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.3.0}/tests/operation/__init__.py +0 -0
  94. {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.3.0}/tests/operation/base_test.py +0 -0
  95. {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.3.0}/tests/operation/callback_test.py +0 -0
  96. {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.3.0}/tests/operation/child_test.py +0 -0
  97. {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.3.0}/tests/operation/invoke_test.py +0 -0
  98. {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.3.0}/tests/operation/step_test.py +0 -0
  99. {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.3.0}/tests/operation/wait_test.py +0 -0
  100. {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.3.0}/tests/retries_test.py +0 -0
  101. {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.3.0}/tests/serdes_test.py +0 -0
  102. {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.3.0}/tests/suspend_test.py +0 -0
  103. {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.3.0}/tests/threading_test.py +0 -0
  104. {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.3.0}/tests/types_test.py +0 -0
  105. {aws_durable_execution_sdk_python-1.1.2 → aws_durable_execution_sdk_python-1.3.0}/tests/waits_test.py +0 -0
@@ -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@19b2f06db2b6f5108140aeb04014ef02b648f789 # v4.31.11
78
+ uses: github/codeql-action/upload-sarif@b20883b0cd1f46c72ae0ba6d1090936928f9fa30 # v4.32.0
79
79
  with:
80
80
  sarif_file: results.sarif
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: aws-durable-execution-sdk-python
3
- Version: 1.1.2
3
+ Version: 1.3.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?**
@@ -1,4 +1,4 @@
1
1
  # SPDX-FileCopyrightText: 2025-present Amazon.com, Inc. or its affiliates.
2
2
  #
3
3
  # SPDX-License-Identifier: Apache-2.0
4
- __version__ = "1.1.2"
4
+ __version__ = "1.3.0"
@@ -2,6 +2,8 @@
2
2
 
3
3
  # Main context - used in every durable function
4
4
  # Helper decorators - commonly used for step functions
5
+ # Concurrency
6
+ from aws_durable_execution_sdk_python.concurrency.models import BatchResult
5
7
  from aws_durable_execution_sdk_python.context import (
6
8
  DurableContext,
7
9
  durable_step,
@@ -20,7 +22,7 @@ from aws_durable_execution_sdk_python.exceptions import (
20
22
  from aws_durable_execution_sdk_python.execution import durable_execution
21
23
 
22
24
  # Essential context types - passed to user functions
23
- from aws_durable_execution_sdk_python.types import BatchResult, StepContext
25
+ from aws_durable_execution_sdk_python.types import StepContext
24
26
 
25
27
  __all__ = [
26
28
  "BatchResult",
@@ -2,6 +2,7 @@ from __future__ import annotations
2
2
 
3
3
  import hashlib
4
4
  import logging
5
+ from dataclasses import dataclass
5
6
  from typing import TYPE_CHECKING, Any, Concatenate, Generic, ParamSpec, TypeVar
6
7
 
7
8
  from aws_durable_execution_sdk_python.config import (
@@ -74,6 +75,20 @@ logger = logging.getLogger(__name__)
74
75
  PASS_THROUGH_SERDES: SerDes[Any] = PassThroughSerDes()
75
76
 
76
77
 
78
+ @dataclass(frozen=True)
79
+ class ExecutionContext:
80
+ """Readonly metadata about the current durable execution context.
81
+
82
+ This class provides immutable access to execution-level metadata.
83
+
84
+ Attributes:
85
+ durable_execution_arn: The Amazon Resource Name (ARN) of the current
86
+ durable execution.
87
+ """
88
+
89
+ durable_execution_arn: str
90
+
91
+
77
92
  def durable_step(
78
93
  func: Callable[Concatenate[StepContext, Params], T],
79
94
  ) -> Callable[Params, Callable[[StepContext], T]]:
@@ -218,11 +233,13 @@ class DurableContext(DurableContextProtocol):
218
233
  def __init__(
219
234
  self,
220
235
  state: ExecutionState,
236
+ execution_context: ExecutionContext,
221
237
  lambda_context: LambdaContext | None = None,
222
238
  parent_id: str | None = None,
223
239
  logger: Logger | None = None,
224
240
  ) -> None:
225
241
  self.state: ExecutionState = state
242
+ self.execution_context: ExecutionContext = execution_context
226
243
  self.lambda_context = lambda_context
227
244
  self._parent_id: str | None = parent_id
228
245
  self._step_counter: OrderedCounter = OrderedCounter()
@@ -245,6 +262,9 @@ class DurableContext(DurableContextProtocol):
245
262
  ):
246
263
  return DurableContext(
247
264
  state=state,
265
+ execution_context=ExecutionContext(
266
+ durable_execution_arn=state.durable_execution_arn
267
+ ),
248
268
  lambda_context=lambda_context,
249
269
  parent_id=None,
250
270
  )
@@ -254,6 +274,7 @@ class DurableContext(DurableContextProtocol):
254
274
  logger.debug("Creating child context for parent %s", parent_id)
255
275
  return DurableContext(
256
276
  state=self.state,
277
+ execution_context=self.execution_context,
257
278
  lambda_context=self.lambda_context,
258
279
  parent_id=parent_id,
259
280
  logger=self.logger.with_log_info(
@@ -72,7 +72,7 @@ class Logger(LoggerInterface):
72
72
  # Use 'operation_name' instead of 'name' as key because the stdlib LogRecord internally reserved 'name' parameter
73
73
  extra["operationName"] = info.name
74
74
  if info.attempt is not None:
75
- extra["attempt"] = info.attempt + 1
75
+ extra["attempt"] = info.attempt
76
76
  if info.operation_id:
77
77
  extra["operationId"] = info.operation_id
78
78
  return cls(
@@ -202,9 +202,10 @@ class StepOperationExecutor(OperationExecutor[T]):
202
202
  ExecutionError: For fatal errors that should not be retried
203
203
  May raise other exceptions that will be handled by retry_handler
204
204
  """
205
- attempt: int = 0
205
+ # Get current attempt - checkpointed attempts + 1
206
+ attempt: int = 1
206
207
  if checkpointed_result.operation and checkpointed_result.operation.step_details:
207
- attempt = checkpointed_result.operation.step_details.attempt
208
+ attempt = checkpointed_result.operation.step_details.attempt + 1
208
209
 
209
210
  step_context: StepContext = StepContext(
210
211
  logger=self.context_logger.with_log_info(
@@ -170,10 +170,11 @@ class WaitForConditionOperationExecutor(OperationExecutor[T]):
170
170
  else:
171
171
  current_state = self.config.initial_state
172
172
 
173
- # Get attempt number
173
+ # Get attempt number - current attempt is checkpointed attempts + 1
174
+ # The checkpoint stores completed attempts, so the current attempt being executed is one more
174
175
  attempt: int = 1
175
176
  if checkpointed_result.operation and checkpointed_result.operation.step_details:
176
- attempt = checkpointed_result.operation.step_details.attempt
177
+ attempt = checkpointed_result.operation.step_details.attempt + 1
177
178
 
178
179
  try:
179
180
  # Execute the check function with the injected logger
@@ -45,12 +45,12 @@ class CheckpointBatcherConfig:
45
45
  Attributes:
46
46
  max_batch_size_bytes: Maximum batch size in bytes (default: 750KB)
47
47
  max_batch_time_seconds: Maximum time to wait before flushing batch (default: 1.0 second)
48
- max_batch_operations: Maximum number of operations per batch (default: unlimited)
48
+ max_batch_operations: Maximum number of operations per batch (default: 250)
49
49
  """
50
50
 
51
- max_batch_size_bytes: int = 750 * 1024 # 750KB - private readonly MAX_PAYLOAD_SIZE
52
- max_batch_time_seconds: float = 1.0 # 1 second default
53
- max_batch_operations: int | float = float("inf") # No operation limit by default
51
+ max_batch_size_bytes: int = 750 * 1024 # 750KB
52
+ max_batch_time_seconds: float = 1.0
53
+ max_batch_operations: int = 250
54
54
 
55
55
 
56
56
  @dataclass(frozen=True)