Languages
Per-language support and serve adapters for the Go, TypeScript, and Python Workflow SDKs.
The three SDKs are contract-locked — the same round-trip tests assert their opcode envelopes, protocol types, and HMAC signatures are byte-identical. That means the protocol surface is uniform. What differs is how complete each implementation is and which HTTP frameworks each one can serve behind.
At a glance
| Go | TypeScript | Python | |
|---|---|---|---|
| Package | github.com/ductor-io/ductor-go | @ductor/sdk | ductor (PyPI) |
| Version | — | 0.1.0 | — |
execute (run steps) | ✅ | ✅ | ❌ HTTP 501 |
discover / health-check / code | ✅ | ✅ | ✅ |
| Protocol types + HMAC | ✅ | ✅ | ✅ (round-trips) |
Python execution is not supported
Go and TypeScript can execute workflows end to end. Python supports
registration, discovery, health checks, protocol types, and signing, but its
execute action returns HTTP 501.
Per-language support
Module github.com/ductor-io/ductor-go (Go 1.25). Install and import the
ductor package; serve adapters live in the ductor/serve subpackage.
go get github.com/ductor-io/ductor-goimport (
"net/http"
"github.com/ductor-io/ductor-go/ductor"
"github.com/ductor-io/ductor-go/ductor/serve"
)
client := ductor.NewClient(ductor.ClientOptions{
AppID: "checkout",
SigningKey: []byte(os.Getenv("DUCTOR_SIGNING_KEY")),
})
// register workflows on client...
http.Handle("/api/ductor", serve.NetHTTP(client))Serve adapters (sdks/go/ductor/serve/):
| Adapter | Status | Notes |
|---|---|---|
serve.NetHTTP | Production | Stdlib http.Handler. Mount on any path. |
serve.Lambda | Production | AWS API Gateway proxy integration; handles base64 bodies and case-insensitive headers. |
serve.Connect | Pass-through | Forwards to NetHTTP under a Connect-conventional path prefix. Not a Connect-RPC bridge. |
Package @ductor/sdk, version 0.1.0. It has full protocol parity with Go —
Client, the step API (run, sleep, sleepUntil, waitForEvent,
waitForSignal, invoke), opcode types, and the HMAC sign/verify helpers.
npm install @ductor/sdkServe adapters are published as package subpath exports (from package.json):
| Import | Framework |
|---|---|
@ductor/sdk/serve/express | Express |
@ductor/sdk/serve/hono | Hono |
@ductor/sdk/serve/next | Next.js |
@ductor/sdk/serve/nethttp | Node http |
Package ductor on PyPI. Install the core, or the fastapi extra for the
Starlette/FastAPI adapters.
pip install ductor # core
pip install ductor[fastapi] # + FastAPI/Starlette adaptersYou serve it through the ASGI adapter, which works with any ASGI 3.0 server —
FastAPI, Starlette, Uvicorn, or Hypercorn (ductor.serve.asgi.asgi_app):
from fastapi import FastAPI
from ductor import Client, WorkflowOpts, Trigger
from ductor.serve.asgi import asgi_app
app = FastAPI()
client = Client(app_id="checkout")
client.workflow("place-order", WorkflowOpts(trigger=Trigger(event="order.placed")))
app.mount("/api/ductor", asgi_app(client))Workflow execution is unavailable in Python
The Python SDK supports discover, health-check, and code. The execute
action returns HTTP 501, so use this SDK for registration and discovery,
not workflow execution.
Operational gotchas
These apply regardless of language:
ductor devstill needs Postgres. The dev harness embeds Redis (via miniredis) but not the database — you must provide a reachable Postgres..envis not auto-loaded in production. Local dev may read it, but a production process expects real environment variables to be set.- An empty signing key disables HMAC verification. Convenient in development, unacceptable in production — always configure a key for a deployed bridge.
Related
Bridge Protocol
The signed HTTP protocol between Ductor and your SDK — the five actions, the opcode wire format, HMAC signing, and the sync, checkpoint, and inline-run server endpoints.
Engine Extensions
The eight extension-point types — strategies, plugins, CEL functions, middleware, providers — how to ship them, and the spec.yaml that declares their identity and compatibility.