Skip to content

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

pip install dory-processor-sdk

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
pip install "dory-processor-sdk[production]"

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

dory init my-processor

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-based BaseProcessor with counter = stateful(0) and data = stateful(dict), plus startup/run/shutdown hooks and a __main__ guard.
  • Dockerfilepython:3.11-slim, pip install dory-processor-sdk[production], EXPOSE 8080 8081, and a HEALTHCHECK that 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:

python main.py

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

dory validate          # validate default config
dory validate -c FILE  # validate a specific config file

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