Durable Workflow Python SDK
Build durable Python workflows and activities against Durable Workflow Cloud or a self-hosted Server. The SDK uses the same language-neutral runtime protocol as the first-party PHP and Rust SDKs.
Install
pip install durable-workflow
Python 3.10 or newer is required.
Quickstart
import asyncio
from uuid import uuid4
from durable_workflow import Client, Worker, workflow, activity
@activity.defn(name="greet")
def greet(name: str) -> str:
return f"hello, {name}"
@workflow.defn(name="greeter")
class GreeterWorkflow:
def run(self, ctx, name):
result = yield ctx.schedule_activity("greet", [name])
return result
async def main():
workflow_id = f"greet-{uuid4().hex}"
async with Client(
"http://server:8080",
token="dev-token-123",
namespace="default",
) as client:
worker = Worker(
client,
task_queue="python-workers",
workflows=[GreeterWorkflow],
activities=[greet],
)
handle = await client.start_workflow(
workflow_type="greeter",
workflow_id=workflow_id,
task_queue="python-workers",
input=["world"],
)
await worker.run_until(workflow_id=workflow_id, timeout=30.0)
result = await client.get_result(handle)
print(result) # "hello, world"
if __name__ == "__main__":
asyncio.run(main())
Pass the Server origin to Client without a trailing /api. For Cloud, pass
the complete namespace runtime URL exactly as provisioned. Cloud client and
worker processes use separate runtime credentials:
client = Client(
runtime_url,
control_token=client_token,
worker_token=worker_token,
namespace=namespace,
)
Keep the client token in application processes and the worker token in worker processes when deploying them separately.
Capabilities
- Workflows, activities, child workflows, timers, and continue-as-new
- Signals, queries, validated updates, schedules, and message streams
- Activity retries, timeouts, cancellation, and heartbeats
- Deterministic parallel work, side effects, version markers, and sagas
- Replay verification and an in-process workflow test environment
- Avro payloads, external payload storage, metrics, and interceptors
See the capability matrix for the complete cross-SDK contract.
Documentation
- Python SDK portal and API reference
- Python SDK guide
- Complete SDK reference
- Runnable examples
- Symmetric SDK playground
Runtime choices
Use Durable Workflow Cloud
for a managed namespace, or run the published
durableworkflow/server
image yourself. Workflow and activity type names, task queues, and payloads are
portable between both runtime choices.
Compatibility
Stable 2.x SDK releases follow semantic versioning and negotiate runtime
capabilities with Server at startup. Use stable 2.x SDK and Server channels
for new applications. The compatibility guide
documents protocol and upgrade guarantees.
Cooperative cancellation release candidate
Use request_cancellation() for bounded, replayable workflow cleanup. Opt in
against a Server that advertises protocol 1.20 and the required capabilities:
set DURABLE_WORKFLOW_WORKER_PROTOCOL_VERSION=1.20 and include
cooperative_cancellation in the Worker's capabilities. Durable local callback
admission also needs prepared_local_activities, with
prepared_local_activity_cancellation_policies for explicit local policies.
Independently cancellable scopes remain disabled.
The cooperative worker supervises async and synchronous activity callbacks independently of application heartbeats. Existing terminal cancellation remains available. See the cancellation guide for immutable context, operation policies, shielded cleanup and recovery.
Development
pip install -e '.[dev]'
ruff check src/ tests/
mypy src/durable_workflow/
pytest tests/ -m "not integration"
Integration tests use Docker:
export COMPOSE_PROJECT_NAME=sdk-python-local
docker compose -f docker-compose.test.yml up -d --build --wait
SERVER_PORT=$(docker compose -f docker-compose.test.yml port server 8080 | sed 's/.*://')
DURABLE_WORKFLOW_SERVER_URL="http://127.0.0.1:$SERVER_PORT" DURABLE_WORKFLOW_AUTH_TOKEN=test-token pytest tests/integration/ -v
docker compose -f docker-compose.test.yml down -v
Candidate cooperative cancellation qualification is explicit. In a manual CI
run, supply an exact public server_commit and set cooperative_qualification
to true. CI verifies that checkout, builds the candidate Server, enables protocol
1.20, runs the connected cases and retains JUnit, raw observations, image
authority and exact source provenance. An optional exact native_commit mounts
that public Native checkout read-only into the test stack. The image's published
Composer authority stays intact and the evidence identifies the source overlay.
These are source qualification runs. For a local
candidate, set DURABLE_WORKFLOW_WORKER_PROTOCOL_VERSION=1.20 before starting
Compose and DURABLE_WORKFLOW_COOPERATIVE_QUALIFICATION=1 for pytest. These cases
fail if the runtime does not discover the required capability. Ordinary CI
keeps protocol 1.19 and skips this unpublished feature's connected cases.
License
Metadata
Release files for durable-workflow 2.4.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| durable_workflow-2.4.0.tar.gz | 488.3 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| durable_workflow-2.4.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 755.1 kB
Release files / durable_workflow-2.4.0.tar.gz
| Download URL | durable_workflow-2.4.0.tar.gz |
|---|---|
| Size | 488.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
5dc1883256513041e2d9c832146217ae1b41da3a244011da140c2f132c4a05b2
|
|
BLAKE2b-256 checksum How to use checksums |
77bf4918c082ec18df3143f68d746015544e22bff8b0cfaf7cdbc610ebdc3e41
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.13.14
|
Release files / durable_workflow-2.4.0-py3-none-any.whl
| Download URL | durable_workflow-2.4.0-py3-none-any.whl |
|---|---|
| Size | 266.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
7439f9fd84480258d263f382983655ac3516c975420c342b9aedf8e62ee5104e
|
|
BLAKE2b-256 checksum How to use checksums |
21bac924f65713a41dfaedaafe03998a72d69bb45e4435409acc2ced7c7246dc
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.13.14
|