Metadata-Version: 2.4
Name: ogha
Version: 0.1.1
Summary: Durable execution for Python — write ordinary code that survives crashes, restarts, and month-long waits. Nine methods, one log.
Project-URL: Homepage, https://coding2fun.in/ogha
Project-URL: Documentation, https://coding2fun.in/ogha/python
Author: Kishore Karunakaran
License-Expression: Apache-2.0
Keywords: background-jobs,distributed-systems,durable-execution,orchestration,resilience,saga,workflow,workflows
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
Classifier: Topic :: System :: Distributed Computing
Classifier: Typing :: Typed
Requires-Python: >=3.10
Requires-Dist: cbor2>=5.6
Description-Content-Type: text/markdown

# Ogha — durable execution for Python

Write ordinary Python. It survives crashes, restarts, deploys, and month-long
waits. You split your code into **steps** (units of real work) and **workflows**
(compositions of them); Ogha records every step and replays it faithfully after
any failure, so a multi-step process finishes even if a worker dies halfway
through. No retry loops, no idempotency tables, no state machines to hand-build.

> **Alpha.** The API is stable in shape (nine methods); details may still change
> before 1.0.

```python
import ogha

@ogha.step(retry=ogha.RetryPolicy(max_attempts=5), pivot=True)
def charge(order, amount):
    return payments.charge(order["card"], amount)   # runs once; recorded

@ogha.workflow
async def checkout(ctx, order):
    total   = await ctx.call(validate, order)
    receipt = await ctx.call(charge, order, total)  # survives a crash right here
    return receipt
```

## Install

```bash
pip install ogha          # Python 3.10+
```

## Run the engine

Ogha ships as one container that carries the engine, storage, and a live
dashboard. Pull it (public, no login) and open `http://localhost:8080`:

```bash
docker run -p 8080:8080 public.ecr.aws/h6s8i3h8/ogha:0.1.0-obf \
  --storage=postgres --dsn="postgres://…" --auth-disabled
```

A ready-to-use `docker compose` (engine + PostgreSQL) is in the getting-started
guide below.

## The nine methods

Everything a workflow can do is nine methods on `ctx`:

| Method | What it does |
| :--- | :--- |
| `ctx.call(fn, …)` | run a step durably |
| `ctx.rpc(svc, m)` | durably call a service you can't import |
| `ctx.spawn(wf)` | start a child workflow — its own run |
| `ctx.join(*h, until=)` | wait on many: all / any / quorum(n) |
| `ctx.sleep(s)` | durable sleep, seconds to months |
| `ctx.wait(name)` | wait for the outside world (a webhook) |
| `ctx.gate(action)` | a fail-closed human approval |
| `ctx.emit(event)` | a milestone on the run's timeline |
| `ctx.cancel(h?)` | cooperatively cancel a child or the run |

Retries, timeouts, and saga compensation are declared on the step
(`retry=`, `compensate_with=`, `pivot=`), not scattered through the workflow.

## A worker

A worker is a long-running process that executes your steps; importing your
module registers them.

```python
import ogha, myapp   # importing registers @step / @workflow
client = ogha.connect("http://localhost:8080")
ogha.Worker(client, target="python://checkout", concurrency=8).run()
```

Submit work and wait for it:

```python
run = client.submit("checkout", data, target="python://checkout")
result = client.result(run.run_id)      # blocks until terminal
```

## Documentation

- **Overview & the nine methods:** https://coding2fun.in/ogha
- **Getting started (full example):** https://coding2fun.in/ogha/python

## License

See the project for licensing.
