A lightweight durable functions framework with different persistence layers.
Project description
Durables
A lightweight, Python-based durable function orchestration library inspired by Azure Durable Functions and Temporal.io.
Overview
Durables provides a simple framework for building reliable, stateful workflows in Python using an approach similar to popular workflow orchestration systems like Azure Durable Functions and Temporal.io. The core concepts include:
- Orchestrator Functions: Define the workflow logic and sequence
- Activity Functions: Perform the actual work units
- Input/Output Functions: Handle data flow between processes
- Persistence: Maintain workflow state for reliability and restartability
Key Features
- Python-native API with async/await syntax
- Automatic replay and checkpointing of execution state
- Support for waiting on external inputs
- Input request publishing for more interactive workflows
- Simple persistence layer with JSONL files
Installation
pip install durables
Quick Start
Here's a simple example demonstrating an orchestrator function that coordinates two activities:
from durables.durable_functions import (
orchestrator_function, activity_function, input, output
)
from durables.persistence.jsonl import JSONLStream
import uuid
@activity_function
async def say_hello(name):
return f"Hello, {name}!"
@activity_function
async def format_result(message):
return message.upper()
@orchestrator_function
async def greeting_workflow():
# Get input from external source
name_bytes = await input()
name = name_bytes.decode('utf-8')
# Call first activity
hello_result = await say_hello(name)
# Call second activity
formatted = await format_result(hello_result)
# Send output
await output(formatted.encode('utf-8'))
# Run the workflow
async def main():
session_id = uuid.uuid4()
input_stream = JSONLStream("input")
output_stream = JSONLStream("output")
# Provide input to the workflow
await input_stream.put(DurableFunctionMessage(id=0, payload=b"World"))
# Execute the workflow
await greeting_workflow(
session_id=session_id,
input_stream=input_stream,
output_stream=output_stream
)
# Read the output
result = await anext(output_stream.iterate_blocking())
print(result.payload.decode('utf-8')) # HELLO, WORLD!
Waiting for Input
Durables supports workflows that wait for external input before continuing:
@orchestrator_function
async def interactive_workflow():
# Ask a question
await output(b"What's your name?")
# Wait for response (with settings to control behavior)
name_bytes = await input()
name = name_bytes.decode('utf-8')
# Use the input
greeting = f"Nice to meet you, {name}!"
await output(greeting.encode('utf-8'))
Comparison with Azure Durable Functions & Temporal.io
While inspired by these systems, Durables offers a lighter-weight alternative:
| Feature | Durables | Azure Durable Functions | Temporal.io |
|---|---|---|---|
| Programming Model | Async/await in Python | Async/await in C#, JS, Python | SDK in multiple languages |
| Infrastructure | Minimal (local files) | Azure Functions, Storage | Temporal server cluster |
| Scalability | Local/custom | Built-in Azure scaling | Enterprise-grade |
| Monitoring | Basic logging | Azure insights | Temporal Web UI |
| Learning Curve | Gentle | Moderate | Moderate-steep |
Advanced Usage
Publishing Input Requests
For more interactive workflows, enable request publishing:
from durables.models import OrchestratorSettings
await my_workflow(
session_id=session_id,
input_stream=inbox,
output_stream=outbox,
settings=OrchestratorSettings(
wait_for_input=True,
publish_input_requests=True
)
)
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
License
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file durables-0.1.0.tar.gz.
File metadata
- Download URL: durables-0.1.0.tar.gz
- Upload date:
- Size: 29.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.8
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5a397923be170edc67762963ac3fc22d244f32d20869923d0e6e76cd4b89d92d
|
|
| MD5 |
e0a694124e142f7327746f14e7762df1
|
|
| BLAKE2b-256 |
dbfceffa645997e5b81b3ea5169dd10e9fb16691b9b61c36549befd967d33690
|
File details
Details for the file durables-0.1.0-py3-none-any.whl.
File metadata
- Download URL: durables-0.1.0-py3-none-any.whl
- Upload date:
- Size: 9.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.8
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a79e226e4812abeb4f434876e5808140a7f273cee26f57afbbcce4dfddb34b2a
|
|
| MD5 |
04b9907c0842847131ea060db2de3b26
|
|
| BLAKE2b-256 |
88f7e4c2b0aa41e807122747395a7940bbc83137a104fcd655f8406dc76c8d59
|