Python (py.nozzle)
py.nozzle provides Python bindings for nozzle via nanobind. NumPy arrays are zero-copy via DLPack.
Install
pip install nozzle
From Source
git clone --recurse-submodules https://github.com/nozzle-io/py.nozzle.git
cd py.nozzle
pip install .
Requirements
- Python 3.9+
- CMake 3.20+
- C++17 compiler
- macOS 12+ / Windows 10+ / Linux (glibc 2.31+)
Sender
import nozzle
import numpy as np
sender = nozzle.Sender.create("my_output", "MyApp")
img = np.zeros((480, 640, 4), dtype=np.uint8)
img[100, 100] = [255, 128, 64, 255]
sender.publish_array(img)
Receiver
import nozzle
receiver = nozzle.Receiver.create("my_output", "MyViewer")
frame = receiver.acquire_frame(timeout_ms=1000)
if frame.valid():
info = frame.info()
print(f"{info.width}x{info.height}, format={info.format}")
arr = frame.get_array()
print(arr.shape, arr.dtype)
Discovery
senders = nozzle.enumerate_senders()
for s in senders:
print(f"{s.name} ({s.application_name}) — {s.backend}")
names = nozzle.list_senders()
DLPack Support
Frames implement __dlpack__ and __dlpack_device__ for zero-copy interop with PyTorch, JAX, and other DLPack-compatible frameworks:
import torch
frame = receiver.acquire_frame(timeout_ms=1000)
if frame.valid():
tensor = torch.from_dlpack(frame)
Pixel Format Mapping
NumPy dtypes map automatically to nozzle formats:
| NumPy dtype | Channels | Nozzle Format |
|---|---|---|
uint8 |
1 | R8 UNORM |
uint8 |
2 | RG8 UNORM |
uint8 |
4 | RGBA8 UNORM |
float32 |
1 | R32 Float |
float32 |
4 | RGBA32 Float |
float16 |
4 | RGBA16 Float |
API Reference
Sender
| Method | Description |
|---|---|
Sender.create(name, application_name, ring_buffer_size=3) |
Create a sender |
sender.publish_array(array) |
Publish a NumPy array as a frame |
sender.info() |
Get sender metadata |
sender.valid() |
Check if sender is initialized |
Receiver
| Method | Description |
|---|---|
Receiver.create(name, application_name) |
Create a receiver |
receiver.acquire_frame(timeout_ms=0) |
Acquire latest frame |
receiver.valid() |
Check if receiver is initialized |
Frame
| Method | Description |
|---|---|
frame.info() |
Get frame metadata (width, height, format, frame_index) |
frame.get_array() |
Copy frame data to NumPy array |
frame.lock_pixels() |
Zero-copy pixel access via LockedPixels |
frame.valid() |
Check if frame holds valid data |
frame.release() |
Explicitly release frame |
frame.__dlpack__() |
DLPack export |
Architecture
The Python extension wraps the nozzle C ABI via nanobind. No C++ API usage:
py.nozzle
├── src/nozzle.cpp nanobind C++ extension
├── src/nozzle/ Python package (__init__.py)
├── libs/nozzle/ git submodule
└── tests/ pytest suite