Skip to main content

openwop-client 2.x — Python SDK for OpenWOP

OpenWOP is the open-source protocol for multi-agent workflow orchestration: run AI agents as workflows you can watch, pause for human approval and replay, on any host that implements it.

openwop.dev · Quickstart

pip install "openwop-client>=2,<3"
from openwop_client import CreateRunRequest, OpenwopClient

client = OpenwopClient(base_url="https://api.example.com", api_key="hk_test_abc123")
resp = client.runs_create(CreateRunRequest(workflowId="my-workflow", inputs={"q": "hello"}))
for event in client.runs_events(resp.runId):
    print(event.sequence, event.type)

For implementers

This package is the reference Python client for the v2 major (spec/v2/, RFC 0168 §D): synchronous, zero runtime deps, one typed method per operation in spec/v2/path-manifest.json (55 operations), typed dataclasses, and pure-stdlib SSE iterators for the run and host event channels.

pip install "openwop-client>=2,<3"   # 2.10.0 — v2-only; the 1.x client stays on openwop-client<2

Spec: github.com/openwop/openwop · Corpus tag: see CORPUS_TAG · Mirrors: api/v2/openapi.yaml, schemas/v2/, spec/v2/errors.json · Sibling: the TypeScript client at sdk/typescript-v2/

The 1.x package (sdk/python/) is untouched and keeps publishing for v1 hosts. This is a v2-ONLY client: it never sends a /v1/… path. The import name stays openwop_client.

What is different from 1.x (RFC 0172 / 0171 / 0173)

1.x 2.x
/v1/runs, /v1/agents, … Bare origin, unversioned path keys: /runs, /agents, …
Negotiation by protocolVersion OpenWOP-Version: <major>.0 on every request (ctor major=2); 406 protocol_version_unsupported when the host does not list the major.
dedup=True → X-Dedup dedup=True → OpenWOP-Dedup: enforce.
runs_poll_events(last_sequence=) runs_poll_events(after_sequence=); the response is the closed { runId, events, lastSequence, status, isTerminal }.
Capabilities with supported sub-dataclasses The closed v2 root: protocolVersions + preferredVersion required, families: dict[str, CapabilityRecord] (status / since / until / witness / facets). CAPABILITY_FAMILY_KEYS is generated from the schema.
HTTP_ERROR_CODES hand-kept ERROR_CODES / ErrorCode (108) generated from spec/v2/errors.json, plus ERROR_CODE_HTTP_STATUS, RETRIABLE_ERROR_CODES, is_vendor_error_code.
*_workspace_file (4), runs_debug_bundle, RegistryClient Removed — not v2 operations (the registry is resolved through .well-known/openwop-registry.json endpoints).
quote(run_id, safe='') → t%2Fr Tenant-bound ids (run_id, subscription_id) go on the wire projected: acme/r-9f3c → acme~2Fr-9f3c (identity.md §5 "Wire form"). project_id / unproject_id are exported; unproject_id reads both the projected and the percent form a link may carry.
— runs_compensation, runs_effects, host_effect_seams (RFC 0173), host_events (the hostEvents SSE channel).
Webhook openwop-Webhook-* names, v1=<hex> OpenWOP-* only (X-openwop-* accepted through the overlap); sha256=<hex>; an unrecognized OpenWOP-Signature-Algorithm is rejected.

Quickstart

from openwop_client import CreateRunRequest, OpenwopClient, RunConfigurable, WopError, is_terminal_run_status

client = OpenwopClient(base_url="https://api.example.com", api_key="hk_test_abc123")  # major=2 → OpenWOP-Version: 2.0

caps = client.discovery_capabilities()            # the closed v2 root
print(caps.preferredVersion, caps.protocolVersions, "webhooks" in caps.families)

resp = client.runs_create(
    CreateRunRequest(workflowId="my-workflow", inputs={"q": "hello"}, configurable=RunConfigurable(run={"runTimeoutMs": 60_000})),
    idempotency_key="idem-1",
    dedup=True,
)

for event in client.runs_events(resp.runId, stream_mode=("updates", "messages")):
    print(event.sequence, event.type)

cursor = None
while True:                                       # long-poll fallback
    page = client.runs_poll_events(resp.runId, after_sequence=cursor)
    cursor = page.lastSequence
    if page.isTerminal:
        break

comp = client.runs_compensation(resp.runId)       # None when `compensation` is unadvertised

try:
    client.runs_get("tenant/does-not-exist")
except WopError as err:
    if err.envelope and err.envelope.error == "not_found":
        ...

Webhook receivers:

from openwop_client import read_webhook_headers, verify_webhook_signature

read = read_webhook_headers(request.headers)
outcome = verify_webhook_signature(secret, read.signature, read.timestamp, raw_body, algorithm_header=read.algorithm) if read else None

Generated surface

src/openwop_client/_generated.py is produced by scripts/generate.py from the vendored spec/v2/errors.json and schemas/v2/capabilities.schema.json; python3 scripts/generate.py --check (run by scripts/sdks-check.sh) fails when it drifts.

Development

python3 scripts/generate.py --check
ruff check .
PYTHONPATH=src python3 -m unittest discover -s tests

Metadata

Release files for openwop-client 2.10.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 openwop-client 2.10.0
File Size Uploaded Provenance Actions
openwop_client-2.10.0.tar.gz 79.1 kB With provenance Details for openwop_client-2.10.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for openwop-client 2.10.0
File Interpreter ABI Platform Actions
openwop_client-2.10.0-py3-none-any.whl Python 3 none any Details for openwop_client-2.10.0-py3-none-any.whl

Total release size: 139.5 kB

Release files / openwop_client-2.10.0.tar.gz

Download URL openwop_client-2.10.0.tar.gz
Size 79.1 kB
Tags Source
SHA-256 checksum
How to use checksums
21f73208874bab52d6eb4af768dd7e6a2f3c44638f856cda91be1c3e393a5f46
BLAKE2b-256 checksum
How to use checksums
0f20263e055facfa92019005a880a9ccd8ef4b4328937cfa3618e8f4e2c5d0a3
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

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 2, 2026.

Transparency log

Release files / openwop_client-2.10.0-py3-none-any.whl

Download URL openwop_client-2.10.0-py3-none-any.whl
Size 60.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
8bdf633ecb8ab96ae366d1dcffaaa1707198683f68b20f3eb70ca9a00b4d433e
BLAKE2b-256 checksum
How to use checksums
6324760c2078cd435ff14e12c9134ebe4a30247f5541a3047fb3f9ce910f3077
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

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 2, 2026.

Transparency log

Security for openwop-client 2.10.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

Both files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for openwop_client-2.10.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 2, 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.

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