Skip to main content

pixelflux

License: MPL 2.0 Docs Ask DeepWiki

A performant pixel delivery pipeline for diverse sources, blending flexible and high-performance modern encoding formats.

This module provides a Python interface to a high-performance capture library supporting both X11 and Wayland environments. It captures pixel data, detects changes, and encodes modified stripes into JPEG or H.264.

It encodes JPEG, H.264, H.265, VP8, VP9, and AV1. Every video codec runs on NVIDIA's NVENC (H.264, H.265, AV1) or on VA-API for Intel/AMD GPUs (all five) where the GPU carries it, H.264, H.265 and AV1 additionally on a Jetson's Tegra encoder through the vendor V4L2 interface, and otherwise on the software encoder the build resolves for it: x264 or, in a GPL-free build, the BSD-licensed OpenH264 for H.264; x265 or kvazaar for H.265; libvpx for VP8 and VP9; SVT-AV1 for AV1. JPEG and H.264 can be cut into stripes encoded in parallel; the other codecs stream whole frames. About "zero copy": the Wayland GPU path is truly zero-copy (dmabuf frames flow GBM → encoder without touching system RAM), and so is the X11 path on an NVIDIA GPU whose session encodes on NVENC: NvFBC has the driver composite the X screen straight into video memory and that buffer is registered with the encoder in place, so a frame is never read, written, or copied by the CPU. Every other X11 session copies exactly once: the X server renders each frame into a shared-memory surface (XShmGetImage); the encoder threads then read that mapped surface in place and pass the encoded bytes to Python through the buffer protocol without any further copies.

Installation

pixelflux is a single self-contained Rust extension compiled during installation. Both the X11 and Wayland backends, all encoders, and the Python API live in it. (libjpeg-turbo — and, in a GPL-free build, openh264 — C sources are vendored and built by their Rust -sys crates, so cmake and nasm are required, but no system copies of those libraries are used.)

1. Prerequisites

Ensure you have the Rust toolchain (cargo), Python development files, and the development libraries below.

# Install Rust
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

# Build dependencies (Debian/Ubuntu)
sudo apt-get update && \
sudo apt-get install -y \
  git \
  curl \
  python3-dev \
  cmake \
  nasm \
  libclang-dev \
  libavcodec-dev \
  libavfilter-dev \
  libavutil-dev \
  libx264-dev \
  libgbm-dev \
  libdrm-dev \
  libwayland-dev \
  libinput-dev \
  libudev-dev \
  libxkbcommon-dev \
  libpixman-1-dev \
  libva-dev

Notes: the FFmpeg bindings (ffmpeg-sys-next 9.0) work with any system FFmpeg 6.0–9.0 (only avcodec/avfilter are used: the VA-API encoders, and the software HEVC/VP8/VP9/AV1 encoders that FFmpeg build carries — libx265 or libkvazaar, libvpx, libsvtav1; each is opened once in a forked child, and a codec whose encoder the build lacks or cannot run on the machine has no software path, which pixelflux.SOFTWARE_ENCODERS reports; pixelflux.hardware_encoders(encode_node_index, auto_gpu) reports the hardware half, the codecs the NVENC or VA-API of the node those two capture settings resolve to has an engine for, probed once per node); on distros shipping an older FFmpeg, install a newer build and point PKG_CONFIG_PATH at it. Software AV1 additionally wants SVT-AV1 2.3.0 or newer, where the encoder's packet call became blocking for low delay: below it a session still encodes, but the encoder holds two frames before its first packet and every frame ships that late. libjpeg-turbo is vendored and built statically by its crate — no libturbojpeg system package is needed (only cmake + nasm). X11 capture uses pure-Rust XCB; colorspace conversion is pure-Rust and the NVENC/CUDA libraries are loaded at runtime (no compile-time NVIDIA packages).

GPL component (libx264): software H.264 uses the system libx264 (GPL-2.0+), which is the only GPL-licensed dependency of pixelflux itself. It is enabled by default; to build without it, set PIXELFLUX_ENABLE_GPL=0 (or =false) before pip install. The build then substitutes the BSD-licensed Cisco OpenH264 (vendored, built from source) as the software H.264 encoder behind the very same API and wire format — striped and full-frame sessions, CRF and CBR, live bitrate/quality changes all keep working, and libx264-dev is not required. What you lose is 4:4:4 software H.264: OpenH264 is 4:2:0-only, so video_fullcolor is encoded 4:2:0 on the CPU (NVENC still carries it). Software H.265 follows the same switch through the linked FFmpeg: x265 (GPL) in the default build, kvazaar (BSD) otherwise. JPEG, NVENC, and VA-API are unaffected. pixelflux.SOFTWARE_ENCODERS maps each codec to the software encoder the build in use carries ({"h264": "x264", "h265": "x265", "vp8": "libvpx", "vp9": "libvpx", "av1": "svt-av1"} for the wheels), and a notice is printed at install time whether GPL components are enabled or not.

