Async Durable Execution for Python¶
Build long-running AWS Lambda workflows with native async/await. The SDK
checkpoints completed work, suspends waits without active compute, and resumes
workflows after interruptions.
from datetime import timedelta
from async_durable_execution import durable_callable, durable_execution, step, wait
@durable_callable
async def reserve_inventory(order_id: str) -> dict:
return {"order_id": order_id, "reserved": True}
@durable_execution
async def handler(event: dict) -> dict:
reservation = await step(
reserve_inventory(event["order_id"]),
name="reserve-inventory",
)
await wait(timedelta(hours=24), name="payment-window")
return {"status": "ready-to-ship", "reservation": reservation}
Completed steps return their checkpointed results during replay instead of running again.
Why This SDK¶
- Async-first: handlers, steps, callbacks, child contexts,
flownodes, map functions, and condition checks useasync def. - Durable primitives: compose checkpointed steps, waits, callbacks, child contexts, invokes, maps, and parallel branches.
- Declarative DAG workflows: define validated acyclic graphs with typed inputs, conditional dependencies, failure routes, and durable node bodies.
- Normal asyncio composition: durable operations return
asyncio.Taskobjects and work withasyncio.gather(). - Custom operation SPI: third-party packages can reserve stable primitive identities and build replay-safe durable operations without importing SDK internals.
- Local and cloud testing: run the same durable handler in memory or against a deployed Lambda function.
Community maintained
This project is a community-maintained async fork of the Apache-2.0 licensed AWS Durable Execution Python SDK. See the SDK comparison before choosing it for production.
Execution Model¶
A durable workflow is replayed, not resumed from an in-memory Python stack. When a wait finishes or an interrupted execution continues, Lambda invokes the handler again from its first line. The SDK uses the saved execution history to avoid repeating completed durable operations.
sequenceDiagram
participant L as AWS Lambda
participant H as handler()
participant S as SDK and durable history
L->>H: First invocation
H->>S: step("reserve-inventory")
S-->>H: Run it and save the result
H->>S: wait("payment-window")
S-->>L: Save progress and suspend
Note over L,S: The payment window ends
L->>H: Invoke again from the first line
H->>S: step("reserve-inventory")
S-->>H: Return the saved result
H->>S: wait("payment-window")
S-->>H: The wait is complete
H-->>L: Continue and return the response
In the example above, reserve_inventory() runs only during the first
invocation. On the second invocation, ordinary handler code before the wait
runs again, but step() returns the saved reservation instead of calling
reserve_inventory() again.
This gives workflow code two different behaviors:
- Ordinary Python code replays. For the same event and saved results, it must make the same decisions and call durable operations in the same order.
- Durable operations use history. Completed steps return saved results, and waits or callbacks continue from their recorded state.
Keep API calls, database access, filesystem operations, random values, UUIDs,
clock reads, and other side effects inside checkpointed steps. Standard
logging calls are replay-aware and can remain in the handler.
Next Steps¶
- Follow the getting-started guide.
- Apply common workflow patterns.
- Deploy and invoke a durable Lambda function.
- Learn the advanced asyncio patterns.
- Build custom durable operations.
- Define a durable DAG workflow.
- Browse the API reference.
- Test locally with the runner API.