Getting Started¶
The Dory SDK lets you build stateful Python processors that survive pod migrations, graceful shutdowns, and node drains with their in-memory state intact. This page gets you from an empty directory to a running processor.
Package naming
The package installs as dory-processor-sdk but imports as dory. All examples use from dory import ... / from dory.simple import ....
Install¶
Optional extras:
| Extra | Installs | When to use |
|---|---|---|
[production] |
kubernetes client and runtime deps |
Required for the default ConfigMap state backend; used by the generated Dockerfile |
[dev] |
Linting and test tooling | Local development |
ConfigMap backend needs [production]
The default state backend (configmap) requires the kubernetes package. Without it, the SDK silently sets K8S_AVAILABLE = False and the error only surfaces on the first ConfigMap operation. Install the [production] extra for any Kubernetes deployment. See State Management.
Scaffold a project¶
Options:
| Flag | Meaning |
|---|---|
-o DIR |
Output directory |
-i IMG |
Base image used in the generated Dockerfile |
-f |
Overwrite existing files |
dory init generates two files:
main.py— a class-basedBaseProcessorwithcounter = stateful(0)anddata = stateful(dict), plusstartup/run/shutdownhooks and a__main__guard.Dockerfile—python:3.11-slim,pip install dory-processor-sdk[production],EXPOSE 8080 8081, and aHEALTHCHECKthat curls/health.
Minimal class-based example¶
from dory import DoryApp, BaseProcessor, stateful
class CounterProcessor(BaseProcessor):
counter = stateful(0)
seen = stateful(dict)
async def startup(self) -> None:
self.context.logger().info("starting up")
async def run(self) -> None:
async for i in self.run_loop(interval=1.0):
self.counter += 1
async def shutdown(self) -> None:
self.context.logger().info(f"final counter={self.counter}")
if __name__ == "__main__":
DoryApp().run(CounterProcessor)
stateful(...) declares class attributes that round-trip automatically across restarts and migrations. Use a factory (dict/list) for mutable defaults. See Core Concepts for the full lifecycle.
config() and logger() are methods
context.config() and context.logger() are methods — call them with (). Treating them as properties is a common error.
Function-based alternative¶
For simple processors, the dory.simple API skips the class. The @processor decorator collects module-level state(...) globals and, when the module runs as __main__, starts the app automatically.
from dory.simple import processor, state
counter = state(0)
@processor
async def main(ctx):
async for i in ctx.run_loop(interval=1.0):
counter.value += 1
dory.simple is not re-exported
Import the function API directly: from dory.simple import processor, state. It is not available as from dory import processor. The @processor decorator must be at module top level.
Running locally¶
Run either form directly with Python:
DoryApp().run(...) wraps asyncio.run(...), starts the health server, runs startup(), restores any saved state, then enters your run() loop. Press Ctrl+C (SIGINT) to trigger graceful shutdown and a final state save.
Ports served¶
A single HTTP server runs on the health port (default 8080), exposing:
| Path | Purpose |
|---|---|
/health |
Liveness/readiness probes |
/metrics |
Prometheus metrics — see Observability |
/state |
State capture for pod migration (bearer auth) — see State Management |
/prestop |
PreStop hook: request shutdown + immediate state save |
The generated Dockerfile also exposes 8081. Set the port with DORY_HEALTH_PORT (0 = auto-assign).
Validate configuration¶
Production config comes from the orchestrator
In production, the Dory orchestrator injects configuration through environment variables (pod identity, state backend, timeouts, orchestrator URL, tokens). You do not hand-write production config — see Configuration for the full env var reference.
Next steps¶
- Core Concepts — lifecycle,
BaseProcessor,ExecutionContext, decorators - State Management — backends, serialization, recovery
- Resilience — circuit breakers, retries, recovery primitives
- Edge & Failover — fencing, roles, heartbeats
- API Reference