Skip to main content

Durable Workflow Python SDK

Quality Gate CI PyPI Python License

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

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. The installed package includes durable_workflow/server_compatibility.json, matching the release declarations in pyproject.toml. Its supported-server-release-baselines maps each supported Server major to its minimum stable release. Readers validate every entry before selection and refuse missing majors, malformed entries, or a contradiction with the unchanged legacy supported-server-versions 2.x baseline. An absent map retains legacy reader behavior. This declaration does not replace protocol or capability negotiation. The compatibility guide documents protocol and upgrade guarantees.

Worker protocol and cooperative cancellation

Workers use protocol 1.20 by default. For a Server that supports only 1.19, set DURABLE_WORKFLOW_WORKER_PROTOCOL_VERSION=1.19. This changes the request protocol without enabling optional worker features.

Use request_cancellation() for bounded, replayable workflow cleanup. Opt in against a Server that advertises protocol 1.20 and the required capabilities: 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.

For synchronous Nexus completion waits, the cooperative worker also negotiates nexus_cooperative_cancellation when Server advertises the installed workflow_run binding. Owned target cleanup keeps the caller pending until the Server commits delivery at the original call. Async and acceptance-only calls keep their admission behavior. Existing terminal results and recorded legacy Nexus histories retain their replay semantics.

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.

A suspended replay is not a workflow exit. Python may run finally blocks and context-manager exits when disposing of that replay. The SDK discards commands and ctx.logger messages produced only by disposal; queries observe the state at the pending command. Actual completion, failure and cooperative cancellation run cleanup through the normal history, and cold replay uses its recorded results. Put external cleanup in an Activity rather than direct I/O in a finalizer, and use ctx.cancellation_shield() when that Activity must finish after cancellation. The disposal guarantees require SDK 2.12.2 or later.

Both await activity.context().heartbeat() and synchronous activity.context().heartbeat_sync() stop at an explicit Server refusal. They raise ActivityLeaseAuthorityLost with its original .reason for an elapsed deadline, closed attempt or closed run. Cancellation continues to raise ActivityCancelled. The worker submits no result or failure for an attempt whose heartbeat refused continuation, even if application code catches that exception. A heartbeat check acts only when called. Code that never heartbeats can continue until it returns, subject to independent lease/cancellation supervision; a running native thread cannot be forcibly stopped or its effects undone by the SDK.

Development

The installed durable-workflow-replay-conformance command runs an offline Python replay shard. Its sdk-python artifact pin must match the installed distribution version reported by importlib.metadata.version("durable-workflow"). The report records that installed identity separately from the declared platform tuple and fails if metadata is missing or the SDK pin differs. Replay success does not prove installation or execution of the other declared artifacts; the aggregate runner supplies its own verified installation receipts.

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_COOPERATIVE_QUALIFICATION=1 for pytest. These cases fail if the runtime does not discover the required capability. Ordinary CI uses the SDK's default protocol and skips the optional connected cooperative cases.

License

MIT

Metadata

Release files for durable-workflow 2.14.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for durable-workflow 2.14.0
File Size Uploaded Provenance Actions
durable_workflow-2.14.0.tar.gz 690.3 kB With provenance Details for durable_workflow-2.14.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for durable-workflow 2.14.0
File Interpreter ABI Platform Actions
durable_workflow-2.14.0-py3-none-any.whl Python 3 none any Details for durable_workflow-2.14.0-py3-none-any.whl

Total release size: 1.0 MB

Release files / durable_workflow-2.14.0.tar.gz

Download URL durable_workflow-2.14.0.tar.gz
Size 690.3 kB
Tags Source
SHA-256 checksum
How to use checksums
15ec395de81eddabf5d139a4a294466c62ab851384ee47ba2e372505092ab9bc
BLAKE2b-256 checksum
How to use checksums
34c1b5ca0f281fc93eeeba084696e6e0f865fb76572dc44e33cddb0a3a82e0a8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 4, 2026.

Transparency log

Release files / durable_workflow-2.14.0-py3-none-any.whl

Download URL durable_workflow-2.14.0-py3-none-any.whl
Size 339.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
d98549a2a9a844733b19f1cabc33d28a9c01560b772b4cd28f4215268d4d0328
BLAKE2b-256 checksum
How to use checksums
d1aab34dc11c9a7a51727acbbc70852e12963f61d6672233d3278b2a0760e9c8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 4, 2026.

Transparency log

Security for durable-workflow 2.14.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for durable_workflow-2.14.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 4, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

2.14.0 This release

2 release files Full provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page