Caveat (transitively-linked x264): the extension links the system FFmpeg (libavcodec/libavfilter) for VA-API, and many distro FFmpeg builds (e.g. Ubuntu/Debian's) are themselves compiled with --enable-libx264, so their libavcodec drags libx264 in as a transitive shared-library dependency even when pixelflux was built GPL-free. pixelflux contains no x264 code in that case (verified: no x264 symbols or NEEDED entries), for a deployment that must be x264-free end to end, use an FFmpeg built without --enable-libx264 (the project's non-GPL wheel builds FFmpeg n8.1 LGPL-only with kvazaar, libvpx, SVT-AV1, and dav1d; the GPL wheel's FFmpeg adds x264 and x265 under --enable-gpl).

Official wheels are always GPL-enabled (x264 and x265 as the software H.264 and H.265 encoders, a GPL-built FFmpeg); the PIXELFLUX_ENABLE_GPL=0 path is for verified license-minimal source builds. The AppImage distribution bundles the LGPL-only FFmpeg variant so the optional GPL-free posture holds end-to-end.

  • NVIDIA (NVENC): The library detects the NVIDIA driver at runtime. No extra compile-time packages are needed.
  • Intel/AMD (VA-API): Ensure libva-dev and libdrm-dev are installed. You must also have the correct drivers (e.g., intel-media-va-driver-non-free or mesa-va-drivers).
  • NVIDIA Jetson (Tegra): Nothing to install or build against. The L4T libraries the backend needs ship with JetPack and are loaded at runtime.

3. Install the Package

Option A: Install a prebuilt wheel

Every release on the GitHub Releases page carries wheels (manylinux_2_28 and musllinux, x86_64 and aarch64, CPython 3.9–3.14), the pre-releases cut per commit included; take the one for your interpreter and platform:

pip install ./pixelflux-<version>-cp312-cp312-manylinux_2_28_x86_64.whl

Option B: Install from local source

# From the root of the project repository
pip install .

Usage

Backend Selection

X11 GPU capture (NvFBC and DRI3)

On an NVIDIA GPU whose session encodes on NVENC, X11 capture goes through NvFBC: the NVIDIA X driver composites each frame into a buffer it owns in video memory and hands back a CUDA device pointer, which is registered with the encoder in place. Nothing is copied, the driver generates a frame when an application damages the screen (push model) rather than on a sampling timer, and a fullscreen unoccluded application can present straight into the capture buffer, bypassing the X server. Measured at 1920x1080 on a Tesla V100 against the XShm path on the same display and codec: 2.51 ms per frame instead of 5.24 ms for H.264, and 3.03 ms instead of 5.69 ms for H.265, with the host CPU spending under 0.2 ms a frame because it touches no pixels.

It is chosen automatically and needs no setting. A session it cannot serve says so once and streams through XShm instead: a codec NVENC has no engine for, software encoding, a GPU that is not NVIDIA, a watermark (which is composited into host pixels), or a driver without NvFBC. libnvidia-fbc.so.1 is loaded at run time and ships with the driver; containers get it under the video driver capability. There is nothing to turn on or off: what the driver offers decides.

On any other X server whose screen lives on the GPU (XLibre's Xvfb started with -glamor -dri, an Xorg on a DRM driver), X11 capture goes through DRI3: pixelflux allocates a small pool of dmabufs through GBM on the render node the server draws with, hands each to the server as a pixmap (PixmapFromBuffers), and every frame is one CopyArea of the root into the next one, a GPU blit in glamor. The hardware encoder, NVENC or VA-API, imports the dmabuf in place through the same path the Wayland zero-copy capture uses, so no frame crosses to the CPU. The Damage extension says whether anything was drawn since the last frame and ends the wait for the next one, so a change is published as it lands, and the XFixes cursor is composited by the server through Render. It is declined, with one line saying why, for a codec no hardware engine serves, software encoding, a server without DRI3 1.2, Damage, or Render, a server drawing on a device other than the encode node, a buffer the server will not import, or a first frame the encoder cannot read; the session then streams through XShm. A watermark is not a reason: the server composites it through Render like the cursor, so it costs no readback here.

pixelflux supports both an X11 and a Wayland backend (the latter built on Smithay), selected per capture by the use_wayland attribute on CaptureSettings:

  • settings.use_wayland = True — force the Wayland backend
  • settings.use_wayland = False — force the X11 backend
  • settings.use_wayland = None (default) — use Wayland when the session exposes a WAYLAND_DISPLAY, otherwise X11

To test launching programs into this backend simply add WAYLAND_DISPLAY=wayland-1 before launching them:

WAYLAND_DISPLAY=wayland-1 glmark2-es2-wayland -s 1920x1080

Each display renders at its own target_fps, and fresh input may pull its next frame forward: half a frame after the last one, a pointer move or a key press is composited and published at once, and the cadence then follows the input's phase, so a pointer moving at the client's refresh rate is captured as it lands instead of up to a frame later. The frames pulled forward come out of a small budget, which keeps the sustained rate within a few percent of target_fps.

Host capture (external compositors)

Setting wayland_host_display to another compositor's socket captures that session instead of the built-in one, with input injected through the virtual keyboard/pointer protocols. Frames are fetched with ext-image-copy-capture-v1 when the host offers it (wlroots 0.19+, KWin 6.2+, COSMIC) and zwlr-screencopy-v1 (v3) otherwise, so any wlroots-era or KDE compositor works; PIXELFLUX_HOST_CAPTURE=zwlr forces the fallback for triage. Both protocols share the same buffer plan: with a GPU the host blits into GBM dmabufs that the encoder imports directly (no CPU copy anywhere), a host that cannot import our dmabufs (other GPU, software renderer) is captured through shm instead, and both are damage-gated so a static screen costs nothing.

A host that offers neither protocol — GNOME, or KDE before its ext-image-copy-capture support — is captured through xdg-desktop-portal instead: one RemoteDesktop session on the session bus (DBUS_SESSION_BUS_ADDRESS) hands out a PipeWire stream per monitor, and takes the keyboard and pointer where the host has no virtual-input protocol for them. A host that grants the screen but refuses those devices answers the whole request as a refusal, so the session is asked again for capture alone: declining remote interaction leaves the video working without injection. Each capability picks its rung from the registry, so a KWin that serves ext-image-copy-capture but no zwlr-virtual-pointer gets its frames natively and its pointer from the portal. The compositor owns the portal's buffers: a dmabuf frame is imported by the encoder where it lies (the stream offers the modifiers the encoder's display imports) and a memfd frame is read in place, cursor metadata delivers the host's own cursor sprite to the cursor callback, and the stream is asked for at most the capture's frame rate. Portal input takes the lower-latency libei channel where the backend answers ConnectToEIS — one socket for keyboard, pointer and touch, and the path the GNOME and KDE backends develop — and the portal's own Notify* methods otherwise. A successful ConnectToEIS makes the session refuse Notify*, so libei is taken only once its handshake binds a device; keys resolve against the compositor's own keymap that libei delivers, with a raw-keycode fallback, while the Notify* path travels keysyms the host applies its layout to. The portal's consent dialog, where a backend shows one (GNOME; KDE shows none to an unsandboxed process), blocks only the first start: the restore token the backend hands back is kept in $XDG_STATE_HOME/pixelflux/portal-restore-token (~/.local/state by default) and restores the session without a dialog when it is reopened to change the cursor mode and on every later start. libpipewire-0.3 is loaded at run time as for the virtual camera; the bus client is pure Rust.

Displays map onto host outputs by rank, so multi-display capture needs the host to expose that many outputs: ScreenCapture.output_capacity() reports the host's output count (-1 when self-compositing, where outputs are created on demand), and create_output refuses ids the host cannot back rather than minting an output that would never receive a frame.

A capture's size is asked of the host through wlr-output-management, but what it captures is the mode the host ends up running. A host that refuses the request, offers no layout management (KWin), or acknowledges a mode it never applies (Hyprland) has the capture re-sized to the mode it announces, which get_realized_geometry reports and capture_state carries as a caveat, so an output with a fixed mode list streams at its own resolution instead of never converging.

The built-in compositor also serves ext-image-copy-capture-v1 (with per-output sources), so standard capture tools — or another pixelflux — can record a pixelflux session: dmabuf clients are filled by one GPU blit from the composited frame, shm clients by one readback, and an unchanged screen holds the frame instead of duplicating it.

Automatic GPU Selection

Set the auto_gpu attribute on CaptureSettings to let pixelflux pick a render node automatically instead of supplying one — "true" (or any truthy value) picks the first GPU, and a token (a kernel driver name, PCI vendor id, or devicetree prefix) picks the first GPU that matches. It enumerates /sys/class/drm, pairs each cardN with its renderD* node by PCI device, and skips non-GPU cards (IPMI/VGA). Selection is driver-aware: NVIDIA nodes are routed to NVENC, while Intel (i915) and AMD (amdgpu) nodes take the VA-API path. Both the X11 and Wayland backends honor it. (Selkies fills this from its --auto-gpu / SELKIES_AUTO_GPU inputs.)

settings.auto_gpu = "true"

When auto-selection is off, the encoder device is chosen by encode_node_index (default -2 = auto): -1 forces software and >= 0 selects /dev/dri/renderD(128 + index); an explicit encode_node_path / render_node_path takes precedence.

Capture Settings

The CaptureSettings class configures both backends.

from pixelflux import CaptureSettings, ScreenCapture

settings = CaptureSettings()

# --- Core Capture ---
settings.capture_width = 1920
settings.capture_height = 1080
settings.capture_x = 0
settings.capture_y = 0
settings.capture_cursor = True
settings.target_fps = 60.0
settings.scale = 1.0  # Fractional scaling (Wayland only)
settings.wayland_host_display = ""                  # Capture from an EXTERNAL compositor instead of the built-in one (host-capture mode)

# --- Codec ---
# "jpeg" (striped stills), "h264" (striped, or full-frame with video_fullframe), or a
# full-frame video codec: "h265", "vp8", "vp9", "av1"
settings.codec = "h264"
# Force CPU encoding and ignore hardware encoders. The software encoder behind each codec
# is the build's (pixelflux.SOFTWARE_ENCODERS): x264 or OpenH264 for H.264, x265 or kvazaar
# for H.265, libvpx for VP8/VP9, SVT-AV1 for AV1.
settings.use_cpu = False

# --- Debugging ---
settings.debug_logging = False # Enable/disable the continuous FPS and settings log and FFmpeg's informational lines. SVT-AV1's banner follows SVT_LOG, errors-only unless set.

# --- JPEG Settings ---
settings.jpeg_quality = 75              # Quality for changed stripes (0-100)
settings.paint_over_jpeg_quality = 90   # Quality for static "paint-over" stripes (0-100)

# --- Video Settings ---
settings.video_crf = 25                            # Quality index on the H.264 QP scale (0-51, lower is better quality); mapped onto each codec's own quantizer range
settings.video_paintover_crf = 18                  # Quality index for the paintover on static content. Must be lower than video_crf to activate.
settings.video_paintover_burst_frames = 5          # Number of high-quality frames to send in a burst when a paintover is triggered.
settings.video_fullcolor = False                   # Use 4:4:4 chroma instead of 4:2:0 where the codec carries it (H.264 and H.265): software x264/x265 and NVENC take it, VA-API negotiates it per device.
settings.video_fullframe = True                    # H.264 only: encode full frames instead of changed stripes (every other video codec is full-frame)
settings.video_streaming_mode = False              # Bypass all VNC logic and work like a normal video encoder, higher constant CPU usage for fullscreen gaming/videos
settings.keyframe_interval_s = 0.0                   # Periodic keyframe interval in seconds (0 = keyframes only on demand/paint-over)
settings.video_cbr_mode = False                    # Switches to CBR mode and ignores CRF value. Used in conjunction with video_bitrate_kbps.
settings.video_bitrate_kbps = 4000                 # Target bitrate for CBR mode. Required when video_cbr_mode is enabled.
settings.video_vbv_multiplier = 1.5                # Optional CBR VBV size as a multiple of one frame's bit budget (0 = auto: 1.5, or 3 with periodic keyframes).
settings.auto_adjust_screen_capture_size = True   # Allow pixelflux to adjust its capture width and height.

# --- Hardware Acceleration ---
# Encoder device selection:
#   -2: Auto-detect (default; combine with auto_gpu — see Automatic GPU Selection)
#   -1: Force software encoding
#   >= 0: Use the GPU at /dev/dri/renderD(128 + index)
settings.encode_node_index = -2
# Explicit encoder device path; takes precedence over the index above. str or bytes,
# e.g. "/dev/dri/renderD128".
settings.encode_node_path = None
# Explicit compositor render node (Wayland); str or bytes.
settings.render_node_path = None

# --- Wire Format / Zero-Copy (X11) ---
# False (default): prepend the per-stripe header to each packet (the WebSocket path): the tag,
# the codec and frame kind, then the frame id, the stripe's top row, its width and height, and
# the id of the frame it predicts from, all big-endian u16.
# True: emit the raw encoded payload with no header (for a WebRTC path that frames itself).
settings.omit_stripe_headers = False

# --- Change Detection & Optimization ---
settings.video_min_qp = 0                          # CBR QP clamps: 0 = encoder default; max bounds the quality floor, min bounds bit waste on easy content
settings.video_max_qp = 0
settings.use_paint_over_quality = True  # Enable paint-over/IDR requests for static regions
settings.paint_over_trigger_frames = 15 # Frames of no motion to trigger paint-over
settings.damage_block_threshold = 10    # Consecutive changes to trigger "damaged" state
settings.damage_block_duration = 30     # Frames a stripe stays "damaged"

# --- Watermarking ---
# Must be a bytes object. The path to your PNG image.
settings.watermark_path = b"/path/to/your/watermark.png" 
settings.cursor_size_cap = 128                     # Cap out-of-band hardware-cursor PNGs to this longest edge (<= 0 = uncapped)
# 0:None, 1:TopLeft, 2:TopRight, 3:BottomLeft, 4:BottomRight, 5:Middle, 6:Animated
settings.watermark_location_enum = 4 

Input Injection (Wayland Only)

In Wayland mode, pixelflux acts as the compositor. You cannot use external tools like xdotool. Instead, use the input injection methods provided by the ScreenCapture instance:

capture = ScreenCapture()
capture.start_capture(my_callback, settings)

# Inject Mouse Motion (Absolute coordinates)
capture.inject_mouse_move(x=500.0, y=300.0)

# Inject Mouse Button (evdev button codes: 272=Left, 273=Right, 274=Middle)
# State: 1 = Pressed, 0 = Released
capture.inject_mouse_button(btn=272, state=1) 

# Inject Scroll (Vertical/Horizontal)
capture.inject_mouse_scroll(x=0.0, y=10.0)

# Inject Keyboard Key
# scancode: Linux raw keycode (e.g., 17 for 'w')
# state: 1 = Pressed, 0 = Released
capture.inject_key(scancode=17, state=1)

Stripe Callback

Your callback receives a single StripeFrame object (the same type on both the X11 and Wayland backends). It supports the buffer protocol — bytes(frame) / memoryview(frame) / len(frame) — and exposes the stripe metadata as attributes:

def my_callback(frame):
    # frame.data_type      (the codec id: 0=JPEG, 1=H.264, 2=VP8, 3=VP9, 4=AV1, 5=H.265)
    # frame.frame_id
    # frame.stripe_y_start
    # frame.stripe_height
    # frame.capture_ns, frame.encode_start_ns, frame.encode_end_ns
    #                      (CLOCK_MONOTONIC nanoseconds, comparable with time.monotonic_ns();
    #                       the stripes of a frame share them)
    # frame.reference_frame_id
    #                      (the frame this one predicts from: -1 when it decodes on its own,
    #                       -2 where the encoder does not track its references)
    encoded_data = bytes(frame)          # copy out, or use memoryview(frame) zero-copy (below)
    # Send encoded_data to the client...

Zero-Copy Frames

memoryview(frame) aliases the native encoder buffer with no copy, on every supported Python version (3.9–3.14). The frame object owns its buffer and keeps it alive until every consumer — including a transport that retained a slice during a partial write — has released its view, so the hand-off is memory-safe. (The old deferred_free / OwnedFrame / PEP 688 / Python-3.12-only path is gone; the native buffer protocol does this on all versions.) Hand the view straight to an async socket; keep the frame referenced for the duration of the send.

def my_callback(frame):
    if frame.data_type == 0 or len(frame) == 0:   # nothing to send
        return
    # Hand BOTH the view and the frame to your sender (e.g. an asyncio.Queue) so the buffer
    # outlives the send: the view pins the frame, which frees the buffer once the view drops.
    queue.put_nowait({"data": memoryview(frame), "owner": frame})

See example/screen_to_browser.py for a complete queue-based usage.

What a Capture Runs On

Which path a capture took is decided by the hardware, the driver and the display server rather than by a setting, so the capture says what it settled on instead of leaving it in the log. capture.stream_info() returns a dict, None before a start and after a stop:

Key Meaning
backend x11 or wayland
capture, zero_copy the capture path (NvFBC, DRI3, XShm, dmabuf, readback) and whether frames reach the encoder without a copy
capture_reason why a zero-copy path was declined, each declined path named (NvFBC: ...; DRI3: ...); empty where there is nothing to explain
encoder, hardware NVENC, VAAPI, or the software library, and whether it runs on a GPU
encoder_reason why the session does not encode in hardware: the refusal the hardware session answered with, software encoding being selected, or a session given up after repeated errors
codec, fullcolor, striped what the stream is, after any demotion
gpu, driver, encode_node the device a hardware session encodes on
renderer, render_node, render_gpu, renderer_reason Wayland only: gl or pixman, the node and GPU the compositor renders on, and why it renders in software

The description follows the capture: a session that demotes itself mid-stream (zero-copy to readback, hardware to software) changes what the next call returns. NVENC names its own device; for a VA-API session the first call brings a GL context up once on the encode node to name the GPU, so a caller with an event loop makes the call off it.

capture.stream_stats() returns cumulative counters since the start (frames, bytes, encode_ns, pipeline_ns from capture to the end of the encode), which a caller differences into a rate. They are relaxed atomics tallied once per delivered frame and read only on the call, so a capture nobody inspects pays nothing for them.

Zero-Copy Pipeline (Wayland)

The Wayland backend implements a Zero-Copy architecture for hardware encoding.

  1. Rendering: The compositor renders the desktop to a GPU buffer (GBM).
  2. Export: This buffer is exported as a Dmabuf (file descriptor).
  3. Encoding: The Dmabuf is imported directly into the encoder context (NVENC or VA-API) without ever copying pixel data to system RAM (CPU).

Performance Note: Software (Pixman) rendering, the absence of a hardware encoder, or utilizing a render node different from the encoding node will force a "Readback" fallback, copying pixels to the CPU and breaking the zero-copy chain (higher latency and CPU load). A watermark does not force readback — on the GPU path it is composited into the frame before encoding.

Built-in MP4 Recorder

For convenience, the extension ships its own fragmented-MP4 muxer (no avformat dependency) with the start_recording(...), stop_recording(), and recording_status() Python functions, controllable through the PIXELFLUX_RECORD* environment variables. Recording taps the encoded full-frame H.264 stream, and HTTP endpoints allow remote trigger/stop/status.

start_recording(path, settings=None, audio_socket="") adds an Opus audio track when audio_socket (or PIXELFLUX_RECORD_AUDIO) names a Unix socket serving an Ogg Opus stream, such as pcmflux's output_socket: the recorder connects, keeps the packets as they are, and places them by their granule positions against the video clock, so the file is muxed without a decode or re-encode. recording_status() counts them as audio_frames.

Screenshots

screenshot_png(display=0) returns a PNG of one display with the cursor drawn in, the same image the Computer-Use server serves: the in-process Wayland compositor's output when one runs, else the root of the X server named by DISPLAY. It needs no running capture.

Recording Sink

The capture session can output the raw video stream directly to a Unix domain socket for external recording: Annex-B for H.264 and H.265, an OBU stream for AV1, and IVF for VP8 and VP9.

Note: This feature requires full-frame video encoding and does not work with JPEG or striped H.264 modes.

# Enable the unix socket (forces IDR frames every 30 frames and on connect)
settings.recording_socket = "/tmp/pixelflux_record"

You can then capture the stream using ffmpeg:

# Raw copy
ffmpeg -f h264 -i unix:///tmp/pixelflux_record -c:v copy test.h264

# Re-encode for a clean MP4
ffmpeg -f h264 -framerate 60 -i unix:///tmp/pixelflux_record -c:v libx264 -preset fast -crf 23 -pix_fmt yuv420p test.mp4

Virtual Camera

VirtualCamera turns a client's webcam uplink into a V4L2 capture device for applications. Encoded frames of any browser codec — H.264, VP8, VP9, AV1, HEVC (WebCodecs or a WebRTC media track) and MJPEG (the canvas fallback) — are pushed in; a worker thread decodes them (libavcodec, TurboJPEG), fits them into the device's fixed format (raw I420 by default, NV12, or YUYV; or MJPEG, a compressed device that carries an MJPEG uplink's frames as received, decoding nothing, and re-encodes only frames that must be fitted), and publishes every frame to the configured sinks at once:

  • a shared-memory ring served over a Unix socket to the Selkies V4L2 interposer (LD_PRELOAD, no privileges, no kernel module), which presents /dev/videoN to the application;
  • a v4l2loopback output device (device_path) on hosts and privileged containers that have the module, where applications need no preload at all;
  • a PipeWire Video/Source node (pipewire) when a daemon is reachable, for PipeWire-native consumers and the pipewire-v4l2 wrapper (libpipewire-0.3 is loaded at run time; nothing is linked at build time).
from pixelflux import VirtualCamera, VirtualCameraSettings

settings = VirtualCameraSettings()
settings.socket_path = "/tmp/selkies_webcam0.sock"   # what the interposer connects to
settings.width, settings.height = 1280, 720          # frames are scaled and letterboxed to fit
settings.pixel_format = "I420"                       # "I420", "NV12", "YUYV" or "MJPEG" (an MJPEG uplink passes through)
settings.device_path = "auto"                        # "", "auto", or a /dev/videoN to mirror into
settings.pipewire = True                             # publish the PipeWire node when a daemon is reachable

cam = VirtualCamera()
cam.start(settings)
flags = cam.push(h264_frame, VirtualCamera.CODEC_H264, keyframe=True)   # any buffer object; returns at once
if flags & VirtualCamera.KEYFRAME_WANTED:
    ...  # the decoder lost its reference (dropped frame, late start): ask the client for a keyframe
print(cam.stats())   # pushed/decoded/published/dropped/skipped/errors, geometry, clients, device_path
cam.stop()

push(data, codec, keyframe=False, offset=0) copies the encoded bytes out of the buffer and returns; decoding never runs on the caller's thread and no worker ever calls back into Python. A full decoder queue drops the oldest frame and, for inter-coded codecs, waits for the next keyframe rather than decoding against a missing reference. VirtualCamera.shm_layout() reports the ring's byte layout for the interposer's ABI test.

Computer Use Interface (X11 and Wayland)

Both backends implement the Anthropic Computer Use specification, providing an HTTP API for AI agents to control the desktop. On Wayland the compositor injects input natively; on X11 the existing display is driven through XTEST with root-window screenshots. Enable it by setting the PIXELFLUX_CU environment variable to the port the server should listen on:

export PIXELFLUX_CU=5000

A bare port is served on the loopback addresses only (127.0.0.1,::1); the API carries no authentication, so open it to other hosts deliberately by naming the addresses to listen on as comma-separated host:port entries, PIXELFLUX_CU=0.0.0.0:5000,[::]:5000 for every interface. The same value is what start_computer_use() takes when a script starts the server itself.

When using Computer Use, call ensure_wayland_display() before starting a capture to bring the compositor socket up early — this lets apps launched alongside your script connect to WAYLAND_DISPLAY immediately. GPU auto-selection (auto_gpu on CaptureSettings) works normally; the screenshot path forces a single-frame CPU readback when the GPU is in zero-copy mode.

The Computer Use server listens for POST requests on /computer-use and responds with JSON. Unless otherwise noted, successful actions return:

{"result":"ok"}

Coordinates are specified in absolute framebuffer pixels. Any coordinates outside the framebuffer are automatically clamped to the nearest valid pixel.

Actions

All actions are POST requests to /computer-use with a JSON body.

screenshot - Capture the current display as a base64-encoded PNG:

curl -s -X POST http://localhost:5000/computer-use \
  -H 'Content-Type: application/json' \
  -d '{"action":"screenshot"}' | jq -r '.data' | base64 -d > screen.png

mouse_move - Move the cursor to absolute pixel coordinates:

curl -s -X POST http://localhost:5000/computer-use \
  -H 'Content-Type: application/json' \
  -d '{"action":"mouse_move","coordinate":[500,300]}'

left_click / right_click / middle_click - Click a mouse button, optionally at a coordinate and/or while holding a keyboard modifier:

# Simple click
curl -s -X POST http://localhost:5000/computer-use \
  -H 'Content-Type: application/json' \
  -d '{"action":"left_click"}'

# Right click at a specific position while holding Shift
curl -s -X POST http://localhost:5000/computer-use \
  -H 'Content-Type: application/json' \
  -d '{"action":"right_click","coordinate":[800,600],"text":"shift"}'

double_click / triple_click - Perform multiple left mouse clicks, optionally while holding a modifier:

curl -s -X POST http://localhost:5000/computer-use \
  -H 'Content-Type: application/json' \
  -d '{"action":"double_click","coordinate":[400,300]}'

curl -s -X POST http://localhost:5000/computer-use \
  -H 'Content-Type: application/json' \
  -d '{"action":"triple_click","text":"ctrl"}'

left_click_drag - Press the left mouse button at start_coordinate, drag to coordinate, then release:

curl -s -X POST http://localhost:5000/computer-use \
  -H 'Content-Type: application/json' \
  -d '{"action":"left_click_drag","start_coordinate":[100,100],"coordinate":[500,300]}'

left_mouse_down / left_mouse_up - Press or release the left mouse button without moving the pointer:

curl -s -X POST http://localhost:5000/computer-use \
  -H 'Content-Type: application/json' \
  -d '{"action":"left_mouse_down"}'

type - Type a string of text:

curl -s -X POST http://localhost:5000/computer-use \
  -H 'Content-Type: application/json' \
  -d '{"action":"type","text":"Hello, world!"}'

key - Press a key or key combination. Key combinations are specified using + separators:

# Single key
curl -s -X POST http://localhost:5000/computer-use \
  -H 'Content-Type: application/json' \
  -d '{"action":"key","text":"Return"}'

# Key combination
curl -s -X POST http://localhost:5000/computer-use \
  -H 'Content-Type: application/json' \
  -d '{"action":"key","text":"ctrl+s"}'

curl -s -X POST http://localhost:5000/computer-use \
  -H 'Content-Type: application/json' \
  -d '{"action":"key","text":"ctrl+alt+Delete"}'

hold_key - Hold a key for the specified duration (seconds). Durations are capped at 100 seconds.

curl -s -X POST http://localhost:5000/computer-use \
  -H 'Content-Type: application/json' \
  -d '{"action":"hold_key","text":"ctrl","duration":2.0}'

scroll - Scroll vertically or horizontally, optionally at a coordinate and/or while holding a keyboard modifier:

# Scroll down 3 clicks
curl -s -X POST http://localhost:5000/computer-use \
  -H 'Content-Type: application/json' \
  -d '{"action":"scroll","scroll_direction":"down","scroll_amount":3}'

# Scroll at a position while holding Shift
curl -s -X POST http://localhost:5000/computer-use \
  -H 'Content-Type: application/json' \
  -d '{"action":"scroll","coordinate":[500,400],"scroll_direction":"up","scroll_amount":5,"text":"shift"}'

cursor_position - Return the current cursor position:

curl -s -X POST http://localhost:5000/computer-use \
  -H 'Content-Type: application/json' \
  -d '{"action":"cursor_position"}' | jq -r '.text'
# → X=500,Y=300

wait - Pause execution for the specified duration (seconds). Durations are capped at 100 seconds.

curl -s -X POST http://localhost:5000/computer-use \
  -H 'Content-Type: application/json' \
  -d '{"action":"wait","duration":0.5}'

zoom - Capture and return a cropped base64-encoded PNG of the specified framebuffer region ([left, top, right, bottom]):

curl -s -X POST http://localhost:5000/computer-use \
  -H 'Content-Type: application/json' \
  -d '{"action":"zoom","region":[100,200,400,350]}' | jq -r '.data' | base64 -d > zoomed.png

NVIDIA Jetson (Tegra)

A Jetson has a hardware video encoder and none of the usual ways to reach it: L4T carries no libnvidia-encode, has no VA-API driver, and its /dev/v4l2-nvenc node is a placeholder that h264_v4l2m2m cannot drive. The encoder is only reachable through the vendor's own libraries, so the Tegra session loads libnvv4l2.so for the encoder node and, for the surfaces, whichever library the board carries: libnvbuf_utils.so on JetPack 4, or libnvbufsurface.so with libnvbufsurftransform.so on JetPack 5 and 6, where the older one is gone. Either way the captured BGRA is converted to NV12 on the VIC block and the encoder is handed DMABUF surfaces, so no frame is converted on a CPU core.

  • Selection: the ladder consults this backend before it probes render nodes, because a Jetson has no render node to probe. hardware_encoders() reports every codec the vendor encoder takes a capture format for there, and a session logs its backend as TEGRA.
  • Codecs: H.264, H.265 and AV1, 4:2:0, Main profile. The capture queue is set to the session's codec and the rest of the path is the same whichever it is. The board decides what it actually has an engine for: one it does not serve refuses the format, and the session falls back to software with the refusal in stream_info. The VIC does the color conversion, so video_fullcolor has no effect on this path.
  • Live changes: the CBR target bitrate can be changed on a running session; the frame rate and the resolution rebuild it, as elsewhere.
  • Measured on a Jetson Nano (L4T R32.6.1, four Cortex-A57 cores) in a live Selkies session, against the striped software encoder on the same board: 0.17 cores at 1080p30 and 0.30 at 1080p60, against 2.26 cores for x264 at 1080p30. At 4K30 it holds 29 fps on 0.44 cores. The encode itself is 0.10 ms a frame at 1080p and 0.21 ms at 4K; what the path actually spends is the copy of the captured frame into the staging surface (2.8 ms at 1080p, 9.6 ms at 4K) and the VIC conversion (1.7 ms and 5.9 ms).
  • Measured on an AGX Orin (L4T R36.4.3, twelve Cortex-A78AE cores), isolated encode path over 200 frames: 0.05 cores at 1080p30, 0.10 at 1080p60, 0.20 at 1080p120 and 0.15 at 4K30, against 0.49 cores for the striped software encoder in a live session at 1080p30. 4K60 is not reachable on that board either: the VIC conversion alone is 12 ms a frame there and the path holds 46 fps. The conversion is pinned to the VIC rather than left at the API's default; both cost 4.9 ms a frame at 1080p there and the GPU 0.9 ms, and that GPU is what a robot runs its perception on.

NVIDIA NVENC (X11)

  • Multi-GPU containers: When several GPUs are exposed to a container, NVENC is filtered in-process to the GPU you selected (no separate LD_PRELOAD shim is required). Verified on NVIDIA drivers 570–595.
  • 4:4:4 (High 4:4:4): Set video_fullcolor = True to encode full-chroma H.264 via NVENC (video_fullcolor codec), in addition to the software path. See VA-API 4:4:4 for how the same request is resolved on VA-API.
  • Force a keyframe on demand: capture.request_idr_frame() forces an IDR frame, e.g. when a client reconnects or its decoder is reset. It routes to whichever encoder is active (NVENC, VA-API, or software) and is a no-op while no capture is running.
  • Predict past a frame a client lost: capture.invalidate_reference(frame_id) leaves that frame and everything encoded after it out of the predictions, so the next frame decodes for a client that never received it and the stream costs no keyframe. Each frame says what it predicts from (StripeFrame.reference_frame_id), which is what a consumer holds the frames behind a loss back by. NVENC and libx264 track their references, on the devices whose drivers offer it; a session that does not reports -2 and answers this with a keyframe instead, as does an H.264 session for a loss covering the frame at its frame_num wrap, which FFmpeg's decoder cannot be predicted past.

Color conversion

The desktop source is sRGB, which shares BT.709's primaries and transfer function, so every session converts with the BT.709 matrix and declares it: the software encoders' host conversion, the VA-API convert (scale_vaapi), and NVENC's GPU kernel, at limited range for 4:2:0 and full range for the software 4:4:4 sessions (x264, x265). Chroma sits at the center of each 2x2 block — the average of all four pixels — so the color a subpixel-antialiased glyph edge carries cancels instead of tinting the chroma plane.

NVENC takes the captured ARGB, so there is no CUDA Toolkit / NVRTC requirement — only the NVIDIA driver runtime (libnvidia-encode, libcuda), which is loaded at runtime. Its fixed-function ARGB→YUV conversion follows the matrix the session declares, measured on Volta and Pascal, but weights the two columns of a 4:2:0 block 3:1 rather than averaging them. A 4:2:0 session therefore converts on the GPU itself, with a small kernel shipped as PTX that libcuda JIT-compiles (still no toolkit and no runtime compiler), reading the frame where it already lies — the packed surface, a pitch-linear dmabuf import, or a texture over an array-typed one — and writing the NV12 the encoder takes. 4:4:4 subsamples nothing, so it keeps the hardware conversion, and so does a driver that refuses the kernel: the matrix is right either way and only the siting differs.

VP8 is the one codec that cannot carry this: its keyframe header holds a single color-space bit whose only defined value is BT.601. Told BT.709 out of band instead — in the decoder configuration a client passes and in the RTP color-space header extension — Chromium and WebKit paint it correctly, while Firefox reads neither and inverts BT.601, shifting saturated color by 20 levels on both transports, so VP8 converts and declares BT.601 (WebKit's GStreamer ports invert BT.709 there whatever it carries, that port dropping the color space the client declares). JPEG stripes are JFIF, which is BT.601 at full range by definition. Nothing extra to install at build or runtime beyond the driver.

Two receiver-side caveats, measured rather than inferred. Chromium and Firefox both convert YUV through libyuv, whose default build clamps the BT.709 Cb→B coefficient to 2.0 because the true 2.112 does not fit its fixed-point constant, so saturated blue arrives up to 12 levels short of the source wherever that conversion runs on the CPU; BT.601's coefficient is clamped the same way and loses 2. And Firefox drops the color description of an AV1 stream it receives over WebRTC, painting it as BT.601 — its WebCodecs path and every other codec on both transports honor what the stream declares.

VA-API 4:4:4

video_fullcolor = True is carried into the VA-API session rather than ruled out in advance. The encoder asks the device which 4:4:4 surface formats it allocates and which of those its video processor renders, since every frame reaches the codec through the scale_vaapi convert (Intel's iHD allocates planar 444P but renders 4:4:4 only as packed XYUV, so it encodes from vuyx), and tries each format on both lists in turn, planar yuv444p ahead of packed vuyx, until one survives the whole bring-up: the surface pool, the convert's output pad and the codec open. A driver can still report a surface its encoder entry point does not take, and that shows only at one of those steps, so a format refused there hands over to the next rather than failing the session. The session builds the surface pool and the convert around the format that survived, names it in its init line, and lets FFmpeg match a profile to it instead of pinning high.

Three layers can refuse, and each says so in the log line that precedes the fallback: the driver rendering no 4:4:4 surface format, the driver refusing to allocate one, and h264_vaapi having no profile that matches it. For H.264, on every current driver the third is what answers: it has no VAProfile in libva at all, so FFmpeg's h264_vaapi advertises only 4:2:0 profiles (plus 10-bit 4:2:0 from libva 1.18). A refusal falls back to the software path, where x264 does carry 4:4:4 — the request is honored, on the CPU, rather than silently downgraded to 4:2:0 (a GPL-free build's OpenH264 is 4:2:0-only and says so in the log).

Nothing here is pinned to that state of affairs: a driver and FFmpeg build that gain H.264 4:4:4 start using it with no code change, and Colorspace: in the stream log always reports what the session settled on rather than what was asked for.

Features

  • Dual Backend (one Rust extension):
    • X11: zero-copy capture through NvFBC on the NVIDIA X driver or through DRI3 on any server whose screen lives on the GPU, else XShm capture via pure-Rust XCB with XFixes cursor and watermark compositing.
    • Wayland: Modern, secure, headless compositor based on Smithay.
  • Flexible Encoding:
    • Software: H.264 through x264 (incl. 4:4:4 — GPL, the default) or, in a GPL-free build, the BSD-licensed OpenH264 (4:2:0), and JPEG — both with multi-threaded striping; full-frame H.265 through x265 (incl. 4:4:4) or kvazaar, VP8 and VP9 through libvpx, AV1 through SVT-AV1, all through the linked FFmpeg; pixelflux.SOFTWARE_ENCODERS names the build's encoder per codec, and pixelflux.hardware_encoders(encode_node_index, auto_gpu) the codecs a render node's NVENC or VA-API serves, the node resolved as a capture resolves it, probed once per node at first call. pixelflux.SOFTWARE_FULLCOLOR and pixelflux.hardware_fullcolor(encode_node_index, auto_gpu) name, of those, the codecs each side encodes 4:4:4 when video_fullcolor asks for it, so a caller knows the chroma a session will carry before it opens one.
    • Hardware: NVIDIA NVENC (H.264, H.265 and AV1; incl. 4:4:4 for H.264 and H.265, ARGB-direct with matched VUI color signaling, multi-GPU containers, API-version negotiation) and VA-API (Intel/AMD; H.264, H.265, VP8, VP9, and AV1, VA-VPP convert, per-device 4:4:4 negotiation, low-power entry points) with Zero-Copy support.
    • Driver-aware GPU auto-selection via the auto_gpu setting.
  • Zero-Copy Frames (X11 & Wayland): the native frame object (buffer protocol) hands the encoded buffer to Python with no copy, on every supported Python version (3.9–3.14).
  • Smart Bandwidth Management:
    • Change Detection: Encodes only changed stripes (Software/JPEG mode).
    • Paint-Over: Automatically improves quality for static regions.
    • Damage Throttling: Limits processing during high-motion scenes.
    • On-demand keyframes: request_idr_frame() forces an IDR for reconnecting clients.
    • Reference invalidation: invalidate_reference(frame_id) has the encoder predict past a frame a client lost, so recovery costs no keyframe.
  • Self-description: stream_info() reports the capture path, the encoder, the GPU, and why a faster path was declined, and stream_stats() the encode's counters, so a caller shows its user what a session runs on instead of pointing them at a log.
  • Input Handling: Built-in input injection for mouse and keyboard (Wayland; XTEST on X11 via Computer Use).
  • Cursor Compositing: Hardware cursor planes or software rendering options.
  • Dynamic Watermarking: Overlay PNGs with static positioning or DVD-screensaver style animation.
  • Recording Sink: Direct Unix socket output of full-frame video streams (Annex-B, OBU, or IVF by codec) for local capture.
  • Virtual Camera: A client's webcam uplink (H.264/VP8/VP9/AV1/HEVC/MJPEG) decoded off the GIL into a V4L2 capture device (or passed through as an MJPEG device when the browser sends JPEG), served to the Selkies V4L2 interposer (no privileges) and mirrored into v4l2loopback and a PipeWire node where available.
  • Built-in MP4 Recorder: Crash-safe fragmented-MP4 recording without any FFmpeg avformat dependency.
  • AI Agent Control: Computer Use API to dump screenshots and drive all facets of a desktop environment.

Development

AGENTS.md carries the conventions and the invariants of this tree, for contributors and coding agents alike. The crate builds in two configurations, cargo test --lib (the default gpl feature, libx264) and cargo test --lib --no-default-features --features openh264, and both are expected to pass. The #[ignore]d gpu_ tests run on an NVIDIA GPU with cargo test gpu_ -- --ignored --nocapture --test-threads=1, the gpu_dmabuf_ ones need a render node, and the gpu_bench_ ones print measurements. pip wheel . --no-deps builds the extension the way the released wheels are built (PIXELFLUX_ENABLE_GPL=0 for the OpenH264 build), and that wheel installed into a selkies checkout set up as its development documentation describes puts the change under the end-to-end suites. The .devcontainer installs the native dependencies the build needs.

License

This project is licensed under the Mozilla Public License Version 2.0. A copy of the MPL 2.0 can be found at https://mozilla.org/MPL/2.0/.

Note that the default build links the GPL-2.0+ libx264 as its software H.264 encoder and reaches GPL-2.0+ x265 through FFmpeg for H.265; build with PIXELFLUX_ENABLE_GPL=0 to exclude every GPL-licensed component (the BSD-licensed openh264 and kvazaar then take their places, and the FFmpeg bindings are used LGPL-only).

LICENSES.md inventories every third-party component of both builds (crates, linked and vendored native libraries, what is loaded at run time) with its license, and describes the check (scripts/check-licenses.py, pixelflux/deny.toml, the Licenses workflow) that keeps the non-GPL build free of copyleft code.

Metadata

Release files for pixelflux 2.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Built distributions (wheels)

Table of built distributions (wheels) for pixelflux 2.1.0
File
pixelflux-2.1.0-cp315-cp315-musllinux_1_2_x86_64.whl CPython 3.15 CPython 3.15 Linux musl 1.2+ x86-64 Details
pixelflux-2.1.0-cp315-cp315-musllinux_1_2_aarch64.whl CPython 3.15 CPython 3.15 Linux musl 1.2+ ARM64 Details
pixelflux-2.1.0-cp315-cp315-manylinux_2_28_x86_64.whl CPython 3.15 CPython 3.15 Linux glibc 2.28+ x86-64 Details
pixelflux-2.1.0-cp315-cp315-manylinux_2_28_aarch64.whl CPython 3.15 CPython 3.15 Linux glibc 2.28+ ARM64 Details
pixelflux-2.1.0-cp314-cp314-musllinux_1_2_x86_64.whl CPython 3.14 CPython 3.14 Linux musl 1.2+ x86-64 Details
pixelflux-2.1.0-cp314-cp314-musllinux_1_2_aarch64.whl CPython 3.14 CPython 3.14 Linux musl 1.2+ ARM64 Details
pixelflux-2.1.0-cp314-cp314-manylinux_2_28_x86_64.whl CPython 3.14 CPython 3.14 Linux glibc 2.28+ x86-64 Details
pixelflux-2.1.0-cp314-cp314-manylinux_2_28_aarch64.whl CPython 3.14 CPython 3.14 Linux glibc 2.28+ ARM64 Details
pixelflux-2.1.0-cp313-cp313-musllinux_1_2_x86_64.whl CPython 3.13 CPython 3.13 Linux musl 1.2+ x86-64 Details
pixelflux-2.1.0-cp313-cp313-musllinux_1_2_aarch64.whl CPython 3.13 CPython 3.13 Linux musl 1.2+ ARM64 Details
pixelflux-2.1.0-cp313-cp313-manylinux_2_28_x86_64.whl CPython 3.13 CPython 3.13 Linux glibc 2.28+ x86-64 Details
pixelflux-2.1.0-cp313-cp313-manylinux_2_28_aarch64.whl CPython 3.13 CPython 3.13 Linux glibc 2.28+ ARM64 Details
pixelflux-2.1.0-cp312-cp312-musllinux_1_2_x86_64.whl CPython 3.12 CPython 3.12 Linux musl 1.2+ x86-64 Details
pixelflux-2.1.0-cp312-cp312-musllinux_1_2_aarch64.whl CPython 3.12 CPython 3.12 Linux musl 1.2+ ARM64 Details
pixelflux-2.1.0-cp312-cp312-manylinux_2_28_x86_64.whl CPython 3.12 CPython 3.12 Linux glibc 2.28+ x86-64 Details
pixelflux-2.1.0-cp312-cp312-manylinux_2_28_aarch64.whl CPython 3.12 CPython 3.12 Linux glibc 2.28+ ARM64 Details
pixelflux-2.1.0-cp311-cp311-musllinux_1_2_x86_64.whl CPython 3.11 CPython 3.11 Linux musl 1.2+ x86-64 Details
pixelflux-2.1.0-cp311-cp311-musllinux_1_2_aarch64.whl CPython 3.11 CPython 3.11 Linux musl 1.2+ ARM64 Details
pixelflux-2.1.0-cp311-cp311-manylinux_2_28_x86_64.whl CPython 3.11 CPython 3.11 Linux glibc 2.28+ x86-64 Details
pixelflux-2.1.0-cp311-cp311-manylinux_2_28_aarch64.whl CPython 3.11 CPython 3.11 Linux glibc 2.28+ ARM64 Details
pixelflux-2.1.0-cp310-cp310-musllinux_1_2_x86_64.whl CPython 3.10 CPython 3.10 Linux musl 1.2+ x86-64 Details
pixelflux-2.1.0-cp310-cp310-musllinux_1_2_aarch64.whl CPython 3.10 CPython 3.10 Linux musl 1.2+ ARM64 Details
pixelflux-2.1.0-cp310-cp310-manylinux_2_28_x86_64.whl CPython 3.10 CPython 3.10 Linux glibc 2.28+ x86-64 Details
pixelflux-2.1.0-cp310-cp310-manylinux_2_28_aarch64.whl CPython 3.10 CPython 3.10 Linux glibc 2.28+ ARM64 Details
pixelflux-2.1.0-cp39-cp39-musllinux_1_2_x86_64.whl CPython 3.9 CPython 3.9 Linux musl 1.2+ x86-64 Details
pixelflux-2.1.0-cp39-cp39-musllinux_1_2_aarch64.whl CPython 3.9 CPython 3.9 Linux musl 1.2+ ARM64 Details
pixelflux-2.1.0-cp39-cp39-manylinux_2_28_x86_64.whl CPython 3.9 CPython 3.9 Linux glibc 2.28+ x86-64 Details
pixelflux-2.1.0-cp39-cp39-manylinux_2_28_aarch64.whl CPython 3.9 CPython 3.9 Linux glibc 2.28+ ARM64 Details

Total release size: 702.8 MB

Release files / pixelflux-2.1.0-cp315-cp315-musllinux_1_2_x86_64.whl

Download URL pixelflux-2.1.0-cp315-cp315-musllinux_1_2_x86_64.whl
Size 26.2 MB
Tags CPython 3.15 Linux musl 1.2+ x86-64
SHA-256 checksum
How to use checksums
fe40f8a6b41647ca8f5fa638510c80517fe8f3f4ea6c493ec794a55aa00ed2dc
BLAKE2b-256 checksum
How to use checksums
75300c5093e3ae551d770f4e924cfb2a00c086383ca8027981fc5f78bab92a07
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 23, 2026.

Transparency log

Release files / pixelflux-2.1.0-cp315-cp315-musllinux_1_2_aarch64.whl

Download URL pixelflux-2.1.0-cp315-cp315-musllinux_1_2_aarch64.whl
Size 24.4 MB
Tags CPython 3.15 Linux musl 1.2+ ARM64
SHA-256 checksum
How to use checksums
c99426737cfe96cb13b7830b77522cf1691f82ce5344a9591edf29e466180c56
BLAKE2b-256 checksum
How to use checksums
b553e85106ee7ed9f30ed65b11b10d29000c3726cf9ccc68955db7041e8bc352
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 23, 2026.

Transparency log

Release files / pixelflux-2.1.0-cp315-cp315-manylinux_2_28_x86_64.whl

Download URL pixelflux-2.1.0-cp315-cp315-manylinux_2_28_x86_64.whl
Size 25.8 MB
Tags CPython 3.15 Linux glibc 2.28+ x86-64
SHA-256 checksum
How to use checksums
f24686924f80602466888e11648a9350bac120ef7d6db6fa55852db9375df210
BLAKE2b-256 checksum
How to use checksums
b82944dbe08c8673dfd2480a7603205ee75271034ddcd6606599cb8f2d9e6d98
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 23, 2026.

Transparency log

Release files / pixelflux-2.1.0-cp315-cp315-manylinux_2_28_aarch64.whl

Download URL pixelflux-2.1.0-cp315-cp315-manylinux_2_28_aarch64.whl
Size 24.0 MB
Tags CPython 3.15 Linux glibc 2.28+ ARM64
SHA-256 checksum
How to use checksums
05db2d7f27ca49485cfa24a7bc5ded1874f45edc524a8d014119120d54676b59
BLAKE2b-256 checksum
How to use checksums
d781ac9a872d359e0a0b54bd83a152fdc2e1bceff30d1fc0a84c88755fba20ca
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 23, 2026.

Transparency log

Release files / pixelflux-2.1.0-cp314-cp314-musllinux_1_2_x86_64.whl

Download URL pixelflux-2.1.0-cp314-cp314-musllinux_1_2_x86_64.whl
Size 26.2 MB
Tags CPython 3.14 Linux musl 1.2+ x86-64
SHA-256 checksum
How to use checksums
30723f1fd143705e0cedecc435a9f5c22a01836003f70ce78bd0f31f4eae4b1f
BLAKE2b-256 checksum
How to use checksums
62a48f95b7cc13732606d1dfd433683f2ebf6b9e78c98b622e4f6d22f51bd8a7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 23, 2026.

Transparency log

Release files / pixelflux-2.1.0-cp314-cp314-musllinux_1_2_aarch64.whl

Download URL pixelflux-2.1.0-cp314-cp314-musllinux_1_2_aarch64.whl
Size 24.4 MB
Tags CPython 3.14 Linux musl 1.2+ ARM64
SHA-256 checksum
How to use checksums
b52ea67229faf114ee23a8eb88a56fc6d1244377b523b7b05c81d80e87764017
BLAKE2b-256 checksum
How to use checksums
40e6b24b9b116b5943f4de36fa73cf9f8c14257b601b8a726b290b68edfa5ba6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 23, 2026.

Transparency log

Release files / pixelflux-2.1.0-cp314-cp314-manylinux_2_28_x86_64.whl

Download URL pixelflux-2.1.0-cp314-cp314-manylinux_2_28_x86_64.whl
Size 25.8 MB
Tags CPython 3.14 Linux glibc 2.28+ x86-64
SHA-256 checksum
How to use checksums
a4f3fb52f5e2dec03c9b1539ac750c19d43a04d00b4de744054260292d1da0f2
BLAKE2b-256 checksum
How to use checksums
55e2b3d4ebf6180ed84c520aafe204a36fcda28d60559caab2e3be889d4eadef
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 23, 2026.

Transparency log

Release files / pixelflux-2.1.0-cp314-cp314-manylinux_2_28_aarch64.whl

Download URL pixelflux-2.1.0-cp314-cp314-manylinux_2_28_aarch64.whl
Size 24.0 MB
Tags CPython 3.14 Linux glibc 2.28+ ARM64
SHA-256 checksum
How to use checksums
9960c804454265d7e25935ef7675032909781a032b50789287c04b1797ebee04
BLAKE2b-256 checksum
How to use checksums
8eab964a7cdb7b6add178c97acb5fbc4b187df14fcf981a88167e065e7c2121b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 23, 2026.

Transparency log

Release files / pixelflux-2.1.0-cp313-cp313-musllinux_1_2_x86_64.whl

Download URL pixelflux-2.1.0-cp313-cp313-musllinux_1_2_x86_64.whl
Size 26.2 MB
Tags CPython 3.13 Linux musl 1.2+ x86-64
SHA-256 checksum
How to use checksums
d4729887bbc3e2a2a364be98809259fb528006390b9e264db226ee7bbdc4692c
BLAKE2b-256 checksum
How to use checksums
6e6701e35117d649746f328b14abacf35179a3b7484d942051101470d754b0b5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 23, 2026.

Transparency log

Release files / pixelflux-2.1.0-cp313-cp313-musllinux_1_2_aarch64.whl

Download URL pixelflux-2.1.0-cp313-cp313-musllinux_1_2_aarch64.whl
Size 24.4 MB
Tags CPython 3.13 Linux musl 1.2+ ARM64
SHA-256 checksum
How to use checksums
f1e109d3443d4295afee2060d608af88bd1f829dea3fb6374eae5f71ce7c279b
BLAKE2b-256 checksum
How to use checksums
0e77010534fb340b8193dccd89deae74543ed5179050f2975cac78d120113157
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 23, 2026.

Transparency log

Release files / pixelflux-2.1.0-cp313-cp313-manylinux_2_28_x86_64.whl

Download URL pixelflux-2.1.0-cp313-cp313-manylinux_2_28_x86_64.whl
Size 25.8 MB
Tags CPython 3.13 Linux glibc 2.28+ x86-64
SHA-256 checksum
How to use checksums
43d47574e52f485d86b4b3d0f56c6bcf160e99ebc658cb59d7a096e6ee0ca1a0
BLAKE2b-256 checksum
How to use checksums
a6954374970992f0f292184c6532e97bc18f48f3430fb5d27574f77bdf9b696b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 23, 2026.

Transparency log

Release files / pixelflux-2.1.0-cp313-cp313-manylinux_2_28_aarch64.whl

Download URL pixelflux-2.1.0-cp313-cp313-manylinux_2_28_aarch64.whl
Size 24.0 MB
Tags CPython 3.13 Linux glibc 2.28+ ARM64
SHA-256 checksum
How to use checksums
7e4f0b94f51bb89f7fa3f152d2657d069382f29d04058c4dc7e7fb3924a81437
BLAKE2b-256 checksum
How to use checksums
f40b5dff1fa8ea3d282bc438fa32b2062251ddb0f29a8ec0fd6e65424bc57deb
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 23, 2026.

Transparency log

Release files / pixelflux-2.1.0-cp312-cp312-musllinux_1_2_x86_64.whl

Download URL pixelflux-2.1.0-cp312-cp312-musllinux_1_2_x86_64.whl
Size 26.2 MB
Tags CPython 3.12 Linux musl 1.2+ x86-64
SHA-256 checksum
How to use checksums
321b3f9119541003ef07e53becf06c0e11887468f0c5e8057bd6dcaab70d2ac5
BLAKE2b-256 checksum
How to use checksums
61680ca4be5ce0642d78df882231f011c96c799a05511a4b7576b156213dba3c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 23, 2026.

Transparency log

Release files / pixelflux-2.1.0-cp312-cp312-musllinux_1_2_aarch64.whl

Download URL pixelflux-2.1.0-cp312-cp312-musllinux_1_2_aarch64.whl
Size 24.4 MB
Tags CPython 3.12 Linux musl 1.2+ ARM64
SHA-256 checksum
How to use checksums
9d25c6acc5e0b3fa5971c3549e50994d7d3e5bfbba4dca442e92406808009f29
BLAKE2b-256 checksum
How to use checksums
37d96014f30a1c3c53cc5ad38867083735a3b26df25eb68871c6d8f0baccc122
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 23, 2026.

Transparency log

Release files / pixelflux-2.1.0-cp312-cp312-manylinux_2_28_x86_64.whl

Download URL pixelflux-2.1.0-cp312-cp312-manylinux_2_28_x86_64.whl
Size 25.8 MB
Tags CPython 3.12 Linux glibc 2.28+ x86-64
SHA-256 checksum
How to use checksums
776bb8e80970a2d07d391cf043b77a6cb203cfdff565dd43713dd07ce9bdf257
BLAKE2b-256 checksum
How to use checksums
3efbdd74a31d99fa8311b26b781b306aed1c2d3941ee5b021a28f1cb131593e2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 23, 2026.

Transparency log

Release files / pixelflux-2.1.0-cp312-cp312-manylinux_2_28_aarch64.whl

Download URL pixelflux-2.1.0-cp312-cp312-manylinux_2_28_aarch64.whl
Size 24.0 MB
Tags CPython 3.12 Linux glibc 2.28+ ARM64
SHA-256 checksum
How to use checksums
b2627fc29cc541b587ff09261a6a95479c549e4f95609f9789a7bf08f79e10b1
BLAKE2b-256 checksum
How to use checksums
88b48f010924720b83e91cf5767e2a13e2ed74cabab626fbff8d1a1c46f886e1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 23, 2026.

Transparency log

Release files / pixelflux-2.1.0-cp311-cp311-musllinux_1_2_x86_64.whl

Download URL pixelflux-2.1.0-cp311-cp311-musllinux_1_2_x86_64.whl
Size 26.2 MB
Tags CPython 3.11 Linux musl 1.2+ x86-64
SHA-256 checksum
How to use checksums
eba0d56ad95e78643d657fbf36c75c128df654f1bb0cb16516da319dc1539f7c
BLAKE2b-256 checksum
How to use checksums
414464a88088689f47ad3d39e266a7d989844d9250206741f3608a3621218818
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 23, 2026.

Transparency log

Release files / pixelflux-2.1.0-cp311-cp311-musllinux_1_2_aarch64.whl

Download URL pixelflux-2.1.0-cp311-cp311-musllinux_1_2_aarch64.whl
Size 24.4 MB
Tags CPython 3.11 Linux musl 1.2+ ARM64
SHA-256 checksum
How to use checksums
d6abdbb5715a44a4e8f626484e2b43adb52e3357644e8c3d007ea51eba2b4308
BLAKE2b-256 checksum
How to use checksums
a5146a2186834fe8d66e9c35d141e6a12c320589b246762d84df2a9100bc8228
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 23, 2026.

Transparency log

Release files / pixelflux-2.1.0-cp311-cp311-manylinux_2_28_x86_64.whl

Download URL pixelflux-2.1.0-cp311-cp311-manylinux_2_28_x86_64.whl
Size 25.8 MB
Tags CPython 3.11 Linux glibc 2.28+ x86-64
SHA-256 checksum
How to use checksums
36a594b25005405eae09fdbfaf66d3c83caae9bc42a834624dfc64fa4e8434d4
BLAKE2b-256 checksum
How to use checksums
670532287a5be4bef74d5c7b63d3cd57a71b84bb1148be8d83a3c307627728b5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 23, 2026.

Transparency log

Release files / pixelflux-2.1.0-cp311-cp311-manylinux_2_28_aarch64.whl

Download URL pixelflux-2.1.0-cp311-cp311-manylinux_2_28_aarch64.whl
Size 24.0 MB
Tags CPython 3.11 Linux glibc 2.28+ ARM64
SHA-256 checksum
How to use checksums
c2e69ac66e599eb340e827c4d1e730638cc4165e67954e386cc53632c2507d38
BLAKE2b-256 checksum
How to use checksums
1e1d3b83eed5f4cf541fb07678bfe385b937f8da018d1f674f19376e88d2f411
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 23, 2026.

Transparency log

Release files / pixelflux-2.1.0-cp310-cp310-musllinux_1_2_x86_64.whl

Download URL pixelflux-2.1.0-cp310-cp310-musllinux_1_2_x86_64.whl
Size 26.2 MB
Tags CPython 3.10 Linux musl 1.2+ x86-64
SHA-256 checksum
How to use checksums
a9ec6da44ec2269f181a099e7df924a6143f26632346569d2fb2ed6455cf0cf6
BLAKE2b-256 checksum
How to use checksums
7ad3933496e73631a1e133e7229226af6cb75beb412b955f25d60cd1c1d50991
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 23, 2026.

Transparency log

Release files / pixelflux-2.1.0-cp310-cp310-musllinux_1_2_aarch64.whl

Download URL pixelflux-2.1.0-cp310-cp310-musllinux_1_2_aarch64.whl
Size 24.4 MB
Tags CPython 3.10 Linux musl 1.2+ ARM64
SHA-256 checksum
How to use checksums
f79886f009b05a9ef4f940ba31877deae68c3db0e3cf97548183356d76d19bda
BLAKE2b-256 checksum
How to use checksums
fbfebc79ba5b0c682e8f8d1def644c1997451c548d7cb517115c84a16f21f459
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 23, 2026.

Transparency log

Release files / pixelflux-2.1.0-cp310-cp310-manylinux_2_28_x86_64.whl

Download URL pixelflux-2.1.0-cp310-cp310-manylinux_2_28_x86_64.whl
Size 25.8 MB
Tags CPython 3.10 Linux glibc 2.28+ x86-64
SHA-256 checksum
How to use checksums
6bb86a54bdde267934d9ccca41909255d2479db87c4effc3eb3ea673cc9b1f34
BLAKE2b-256 checksum
How to use checksums
13826ce7d02459e6b25ab16fb4295f7a132c63f57c422173e7e9bdc90986b6f0
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 23, 2026.

Transparency log

Release files / pixelflux-2.1.0-cp310-cp310-manylinux_2_28_aarch64.whl

Download URL pixelflux-2.1.0-cp310-cp310-manylinux_2_28_aarch64.whl
Size 24.0 MB
Tags CPython 3.10 Linux glibc 2.28+ ARM64
SHA-256 checksum
How to use checksums
8e844ea57f1e8b62e9b712dd59ad5a2e33c9c0572fe6eeef08ba98189367b102
BLAKE2b-256 checksum
How to use checksums
f610e85b6370b474ec176d2a1cfed844ba8b8f16bd060710530bba7ac2bfa718
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 23, 2026.

Transparency log

Release files / pixelflux-2.1.0-cp39-cp39-musllinux_1_2_x86_64.whl

Download URL pixelflux-2.1.0-cp39-cp39-musllinux_1_2_x86_64.whl
Size 26.2 MB
Tags CPython 3.9 Linux musl 1.2+ x86-64
SHA-256 checksum
How to use checksums
7d50bfd42cbb6ec363cc7f7d245e2e9e16eac18919578ef9ada417fc95910474
BLAKE2b-256 checksum
How to use checksums
3920e2e0d30130c4f261818497df1defade3c75b455dd0eeed8a12dfce1e3190
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 23, 2026.

Transparency log

Release files / pixelflux-2.1.0-cp39-cp39-musllinux_1_2_aarch64.whl

Download URL pixelflux-2.1.0-cp39-cp39-musllinux_1_2_aarch64.whl
Size 24.4 MB
Tags CPython 3.9 Linux musl 1.2+ ARM64
SHA-256 checksum
How to use checksums
8482571dcef0cfd8345fd61b5ae1ef921fb32492c67a495dddbfc4b0d2293bc3
BLAKE2b-256 checksum
How to use checksums
8186e39b5e9e6e160f6c2b8675a1564d24388104b6f963fc3de89ca8f97e377b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 23, 2026.

Transparency log

Release files / pixelflux-2.1.0-cp39-cp39-manylinux_2_28_x86_64.whl

Download URL pixelflux-2.1.0-cp39-cp39-manylinux_2_28_x86_64.whl
Size 25.8 MB
Tags CPython 3.9 Linux glibc 2.28+ x86-64
SHA-256 checksum
How to use checksums
1f8b789d5d69e5160b42524d06d8b6a564a23bbfde61d7beaf00a2af23996b30
BLAKE2b-256 checksum
How to use checksums
dea3aa60f1649762f8df0824c67c5d392bcd843c18c44ed6757a64cb35bfc39b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 23, 2026.

Transparency log

Release files / pixelflux-2.1.0-cp39-cp39-manylinux_2_28_aarch64.whl

Download URL pixelflux-2.1.0-cp39-cp39-manylinux_2_28_aarch64.whl
Size 24.0 MB
Tags CPython 3.9 Linux glibc 2.28+ ARM64
SHA-256 checksum
How to use checksums
d5a3f1420f3004a15546a872949a64666f8693eb0d32801c436431a96c019786
BLAKE2b-256 checksum
How to use checksums
4aac550cfeb18a397fe73772460092ee3fb501f46782bf4c938c139dddcaa8b7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 23, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

2.1.0 This release

28 release files

2.0.0

24 release files

1.6.2

32 release files

1.6.0

32 release files

1.5.9

32 release files

1.5.8

32 release files

1.5.6

32 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page