Kruxia Flow Python SDK
Python SDK for Kruxia Flow — the AI-native durable workflow engine.
Define workflows in Python, deploy them to the Kruxia Flow server, and build custom Python workers to execute activities.
Installation
pip install kruxiaflow # or: uv add kruxiaflow
For the standard Python worker with data science packages:
pip install "kruxiaflow[std]"
Note: 0.4.0 is the first PyPI release. Earlier versions were installed from GitHub under the distribution name
kruxiaflow-python; the import package has always beenkruxiaflow, so existing code needs no changes.
Quick Start
Define a Workflow
Workflows describe WHAT to run. They compile to YAML and deploy to the Kruxia Flow API server.
from kruxiaflow import Activity, Workflow, workflow
# Step 1: Fetch weather data
fetch_weather = Activity(
key="fetch_weather",
worker="std",
activity_name="http_request",
parameters={
"method": "GET",
"url": "https://api.weather.gov/gridpoints/LOT/76,73/forecast",
},
outputs=["response"],
)
# Step 2: Send notification (depends on step 1)
send_notification = Activity(
key="send_notification",
worker="std",
activity_name="http_request",
parameters={
"method": "POST",
"url": "http://mailpit:8025/api/v1/send",
"body": {
"Subject": f"Weather Report - {workflow.id}",
"Text": f"Forecast: {fetch_weather['response.body.properties.periods[0].detailedForecast']}",
},
},
depends_on=["fetch_weather"],
)
# Build and print as YAML
weather_workflow = Workflow(
name="weather_report",
activities=[fetch_weather, send_notification],
)
print(weather_workflow)
Deploy to Kruxia Flow
from kruxiaflow import KruxiaFlow
client = KruxiaFlow(api_url="http://localhost:8080")
client.deploy(weather_workflow)
# Start a workflow instance
instance = client.start_workflow(
"weather_report",
inputs={"webhook_url": "https://httpbin.org/post"},
)
print(f"Started: {instance['workflow_id']}")
Write Python Activities with ScriptActivity
Use ScriptActivity to write activities as Python functions that run on the py-std worker:
from kruxiaflow import ScriptActivity, Workflow
@ScriptActivity.from_function(
inputs={"sales_data": [{"product": "Laptop", "amount": 1200.00, "region": "North"}]},
)
async def load_data(sales_data):
import pandas as pd
df = pd.DataFrame(sales_data)
return {"data": df.to_dict(), "row_count": len(df)}
@ScriptActivity.from_function(
inputs={"data": load_data["data"]},
depends_on=["load_data"],
)
async def sql_transform(data):
import duckdb, pandas as pd
df = pd.DataFrame(data)
results = duckdb.sql("""
SELECT region, SUM(amount) as total_sales
FROM df GROUP BY region
""").df()
return {"results": results.to_dict()}
pipeline = Workflow(
name="sales_pipeline",
activities=[load_data, sql_transform],
)
print(pipeline)
Architecture
The Python SDK has two distinct contexts:
┌──────────────────────────────────────────────────────────────────┐
│ WORKFLOW DEFINITION (my_workflow.py) │
│ Describes WHAT to run. Compiles to YAML and deploys to API. │
│ │
│ from kruxiaflow import Activity, Workflow │
│ activity = Activity(key="process").with_worker("std", "analyze")│
└──────────────────────────────────────────────────────────────────┘
│ deploys to
▼
┌──────────────────────────────────────────────────────────────────┐
│ KRUXIA FLOW API SERVER │
└──────────────────────────────────────────────────────────────────┘
▲ polls for work
│
┌──────────────────────────────────────────────────────────────────┐
│ WORKER PROCESS (custom_worker.py) │
│ Contains the actual CODE that executes activities. │
│ │
│ from kruxiaflow.worker import activity, ActivityResult │
│ @activity() │
│ async def analyze(params, ctx): ... │
└──────────────────────────────────────────────────────────────────┘
kruxiaflow.Activity— Workflow definition (describes what to run)kruxiaflow.ScriptActivity— Python function that runs on the py-std workerkruxiaflow.worker.Activity— Custom worker implementation (the code that runs)
Features
Workflow Definition API
Build workflows programmatically with full type safety:
from kruxiaflow import Activity, Input, SecretRef, Dependency
# Workflow inputs and secrets
user_content = Input("user_content", type=str, required=True)
db_url = SecretRef("db_url")
# LLM activity with cost control
analyze = Activity(
key="analyze",
worker="std",
activity_name="llm_prompt",
parameters={
"model": "anthropic/claude-haiku-4-5-20251001",
"prompt": f"Analyze: {user_content!s}",
"max_tokens": 500,
},
outputs=["result"],
settings={
"budget": {"limit": 0.10, "action": "abort"},
"retry": {"max_attempts": 3, "strategy": "exponential"},
},
)
Expression System
SQLAlchemy-style operators for conditional dependencies:
from kruxiaflow import Dependency
# Conditional dependency: only run if confidence > 0.8
save = Activity(
key="save",
...
).with_dependencies(
Dependency.on(analyze, analyze["confidence"] > 0.8)
)
Output References
Access nested JSON paths from upstream activity outputs:
# Dot-notation paths into activity outputs
analyze["result.content"]
analyze["result.usage.total_tokens"]
fetch["response.body.properties.periods[0].temperature"]
YAML Export
Every workflow compiles to YAML that deploys directly to the Kruxia Flow API:
# Print compiled YAML
print(workflow)
# Or get the YAML string
yaml_str = workflow.to_yaml()
Async Client
from kruxiaflow import AsyncKruxiaFlow
async def main():
client = AsyncKruxiaFlow(api_url="http://localhost:8080")
await client.deploy(workflow)
instance = await client.start_workflow("my_workflow", inputs={...})
Standard Python Worker (py-std)
The py-std worker provides a ready-to-use Docker image with pre-installed packages for common data processing, ML, and NLP tasks. Use it with ScriptActivity or inline scripts.
Pre-installed Packages
| Category | Packages |
|---|---|
| Core | httpx, pydantic, orjson, pyyaml |
| Data Processing | pandas, polars, pyarrow, duckdb, numpy |
| Machine Learning | scikit-learn |
| NLP | transformers, sentence-transformers, tiktoken |
Using with ScriptActivity
from kruxiaflow import ScriptActivity
@ScriptActivity.from_function(worker="py-std")
async def process_data(records, threshold=0.5):
import pandas as pd
df = pd.DataFrame(records)
filtered = df[df['value'] > threshold]
return {"count": len(filtered), "total": filtered['value'].sum()}
Using with Inline Scripts
activities:
- key: transform
worker: py-std
activity_name: script
parameters:
script: |
import pandas as pd
df = pd.DataFrame(INPUT["data"])
OUTPUT = {"result": df.describe().to_dict()}
Custom Workers
Build custom Python workers for activities that need specialized logic:
from kruxiaflow.worker import (
activity, ActivityContext, ActivityResult,
ActivityRegistry, WorkerConfig, WorkerManager,
)
@activity()
async def analyze_sentiment(params: dict, ctx: ActivityContext) -> ActivityResult:
text = params["text"]
# Your custom logic here
return ActivityResult.value("result", {"sentiment": "positive", "confidence": 0.85})
# Run the worker
async def main():
config = WorkerConfig() # reads from KRUXIAFLOW_* env vars
registry = ActivityRegistry()
registry.register(analyze_sentiment)
manager = WorkerManager(config=config, registry=registry)
await manager.run()
Examples
15+ production-ready examples covering YAML workflows, Python SDK definitions, and ScriptActivity patterns:
| # | Example | Concepts |
|---|---|---|
| 1 | Weather Report | Sequential workflow, HTTP requests, templates |
| 2 | User Validation | Conditional branching, PostgreSQL queries |
| 3 | Document Processing | Parallel execution, fan-out/fan-in |
| 4 | Content Moderation | LLM cost tracking, budget control, retry |
| 5 | Research Assistant | Multi-model fallback, budget-aware selection |
| 11 | GitHub Health Check | ScriptActivity, HTTP API integration |
| 12 | Sales ETL Pipeline | pandas, DuckDB SQL on DataFrames, Parquet |
| 13 | Customer Churn Prediction | Parallel ML training, LLM explanations |
| 14 | Document Intelligence | AI-powered document analysis |
| 15 | Content Moderation System | Multi-stage moderation pipeline |
| Custom Worker | Worker SDK, ActivityRegistry, ActivityContext |
Examples 11-15 include both .py (Python SDK) and .yaml (compiled output) files.
Run any example to see its compiled YAML:
python examples/01_weather_report.py
Development
# Clone the repo
git clone https://github.com/kruxia/kruxiaflow-python.git
cd kruxiaflow-python
# Install dev dependencies
uv sync --dev
# Run tests (95% coverage required)
uv run pytest
# Lint and format
uv run ruff check
uv run ruff format
# Type check
uv run ty check
Related
- Kruxia Flow — The workflow engine server (Rust)
- kruxiaflow.com — Project homepage
- Discord — Community chat
License
Apache-2.0 (versions prior to July 2026 were MIT)
Metadata
Release files for kruxiaflow 0.4.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| kruxiaflow-0.4.0.tar.gz | 67.4 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| kruxiaflow-0.4.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 114.5 kB
Release files / kruxiaflow-0.4.0.tar.gz
| Download URL | kruxiaflow-0.4.0.tar.gz |
|---|---|
| Size | 67.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
23f47f3e2905977a6761e776888a60bca17ccd2753db9af1d07c82f0f99b3266
|
|
BLAKE2b-256 checksum How to use checksums |
2d82fe5b7c5f2308a7e6e28064cc3bacd65c656dfed015c597fd8c9bccf55235
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
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 Jul 18, 2026.
Transparency logRelease files / kruxiaflow-0.4.0-py3-none-any.whl
| Download URL | kruxiaflow-0.4.0-py3-none-any.whl |
|---|---|
| Size | 47.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
0e9a026c88f1c44e29565c74618ae8698c30768b11e9312f8492cf6860a13c6b
|
|
BLAKE2b-256 checksum How to use checksums |
9bccad7d32324ecad0f25f9399670d83e88c7c6e148193093c2e7d4dd8a733c6
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.12
|
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 Jul 18, 2026.
Transparency log