Metadata-Version: 2.4
Name: demystify-events
Version: 0.2.0
Summary: Durable jobs/events for Demystify: asyncio mirror of @demystify/events (enqueue, transactional outbox, idempotent workers, backoff+jitter, DLQ).
Project-URL: Homepage, https://github.com/demystify-systems/ai-services-tools/tree/main/modules/dmstfy-events/packages/events-py
Project-URL: Repository, https://github.com/demystify-systems/ai-services-tools
Author: Demystify Systems
License: MIT
Requires-Python: >=3.11
Provides-Extra: dev
Requires-Dist: demystify-platform-contracts; extra == 'dev'
Requires-Dist: httpx<1,>=0.27; extra == 'dev'
Requires-Dist: mutmut<4,>=3; extra == 'dev'
Requires-Dist: mypy<2,>=1.13; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.24; extra == 'dev'
Requires-Dist: pytest<9,>=8; extra == 'dev'
Requires-Dist: ruff<0.9,>=0.8; extra == 'dev'
Provides-Extra: pg
Requires-Dist: psycopg-pool<4,>=3.2; extra == 'pg'
Requires-Dist: psycopg[binary]<4,>=3.1; extra == 'pg'
Description-Content-Type: text/markdown

# demystify-events

Durable jobs and events for Python — the asyncio mirror of the TypeScript
**[@demystify/events](https://github.com/demystify-systems/ai-services-tools/tree/main/modules/dmstfy-events)**
runtime. Postgres-backed (pgmq) with a **transactional outbox**, **idempotent
consumers**, exponential backoff **+ full jitter** retries, and a **dead-letter
queue** — with a full-fidelity **in-memory driver** so the same code runs
offline with no database.

Part of the [Demystify Core Services](https://github.com/demystify-systems/ai-services-tools)
suite.

## Install

```bash
pip install demystify-events
# real Postgres driver (psycopg + connection pool):
pip install "demystify-events[pg]"
```

## Quickstart (offline, no database)

```python
from demystify_events import create_events_client
from demystify_events.adapters.memory import MemoryQueueDriver

client = create_events_client(driver=MemoryQueueDriver())

# enqueue a job
await client.enqueue("email.send", {"to": "user@example.com"})

# process it (idempotent, retried with backoff+jitter, DLQ on poison)
async def handler(ctx, job):
    ...  # do work; effects committed in the same transaction as the ack
await client.work("email.send", handler)
```

Switch to real Postgres by passing the `psycopg` driver (from the `[pg]` extra)
with a `database_url` — the handler contract is identical.

## What's in the box

- `create_events_client` / `EventsClient` — enqueue, transactional `enqueue_in_tx`, workers
- `contract_backoff`, `full_jitter_backoff`, `BackoffConfig` — retry schedules
- `ContractRegistry` — JSON-schema event-type validation
- `make_envelope` / `validate_envelope` — canonical event envelopes
- Adapters: `MemoryQueueDriver` (offline) and `psycopg` (Postgres/pgmq)

The published wheel is self-contained — it does **not** vendor
`demystify-platform-contracts`; contract convergence is asserted by the test
suite. See the [module README](https://github.com/demystify-systems/ai-services-tools/tree/main/modules/dmstfy-events)
for the delivery guarantees, chaos-test results, and the `/ops/v1` API.

## License

MIT © Demystify Systems
