pactix
pactix is a Python library for transactional outbox and inbox workflows on PostgreSQL and MySQL 8, built on SQLAlchemy (async).
Use it when a service needs to commit business data and outgoing events in the same transaction, store incoming messages before handler execution, and retry failed work safely across multiple workers.
Features
- PostgreSQL and MySQL 8 persistence, auto-detected per call from the SQLAlchemy engine/connection — no config knob
- Deduplication by
source + message_idon the inbox side - FIFO within the same
event_type + ordering_key - Optional unordered inbox processing with a stale-event filter contract
- Retry scheduling and lease-based recovery for stuck workers
- Optional wakeup-driven outbox scheduling — post-commit signal and PostgreSQL LISTEN/NOTIFY with adaptive fallback polling (see Operations)
- Transport-agnostic core protocols
- Built-in helpers for common hooks, stale-event filters, and closure-based adapters
- Optional Kafka adapters behind the
kafkaextra - Optional HTTP adapters behind the
httpextra
If a publisher or handler may run more than once, that is normal. Business effects still need idempotent application logic.
Installation
pip install "pactix[postgres]" # core + asyncpg driver (PostgreSQL)
pip install "pactix[mysql]" # core + asyncmy driver (MySQL 8)
pip install "pactix[kafka]" # + Kafka transport (aiokafka)
pip install "pactix[http]" # + HTTP transport (httpx + starlette)
pip install "pactix[migrations]" # + Alembic for running the migrations
The core package ships no database driver — install one of the driver extras
above (extras combine, e.g. pactix[postgres,kafka]).
Breaking change: asyncpg moved out of the core dependencies into the
postgres extra. Existing PostgreSQL services must change their requirement
from pactix to pactix[postgres] when upgrading — nothing else changes. The
failure mode without it is loud: SQLAlchemy raises at engine creation naming
the missing DBAPI.
MySQL 8 note: stock MySQL 8 authenticates with caching_sha2_password. Over a
non-TLS connection asyncmy's RSA password exchange additionally needs the
cryptography package, which the mysql extra already pulls in (TLS
connections do not need it).
Database setup
pactix does not run migrations for you. Either run the bundled Alembic migrations
(src/pactix/db/migrations, see alembic.ini) or copy the table
definitions in pactix.db.tables into your own migration
system. The library expects two tables: outbox_message and inbox_message.
The same migrations run on both dialects (the wakeup-trigger revision no-ops on
MySQL); for MySQL run alembic upgrade with a sync mysql+pymysql:// URL. See
Operations for the MySQL notes.
Documentation
- Core workflows — append, publish, save, and process flows
- Helper adapters — closures,
ProcessAll,StaticIdempotency, filters - Kafka transport
- HTTP transport
- Operations, migrations, and workers
See examples/worker_loop.py for a runnable worker-loop sketch.
Development
make install # uv sync with all extras
make check # format + lint + mypy + test
Database-backed tests use testcontainers and require Docker.
Metadata
Release files for pactix 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| pactix-0.2.0.tar.gz | 600.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| pactix-0.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 643.6 kB
Release files / pactix-0.2.0.tar.gz
| Download URL | pactix-0.2.0.tar.gz |
|---|---|
| Size | 600.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
c04445c14b77ed492aa9336a4a405f4b3d6307c7d75ab0dd341442529b8d2223
|
|
BLAKE2b-256 checksum How to use checksums |
757003142371071f0f78a05ae48357835ce90670b43bd17dc89a446ad098c6bc
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.13
|
Release files / pactix-0.2.0-py3-none-any.whl
| Download URL | pactix-0.2.0-py3-none-any.whl |
|---|---|
| Size | 42.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
e1cc2f200f24de5a14bb602946648818fca0ec30a73369083ec99b82fc75cc25
|
|
BLAKE2b-256 checksum How to use checksums |
e3171bf13952c2e34a5e52901da9926e28caacd94c5d985b49bd191a40b18e34
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.13
|