Skip to main content

grampy

A small workflow graph for work queues that already live in a storage — a database, a key-value store, or plain memory: the storage is a driver.

pip install grampy-q              # from quazardous import grampy
pip install "grampy-q[postgres]"  # + the PostgreSQL driver (SQLAlchemy)

Try the brick sorter → — a sorting line where bricks are sorted by colour, TNT bricks get quarantined, defused with retries or thrown away, and a sorted brick sent back waits in a lane before it runs again. It runs the real library in your browser.

You declare a DAG of nodes. Each subject (a job, a request, an offer…) goes through the nodes; a node journal records, per subject and per node, whether the node is running, done, skipped, failed or omitted. Workers claim a node for eligible subjects, conclude it, and the graph decides what becomes claimable next — forks run in parallel, joins wait for their parents.

from quazardous.grampy import Node, NodeJournal, check_dag
from quazardous.grampy.drivers.memory import MemoryDriver
from quazardous.grampy.items import Adapter, Items

DAG = (
    Node("fetch", working="fetching", state="fetched"),
    Node("crop", parents=("fetch",), optional=True),
    Node("read", parents=("fetch",), optional=True),
    Node("judge", parents=("crop", "read"), state="judged"),
)
check_dag(DAG)

class DocsAdapter(Adapter):                       # how grampy reads YOUR object
    def id_of(self, doc):  return doc.id
    def inflate(self, ids):   return [LIBRARY[i] for i in ids]
    def applies(self, doc, node):          # one graph, subjects that differ
        return node != "crop" or doc.scanned

items = Items(NodeJournal(MemoryDriver(), DAG), DocsAdapter())
lease = items.claim("fetch", 10, candidates=my_loader())    # objects in…
for doc in lease:                                           # …and objects out
    ...
items.conclude("fetch", lease)

Handing grampy your objects is the canonical way to use it — see items. The core underneath works on ids alone and stays available: journal.claim("fetch", 10, candidates=[…]) returns subjects, and never reads your data.

The package lives in the quazardous namespace; the distribution is grampy-q (grampy was already taken on PyPI; the q is for queue).

What it does

Each line links to the rules, where it is spelled out.

joins as data which parent statuses a node accepts, k of n, a step that runs on a failure
exclusive choices a node names its branch; what only the others lead to is omitted at once
loops and history bounded ways back, every row taken away kept with when and why
retries declared backoff — constant, linear or exponential, capped, with jitter
leases per node, given back by journal.expire() when a worker dies
waits and grace settled by a durable signal, recorded even before the wait, or failed at its timeout
groups subjects worked together — five of a colour, ten thousand for one file — a whole group or none
lanes a subject that comes back waits, merges with the version waiting, runs again after a cooldown
policies one workflow, subjects treated differently: their own retries, leases and budgets
rate and concurrency several bands at once (GCRA, with bursts), a cap per node, per policy
versions subjects pinned to the graph they started on, migrated all or nothing
items speak your objects: handlers name a branch, or give up a step one kind skips
drawings Mermaid flowchart, Mermaid state diagram, Graphviz, with live counts

Storage

The journal never commits and never reads your tables. Eligibility is your query, passed to claim and read inside its transaction; a claim gives back ids, and you load your own objects. See drivers.

driver needs
drivers.memory nothing — the reference the others are confronted with
drivers.sqlite the standard library
drivers.postgres SQLAlchemy Core

Any other storage: implement the driver protocol and pass the shared contract (quazardous.grampy.testing.JournalContract), concurrency tests included.

Documentation

Tests

pip install -e ".[test]"        # or: uvx --with pytest pytest
pytest                          # graph, states, memory and SQLite drivers
GRAMPY_TEST_PG_DSN=postgresql+psycopg://user:pass@localhost/test \
    pytest                      # + the postgres driver (needs sqlalchemy and a driver)

License

MIT

Release files for grampy-q 0.3.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for grampy-q 0.3.0
File Size Uploaded
grampy_q-0.3.0.tar.gz 109.3 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for grampy-q 0.3.0
File Interpreter ABI Platform
grampy_q-0.3.0-py3-none-any.whl Python 3 none any Details

Total release size: 206.1 kB

Release files / grampy_q-0.3.0.tar.gz

Download URL grampy_q-0.3.0.tar.gz
Size 109.3 kB
Tags Source
SHA-256 checksum
How to use checksums
6c6bd48eb07bc930bb7d774e735148d101db8929d9bc1df2d4c584d1b1dc53fb
BLAKE2b-256 checksum
How to use checksums
485fca7c381d3a5f69327edcd29748c6e8b8fceace850c3fdbaef518b69a828d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 18, 2026.

Transparency log

Release files / grampy_q-0.3.0-py3-none-any.whl

Download URL grampy_q-0.3.0-py3-none-any.whl
Size 96.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
e793d39762b383850b7bcf7d837287bf1c2b97901e1ebbdb5b9978c21d34eb40
BLAKE2b-256 checksum
How to use checksums
b587593e80ccc02a1cc5fda87785af7c0864daf21bd16bec71dfe007726ebfaf
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 18, 2026.

Transparency log

Release history Release notifications | RSS feed

0.6.0

2 release files

0.5.1

2 release files

0.5.0

2 release files

0.4.0

2 release files

This release

0.3.0 This release

2 release files

0.2.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page