--- title: Python bindings sidebar_position: 3 --- # Python bindings **Status: planned for v0.5+. Not shipped yet.** This page is a placeholder so the integration story is honest about what exists and what does not. If you need Python access to cuframes today, read [Workaround for v0.4](#workaround-for-v04) below. ## What v0.5+ will ship A small `cuframes` Python package, distributed as a wheel, providing: - **`ctypes`-based bindings** around the existing C API (`cuframes_publisher_create`, `cuframes_subscriber_create`, `cuframes_acquire`, `cuframes_release`, etc.). No new ABI, no SWIG, no C++ wrapper. - **Zero-copy NumPy / PyTorch access** to the decoded NV12 surface via the [CUDA Array Interface](https://numba.readthedocs.io/en/stable/cuda/cuda_array_interface.html). A subscribed frame is exposed as a CuPy / PyTorch tensor that points at the same GPU memory the publisher wrote — no `cudaMemcpy` to host, no copy on the device either. - **Context-manager API** for acquire / release so frame slots cannot leak across exceptions. Target use cases: - **PyTorch inference on shared frames** — a detector / classifier subscribes to `cuframes://camN`, gets a tensor, runs `model(tensor)` directly. Today this requires either re-decoding the RTSP stream or copying frames over a Unix pipe. - **OpenCV CUDA processing** — `cv2.cuda_GpuMat` constructed from the cuframes pointer, then any cv2.cuda op (resize, color convert, optical flow) runs in place. - **Quick prototyping** — a Jupyter notebook that subscribes to a live camera, slices out a region of interest, and visualises it without spinning up a full FFmpeg pipeline. There is no plan to add CPU-side NumPy fallback. Frames are GPU surfaces; if you want them on the CPU you do an explicit `tensor.cpu()` and accept the copy. ## Workaround for v0.4 Until the bindings ship, the supported path is to call `libcuframes.so` directly from Python using `ctypes` or `cffi`. The C API is small (≈ 10 functions) and stable within a v0.x release. Realistically though, most v0.4 deployments do **not** call cuframes from Python at all. They use the existing C/FFmpeg path: - For inference: subscribe to the **packet** ring with `ffmpeg -f cuframes_packets -i cuframes_packets://camN` and pipe decoded frames into your Python process. You lose zero-copy but gain a working pipeline today. - For prototyping: use the C examples in [`examples/`](https://git.goldix.org/gx/cuframes) as your starting point. If you need a Python-side zero-copy path *right now*, you are going to write the `ctypes` wrappers yourself. Mirror the prototypes from [`include/cuframes/cuframes.h`](/docs/reference/protocol), keep handles opaque (`void *`), and use `cuMemAlloc` / CuPy `UnownedMemory` to view the imported VMM allocation. Expect rough edges — the v0.5 bindings exist precisely because this is not fun to do by hand. ## Track progress Roadmap and milestone notes for the Python package live in [`ROADMAP.md`](https://git.goldix.org/gx/cuframes) in the cuframes repo. v0.5 also gates on the HEVC packet-ring path and a small ABI cleanup, so the bindings are not the only thing on that release. ## See also - [Install](/docs/getting-started/install) — get `libcuframes.so` onto your system so the bindings will have something to load. - [Protocol reference](/docs/reference/protocol) — the C API surface the bindings will mirror. - [FFmpeg `cuframes://` demuxer](/docs/integration/ffmpeg-demuxer) — today's practical path for getting cuframes data into any non-C consumer.