Skip to main content

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

MIT License

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

durables-0.1.0.tar.gz (29.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

durables-0.1.0-py3-none-any.whl (9.7 kB view details)

Uploaded Python 3

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

Hashes for durables-0.1.0.tar.gz
Algorithm Hash digest
SHA256 5a397923be170edc67762963ac3fc22d244f32d20869923d0e6e76cd4b89d92d
MD5 e0a694124e142f7327746f14e7762df1
BLAKE2b-256 dbfceffa645997e5b81b3ea5169dd10e9fb16691b9b61c36549befd967d33690

See more details on using hashes here.

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

Hashes for durables-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 a79e226e4812abeb4f434876e5808140a7f273cee26f57afbbcce4dfddb34b2a
MD5 04b9907c0842847131ea060db2de3b26
BLAKE2b-256 88f7e4c2b0aa41e807122747395a7940bbc83137a104fcd655f8406dc76c8d59

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page