No project description provided
Project description
🌀 Duron
Duron is a Python library that makes async work replayable. You can pause, resume, or rerun async functions without redoing completed steps. Wrap your side effects once, keep orchestration deterministic, and Duron logs every result so repeated runs stay safe.
Why Duron?
- 🔁 Restart-safe — Rerun a job and Duron replays prior results automatically. No duplicate work.
- 🧵 Async-first — Write
async deffunctions and orchestrate them with familiarawaitsyntax. - 🔍 Typed & traceable — Decorators capture type hints so inputs and outputs serialize cleanly.
- 🗄️ Storage-agnostic — Start with file-based logging or plug in your own backend to match your stack.
- 🚀 Drop-in ready — Works in CLI tools, web backends, or long-lived agents—no special runtime or extra dependencies required.
Install
Duron requires Python 3.10+.
pip install git+https://github.com/brian14708/duron.git
Quickstart
Duron defines two kinds of functions:
@duron.durable— deterministic orchestration. It replays from logs, ensuring that control flow only advances when every prior step is known.@duron.effect— side effects. Wrap anything that touches the outside world (APIs, databases, file I/O). Duron records its return value so it runs once per unique input.
import asyncio
import random
from pathlib import Path
import duron
from duron.contrib.storage import FileLogStorage
@duron.effect
async def work(name: str) -> str:
print("⚡ Preparing to greet...")
await asyncio.sleep(2) # Simulate I/O
print("⚡ Greeting...")
return f"Hello, {name}!"
@duron.effect
async def generate_lucky_number() -> int:
print("⚡ Generating lucky number...")
await asyncio.sleep(1) # Simulate I/O
return random.randint(1, 100)
@duron.durable
async def greeting_flow(ctx: duron.Context, name: str) -> str:
message, lucky_number = await asyncio.gather(
ctx.run(work, name), ctx.run(generate_lucky_number)
)
return f"{message} Your lucky number is {lucky_number}."
async def main():
async with greeting_flow.invoke(FileLogStorage(Path("log.jsonl"))) as job:
await job.start("Alice")
result = await job.wait()
print(result)
if __name__ == "__main__":
asyncio.run(main())
To see Duron handle live input and external events, check out examples/agent.py.
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 duron-0.0.1.tar.gz.
File metadata
- Download URL: duron-0.0.1.tar.gz
- Upload date:
- Size: 29.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.9.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0d6b0b01c477b77c8a559db9211a29c20aa8fd38a7c405567c723a5928aa7fb3
|
|
| MD5 |
4ab5acb856b6f8928886ec0e3a246f64
|
|
| BLAKE2b-256 |
4ef365d2b03956d3475beb077fee8581aa4ab88ab591aa415b8e510c609cc5b5
|
File details
Details for the file duron-0.0.1-py3-none-any.whl.
File metadata
- Download URL: duron-0.0.1-py3-none-any.whl
- Upload date:
- Size: 41.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.9.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
016cabc965029d422795e6f2229ce5a637b2ed9c775636e606d1bad7c26f19d8
|
|
| MD5 |
1e94cdf7ffbc3eec04939229fdaf267a
|
|
| BLAKE2b-256 |
242947a493597088a2c8a781ba74d2f25d352e93aba6afcd166feb0bda3769d0
|