PyZMQ: Python bindings for ZeroMQ
PyZMQ is the Python binding for ØMQ (ZeroMQ), a high-performance asynchronous messaging library. It enables scalable, distributed messaging without a dedicated message broker, supporting fundamental communication patterns like request-reply, publish-subscribe, and pipeline. The library is actively maintained with frequent releases; the current stable version is 27.1.0, and it supports Python 3.8+.
Warnings
- breaking In `pyzmq` 27.1.0, the behavior of `zmq.DRAFT_API` was restored to its pre-pyzmq 23 state. It now reflects if *both* `libzmq` and `pyzmq` were built with draft APIs, not just `zmq.has("draft")`.
- gotcha Blocking operations like `socket.send()` and `socket.recv()` can cause your program to hang indefinitely if a message is not available or cannot be sent immediately.
- gotcha Improper termination of ZeroMQ contexts and sockets can lead to resource leaks, preventing programs from exiting cleanly or appearing 'stuck'.
- gotcha ZeroMQ sockets are NOT thread-safe. While a `zmq.Context` can be shared across threads, individual `zmq.Socket` instances should not be shared or accessed concurrently from multiple threads without external synchronization, which is generally discouraged.
- deprecated The `zmq.utils.jsonapi` module is being deprecated, and `send_json`/`recv_json` methods will eventually only support the standard library's `json` module. This change is already present in development versions (e.g., 27.2.0.dev).
- breaking On Windows, `pyzmq` wheels no longer bundle `libzmq` with `AF_UNIX` (IPC) support enabled due to upstream `libzmq` bugs causing crashes. This was re-disabled in `pyzmq` 26.2 after an unintentional re-introduction in 26.0.
Install
-
pip install pyzmq -
pip install 'pyzmq==27.1.0'
Imports
- zmq
import zmq
Quickstart
import zmq
import time
import threading
def run_server():
context = zmq.Context()
socket = context.socket(zmq.REP) # Reply socket
socket.bind("tcp://*:5555")
print("Server: Binding to port 5555...")
try:
while True:
message = socket.recv_string()
print(f"Server: Received request: {message}")
time.sleep(1) # Simulate some work
socket.send_string("World")
except KeyboardInterrupt:
print("\nServer: Shutting down.")
finally:
socket.close()
context.term()
def run_client():
context = zmq.Context()
socket = context.socket(zmq.REQ) # Request socket
socket.connect("tcp://localhost:5555")
print("Client: Connecting to server...")
try:
for request_num in range(3):
print(f"Client: Sending Hello {request_num}...")
socket.send_string(f"Hello {request_num}")
message = socket.recv_string()
print(f"Client: Received reply: {message}")
time.sleep(0.5)
except KeyboardInterrupt:
print("\nClient: Shutting down.")
finally:
socket.close()
context.term()
if __name__ == "__main__":
# Run server in a separate thread for demonstration
server_thread = threading.Thread(target=run_server)
server_thread.start()
time.sleep(0.5) # Give server a moment to bind
run_client()
server_thread.join()