Metadata-Version: 2.4
Name: quillmq
Version: 0.1.0
Summary: QuillMQ: a lightweight single-node message broker (work queues, pub/sub, RPC, durable delivery).
Project-URL: Homepage, https://github.com/bha6kar/quillmq
Project-URL: Repository, https://github.com/bha6kar/quillmq
Project-URL: Issues, https://github.com/bha6kar/quillmq/issues
Author-email: bha6kar <bha6kar@gmail.com>
License: Apache-2.0
License-File: LICENSE
Keywords: asyncio,broker,message-broker,message-queue,pubsub,queue,rpc
Classifier: Development Status :: 4 - Beta
Classifier: Framework :: AsyncIO
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.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: System :: Networking
Requires-Python: >=3.11
Requires-Dist: aiosqlite>=0.19
Requires-Dist: msgspec>=0.18
Provides-Extra: dev
Requires-Dist: mypy>=1.11; extra == 'dev'
Requires-Dist: pre-commit>=3.8; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
Requires-Dist: pytest-cov>=5; extra == 'dev'
Requires-Dist: pytest-timeout>=2.3; extra == 'dev'
Requires-Dist: pytest>=8; extra == 'dev'
Requires-Dist: ruff>=0.6; extra == 'dev'
Requires-Dist: trustme>=1.1; extra == 'dev'
Description-Content-Type: text/markdown

# QuillMQ

[![CI](https://github.com/bha6kar/quillmq/actions/workflows/ci.yml/badge.svg)](https://github.com/bha6kar/quillmq/actions/workflows/ci.yml)
[![PyPI version](https://img.shields.io/pypi/v/quillmq.svg)](https://pypi.org/project/quillmq/)
[![Python versions](https://img.shields.io/badge/python-3.11%20%7C%203.12%20%7C%203.13-blue.svg)](https://pypi.org/project/quillmq/)
[![Licence](https://img.shields.io/badge/licence-Apache--2.0-blue.svg)](LICENSE)

A lightweight, single-node message broker written from scratch in Python asyncio.
It provides work queues, pub/sub fan-out, RPC request/reply, and at-least-once
durable delivery over a small custom TCP protocol. No RabbitMQ or AMQP dependency.

QuillMQ is to RabbitMQ what SQLite is to PostgreSQL: not a replacement for a
clustered production broker, but the better fit when you want embeddable,
single-node, zero-ops messaging you can read and own. See
[COMPARISON.md](COMPARISON.md) for an honest side-by-side.

## Install

    uv sync --extra dev

## Run the broker

    uv run quillmq serve --port 5555 --data ./quill.db

Omit `--data` for an in-memory broker.

## Python client

```python
from quillmq import connect

conn = await connect("quill://127.0.0.1:5555")
ch = await conn.channel()
await ch.declare_queue("tasks", durable=True)
await ch.publish("", "tasks", {"job": 1})
async for msg in ch.consume("tasks", prefetch=10):
    handle(msg.body)
    await msg.ack()
```

## Patterns

- Work queue: many consumers on one queue compete; each message is delivered once.
- Pub/sub: bind several queues to a `fanout` or `topic` exchange.
- RPC: `await ch.rpc_call("service.rpc", {...})`, served by `quillmq.rpc.RPCServer`.

## CLI

    quillmq serve --port 5555 --data ./quill.db
    quillmq publish "" tasks '{"job": 1}'
    quillmq stats
    quillmq tail tasks

## Running in production (single node)

QuillMQ is single-node by design (no clustering), but a single instance is built
to run as a real service:

    quillmq serve \
      --port 5555 \
      --data ./quill.db \
      --auth-token "$QUILLMQ_AUTH_TOKEN" \
      --tls-cert cert.pem --tls-key key.pem \
      --heartbeat 60 \
      --max-delivery-count 10 --dead-letter-queue dead \
      --metrics-port 9095 \
      --json-logs

- Structured logging (text or JSON), and graceful shutdown on SIGTERM/SIGINT.
- Idle connections are reaped after `--heartbeat` seconds; clients send
  keepalives automatically.
- Poison messages are dead-lettered after `--max-delivery-count` attempts; set
  a per-message TTL with a `ttl` header (seconds).
- TLS: pass `--tls-cert`/`--tls-key` and connect with a `quills://` URL.
- Prometheus metrics are served at `http://host:9095/metrics`.
- Every flag has a `QUILLMQ_*` environment variable equivalent.

## Docker

    docker compose up --build

This starts a durable broker on port 5555 with a named volume for persistence.
To build the image directly:

    docker build -t quillmq:latest .

Behind a TLS-intercepting corporate proxy, pass your CA or, as a last resort:

    docker build -t quillmq:latest \
      --build-arg UV_SYNC_FLAGS="--allow-insecure-host pypi.org --allow-insecure-host files.pythonhosted.org" .

## Licence

Apache-2.0.
