Skip to main content

Durable functions using monty-python

Project description

Durable Monty

⚠️ Experimental: This is an experimental project exploring a different approach to durable functions. Not recommended for production use yet.

Durable functions for Python. Write normal async/await code that pauses at gather(), executes tasks in parallel (even distributed), and resumes when done.

What Are Durable Functions?

Durable functions are workflows that survive crashes and restarts. Your code pauses when waiting for tasks, saves its state to a database, and resumes exactly where it left off when tasks complete - even if your process dies in between.

Perfect for: Long-running workflows, parallel task execution, distributed systems, background jobs.

How It Works

Powered by monty-python - a sandboxed Python interpreter that can pause and serialize execution state. When your code hits await gather(), Monty captures the exact execution state (~800 bytes), returns pending tasks, and later resumes from that exact point with results.

Result: Pure Python async/await that works like Temporal or AWS Step Functions, but simpler.

Why This Approach Is Simpler

Other frameworks (Temporal, Durable Functions, etc.):

  • Re-execute your entire function from the start on every resume
  • Use replay/event sourcing to return cached results for completed calls
  • Example: If your workflow pauses at step 7, resuming re-runs steps 1-6 (with cached results) before continuing
  • Requires deterministic code and careful side-effect management

Durable Monty:

  • Serializes the exact Python execution state (call stack, variables, everything)
  • No re-execution - just deserialize and continue from where you left off
  • True pause/resume - no replay, no determinism requirements, no special coding patterns
  • Simpler mental model: "save and restore" instead of "replay and cache"

Trade-offs:

  • Code versioning: Changing workflow code can break in-flight executions (serialized state expects compatible code)
  • Migration complexity: Updating workflows requires careful handling of existing executions
  • Less proven: Built on pydantic-monty, which is newer than battle-tested frameworks like Temporal
  • Python-only: Requires deep interpreter integration, unlike replay-based systems that work with any language

The main practical challenge: if you iterate quickly on workflow code, in-flight executions may break on deployment. Consider draining executions before code changes or using versioned workflows.

from durable_monty import init_db, OrchestratorService, Worker, LocalExecutor

def process(item):
    return f"processed_{item}"

code = """
from asyncio import gather
results = await gather(
    process('a'),
    process('b'),
    process('c')
)
results
"""

service = OrchestratorService(init_db())
# Pass function object - full path derived automatically
exec_id = service.start_execution(code, [process])

# Process until complete
worker = Worker(service, LocalExecutor())
worker.run(until_complete=True)

# Get the result
output = service.get_result(exec_id)
print(output)  # ['processed_a', 'processed_b', 'processed_c']

Install

uv add durable-monty

How It Works

  1. Code hits gather() → pauses and saves state (~800 bytes)
  2. Creates pending calls in database
  3. Worker picks them up and executes in parallel
  4. When all complete → resumes and returns result

State survives restarts. Parallel execution. Pure Python.

Distributed Execution

Redis Queue:

uv add durable-monty --extra rq
from durable_monty.executors.rq import RQExecutor

worker = Worker(service, RQExecutor())
worker.run()

# Start RQ workers: rq worker durable-monty

Event-driven (Lambda, Modal):

uv add durable-monty --extra api
from durable_monty.api import create_app
import uvicorn

app = create_app(service)
uvicorn.run(app, port=8000)

# Executors POST results to: /webhook/complete

Examples

  • examples/with_worker.py - Local execution
  • examples/with_rq.py - Redis Queue
  • examples/with_webhook.py - Webhooks

Development

git clone https://github.com/koenvo/monty-durable
cd monty-durable
uv sync
uv run pytest

License

MIT

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

durable_monty-0.1.5.tar.gz (62.6 kB view details)

Uploaded Source

Built Distribution

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

durable_monty-0.1.5-py3-none-any.whl (15.9 kB view details)

Uploaded Python 3

File details

Details for the file durable_monty-0.1.5.tar.gz.

File metadata

  • Download URL: durable_monty-0.1.5.tar.gz
  • Upload date:
  • Size: 62.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for durable_monty-0.1.5.tar.gz
Algorithm Hash digest
SHA256 91146072fcbaa0b83362d1a447786b60e701e7aabb8307df252dbad4f00dd805
MD5 8584238765c15003cfa24e17dd7bbfde
BLAKE2b-256 ab4091864c4ab3d926052d5f613cdf65b7dd497c554e067da3abb837c14c946a

See more details on using hashes here.

Provenance

The following attestation bundles were made for durable_monty-0.1.5.tar.gz:

Publisher: release.yml on koenvo/durable-monty

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file durable_monty-0.1.5-py3-none-any.whl.

File metadata

  • Download URL: durable_monty-0.1.5-py3-none-any.whl
  • Upload date:
  • Size: 15.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for durable_monty-0.1.5-py3-none-any.whl
Algorithm Hash digest
SHA256 63df22cdd98a8e9602383e934e52ed3f09cc1263b437cae827b83a131f49ec5e
MD5 3bf8ef25d899808bfd6c9a256d9ae3a3
BLAKE2b-256 40bb2aad0c46e2e520ed8dc59c917f6331fe4494763c3cb6dd4aae169b5c9208

See more details on using hashes here.

Provenance

The following attestation bundles were made for durable_monty-0.1.5-py3-none-any.whl:

Publisher: release.yml on koenvo/durable-monty

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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