Skip to main content

Python binding for omq.rs (Rust libzmq port). Drop-in pyzmq replacement on the common path.

Project description

pyomq

Python binding for omq.rs, a Rust libzmq port. Drop-in pyzmq replacement on the common path.

Install

uv pip install pyomq
uv pip install 'pyomq[test]'   # adds pytest, pyzmq for the interop suite

The published wheel includes all optional features (curve, blake3zmq, lz4, zstd). Use pyomq.has("curve") at runtime to check availability.

Usage

import pyomq as zmq  # drop-in for `import zmq` from pyzmq

ctx = zmq.Context()
push = ctx.socket(zmq.PUSH)
push.connect("tcp://127.0.0.1:5555")
push.send(b"hello")
push.close()
ctx.term()

For asynchronous code:

import pyomq
import pyomq.asyncio as zmq_async

ctx = zmq_async.Context()
sock = ctx.socket(pyomq.PUSH)
await sock.connect("tcp://127.0.0.1:5555")
await sock.send(b"hello")
await sock.close()

Status

Sync and asyncio APIs both ship in this release. All 19 ZMTP socket types are wired:

  • Standard (RFC 28 + 47): PAIR, PUB, SUB, REQ, REP, DEALER, ROUTER, PULL, PUSH, XPUB, XSUB.
  • Draft: SERVER, CLIENT (RFC 41), RADIO, DISH (RFC 48), GATHER, SCATTER (RFC 49), PEER, CHANNEL (RFC 51).

Transports: tcp://, ipc://, inproc://, and udp:// (RADIO/DISH only). Optional features built into the wheel: curve, blake3zmq, lz4, zstd.

DISH groups: use socket.join(b"group") / socket.leave(b"group") to manage subscriptions; messages are sent as multipart [group, body].

Backend

pyomq is built on omq-compio (single-threaded io_uring on Linux). The runtime runs on a dedicated background thread; every Python call releases the GIL across the runtime trip. This is the only backend pyomq supports — the omq-tokio backend exists in the upstream Rust workspace for callers that need a multi-thread tokio integration, but pyomq's per-call overhead is shaped around compio's single-thread invariant.

Performance

See BENCHMARKS.md for full tables.

PUSH/PULL throughput: Python bindings

Loopback PUSH/PULL throughput vs pyzmq, on a Linux 6.12 (Debian 13) VM on an Intel Mac Mini 2018 (i7-8700B, 3.2 GHz), Rust 1.95.0, default features:

Size inproc pyomq inproc pyzmq ratio tcp pyomq tcp pyzmq ratio
8 B 1.30 M/s 627 k/s 2.08× 1.36 M/s 565 k/s 2.41×
32 B 1.29 M/s 620 k/s 2.08× 1.36 M/s 576 k/s 2.37×
128 B 1.31 M/s 516 k/s 2.54× 1.29 M/s 496 k/s 2.61×
512 B 1.29 M/s 480 k/s 2.69× 1.21 M/s 461 k/s 2.62×
2 KiB 1.17 M/s 461 k/s 2.54× 908 k/s 342 k/s 2.65×
8 KiB 1.04 M/s 368 k/s 2.83× 349 k/s 102 k/s 3.41×
32 KiB 622 k/s 196 k/s 3.17× 116 k/s 46 k/s 2.50×
128 KiB 203 k/s 70 k/s 2.91× 32 k/s 24 k/s 1.32×

zmq.proxy() forwarding (128 B, TCP)

pyomq pyzmq ratio
PUSH/PULL msg/s 963 k/s 520 k/s 1.85×
REQ/REP rt/s 8,764/s 6,521/s 1.34×

pyomq's proxy() runs as a native Rust async loop on the compio thread — no Python per-message overhead. pyzmq's zmq.proxy() calls libzmq's C-level zmq_proxy. PUSH/PULL forwarding is throughput-bound and pyomq is ~1.9× faster. REQ/REP is latency-bound (4 TCP hops per round-trip) so both are similar.

Run scripts/update_perf.py (after maturin develop --release) to re-measure and update the tables above.

Compression transports

OMQ.rs adds two transparent compression transports on top of TCP: lz4+tcp:// (fast, low-latency) and zstd+tcp:// (higher ratio, better for large or structured payloads). Swap the scheme in your endpoint string and everything else stays the same:

push = ctx.socket(zmq.PUSH)
push.bind("lz4+tcp://127.0.0.1:5555")   # or zstd+tcp://

pull = ctx.socket(zmq.PULL)
pull.connect("lz4+tcp://127.0.0.1:5555")

Both peers must use a matching compression endpoint. Payloads below ~512 B are sent as-is (the codec detects that compression would expand them). For realistic JSON payloads at 2 KiB, lz4 yields ~3.8× and zstd ~4.5× on a bandwidth-limited link.

zstd+tcp:// also auto-trains a dictionary: it samples the first 1000 outbound messages (or 100 KiB of plaintext, whichever comes first), builds an 8 KiB dict, and ships it to the peer once. After that the compression threshold drops from 512 B to 64 B, so small structured messages start compressing too. lz4+tcp:// does not auto-train (LZ4 has no standard dict trainer).

Virtual throughput on bandwidth-limited links (JSON payloads, compio backend):

Compression throughput at 1 Gbps

Compression throughput at 100 Mbps

See BENCHMARKS_COMPRESSION.md for full tables including dict-trained ratios.

Develop

cd bindings/pyomq
uv venv && source .venv/bin/activate
uv pip install maturin pytest pyzmq
maturin develop --release
pytest -v

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pyomq-0.6.1.tar.gz (336.5 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

pyomq-0.6.1-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (1.2 MB view details)

Uploaded CPython 3.9+manylinux: glibc 2.17+ x86-64

pyomq-0.6.1-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl (1.1 MB view details)

Uploaded CPython 3.9+manylinux: glibc 2.17+ ARM64

File details

Details for the file pyomq-0.6.1.tar.gz.

File metadata

  • Download URL: pyomq-0.6.1.tar.gz
  • Upload date:
  • Size: 336.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for pyomq-0.6.1.tar.gz
Algorithm Hash digest
SHA256 f21bc6d9e8ac5a161c448f11e4feaee360b0fe1eedf7906269f45025d90f17ef
MD5 67b197f9a0e3d13807101db5b187f679
BLAKE2b-256 68c556d0e0f0c16e64f262b093ef2e1b21e8fe9edaace5163b81f3556aa21cfa

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyomq-0.6.1.tar.gz:

Publisher: release-pyomq.yml on paddor/omq.rs

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pyomq-0.6.1-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for pyomq-0.6.1-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 deb7b99369a5a1c09916b9573ea6ff541bf90f6732ff5e79d2af7089a6999107
MD5 d6d323a0f97dfa2d57d8fbe9c4f80da2
BLAKE2b-256 b88e24b8d7e7a776ef583071688a30678c9d009a00c550a355bf435dadfb2c70

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyomq-0.6.1-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: release-pyomq.yml on paddor/omq.rs

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pyomq-0.6.1-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.

File metadata

File hashes

Hashes for pyomq-0.6.1-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Algorithm Hash digest
SHA256 670bde82c7a92e9d5aa3dbe48daf40ca3f4bbaa5a535cf8e842aed5864c2e3db
MD5 736ead5626e7b71366a5eec9ce22fefe
BLAKE2b-256 b6dfae94668ff498f7129e9e045646aa0d0ef20be8fe13120dedcb3ec80edbe0

See more details on using hashes here.

Provenance

The following attestation bundles were made for pyomq-0.6.1-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:

Publisher: release-pyomq.yml on paddor/omq.rs

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page