Quick Start (Embedded)
Run a one-task workflow inside your own process, against a local SQLite database. Pick your language — the engine is the same.
Add the dependencies — cloacina = "0.12" and cloacina-workflow = "0.12"
(the task macro generates code that references it directly), plus tokio and
serde_json — then:
use cloacina::executor::WorkflowExecutor;use cloacina::runner::{DefaultRunner, DefaultRunnerConfig};use cloacina::{task, workflow, Context, TaskError};
#[workflow(name = "greeting", description = "Say hello")]pub mod greeting { use super::*;
#[task] pub async fn hello(ctx: &mut Context<serde_json::Value>) -> Result<(), TaskError> { ctx.insert("message", serde_json::json!("Hello World!"))?; Ok(()) }}
#[tokio::main]async fn main() -> Result<(), Box<dyn std::error::Error>> { let runner = DefaultRunner::with_config( "sqlite://app.db", DefaultRunnerConfig::default(), ).await?;
let result = runner.execute("greeting", Context::new()).await?; println!("status: {:?}", result.status);
runner.shutdown().await?; Ok(())}Run with cargo run.
Install with pip install cloaca, then:
import cloaca
with cloaca.WorkflowBuilder("greeting") as builder: builder.description("Say hello")
@cloaca.task() def hello(context): context.set("message", "Hello World!") return context
if __name__ == "__main__": runner = cloaca.DefaultRunner("sqlite://app.db") result = runner.execute("greeting", cloaca.Context()) print("status:", result.status) runner.shutdown()Run with python first_workflow.py.
You just defined a workflow, ran it in-process, and persisted its state to SQLite.
- Tutorials — build up from here, step by step.
- Engine & Primitives — what a Workflow, Task, Context, and Runner actually are.
- Going to production embedded? Running embedded in production.