Skip to content

Publication API

frames2py.publish holds the snapshot type consumers receive and the publisher seam the Engine uses. Consumers only need Snapshot; see Snapshots and consumers.

frames2py.publish.Snapshot dataclass

One publication: a frame and its metadata, shared by every consumer that reads it.

frame is the published array itself, not a copy, and is marked read-only. Frames2Py never writes a published frame again. The read-only flag is NumPy's: it stops accidental writes through frame, not code that sets it back on the owning array, and libraries that ignore it (torch.from_numpy, for one) share the memory writably. A consumer that needs to modify the data, or hands it to such a library, uses copy().

Attributes:

Name Type Description
frame NDArray[Any]

The published frame, read-only, (height, width[, channels]).

meta SnapshotMeta

The publication's metadata.

copy

copy(out: NDArray[Any] | None = None) -> NDArray[Any]

A writable copy of frame: a new array, or out filled and returned.

out must be a writable, C-contiguous ndarray with exactly frame's shape and dtype. Otherwise this raises before writing anything: TypeError for a non-array or a different dtype, ValueError for a different shape, a non-C-contiguous array or a read-only one.

frames2py.publish.SnapshotPublisher

Bases: Protocol

Carries published frames from one writer to any number of readers.

The writer calls begin_write(), fills the returned buffer, then calls end_write(meta). Readers call read(), which returns the latest complete publication, shared rather than copied, or None.

begin_write

begin_write() -> NDArray[Any]

Start a publication; return the buffer to fill.

end_write

end_write(meta: SnapshotMeta) -> None

Complete the publication started by begin_write().

read

read() -> Snapshot | None

The latest complete publication, or None.

reset

reset() -> None

Forget the published snapshot; read() returns None until the next.

frames2py.publish.ImmutablePublisher

Publishes each snapshot as a new buffer that is never written again, in pure Python.

begin_write() allocates a fresh buffer for the writer to fill. end_write(meta) marks it read-only and stores it, with its metadata, as one Snapshot in a one-element list. read() loads that item and returns it: it never copies, never retries and never sees a buffer being written, and the frame and metadata it returns always belong together. One writer only.

The handoff between threads is the list item's store and load. CPython documents single list-item reads and writes as atomic. That a reader which loads the new item also sees the frame written before it is CPython implementation behaviour: on free-threaded 3.14 the store is a release store and the load a sequentially consistent one; with the GIL, the GIL orders them. It is not a Python language guarantee, and CPython itself locks the list during the store.

Parameters:

Name Type Description Default
shape tuple[int, ...]

Frame shape.

required
dtype dtype[Any]

Frame dtype.

required