Files
dora-image-view/AGENTS.md
T
cristhianandClaude Opus 5 22bd1e9e89
validate / dataflow (pull_request) Failing after 59m9s
validate / test (pull_request) Successful in 59m8s
add an in-repo synthetic source so the example needs no network
The example dataflow pulled opencv-video-capture and pyarrow-sender from
dora-hub, needed a webcam, and left `bbox` unwired because every bbox source
is a detector. examples/source.py emits an animated frame, the box around the
square in it, and a caption, so the dataflow exercises all three inputs with
nothing outside this checkout.

SOURCE_FRAMES bounds the run, which lets CI run the dataflow headless rather
than only validate it. Drops the dora-zed and dora-yolo wirings from the
README and trims AGENTS.md to what the code and README do not already say.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018WLVZCFFcCH1EpTXGfS9aD
2026-09-14 16:09:01 -05:00

4.6 KiB

AGENTS.md

This file provides guidance to AI coding assistants when working with code in this repository.

What this is

A dora-rs Python node that displays a video stream with overlays: it keeps a current frame, bbox set and text string, and every image event redraws all three into an OpenCV window. It is a display sink — it produces no outputs. README.md documents the inputs, the encodings and the environment variables; this file covers only what the code and the README do not say.

Everything the example dataflow needs is in this checkout. Do not reintroduce a dependency on another repository — the example must keep running with no camera, no detector and no network.

It is Python on purpose. The node was first written in Rust against the opencv crate; that crate generates its bindings from the OpenCV headers installed on the build machine, so it needs libopencv-dev and libclang-dev on every machine and every architecture and does not cross-compile. Every dependency here ships prebuilt wheels for linux-x86_64, linux-aarch64 and macos-arm64, so uv sync is the whole install. Do not reintroduce a dependency that has to be compiled from source.

Commands

uv sync --group dev                      # deps plus pytest and ruff
uv run pytest && uv run ruff check .     # no camera/dataflow/display needed
dora run dataflow.yml --uv               # the example, in a window
CI=true SOURCE_FRAMES=30 dora run dataflow.yml --uv   # the same, headless

dora build --uv / dora run --uv rewrites each manifest's build: pip install . to uv pip install . and gives the node its own managed venv under .dora/python-envs/<node-id>/, so what it imports at runtime is what was installed at build time.

Architecture

  • dora_plot/main.py — Argument parsing and the dora event loop, nothing else. The env var wins over the CLI flag for PLOT_WIDTH/PLOT_HEIGHT, matching the upstream node. Node(args.name) rather than Node() so the node also runs standalone as a dynamic node.
  • dora_plot/decode.py — to_bgr(): every supported encoding to a writable BGR array. Two behaviours are deliberate, not bugs: bgr8 copies (the payload may be a read-only view on shared memory, and the frame is annotated in place), and yuv420 converts with COLOR_YUV420p2RGB rather than ...2BGR — the upstream node converts to RGB and then displays it as BGR, and that channel swap is part of the behaviour callers already see.
  • dora_plot/plot.py — Plot (the overlay state and the window) and Bboxes. headless (from CI=true) skips only the window: every input is still decoded, which is what makes the node safe in a pipeline test.
  • dora_plot/bbox.py — Parses the bbox struct into xyxy corners. xywh is centre-based (x, y are the box centre). _flat() unwraps the single-element list that pa.array([{...}]) produces around each field, and reads a field stored flat as-is.
  • examples/source.py — The synthetic source node: an animated frame, the box around the square in it, and a caption. It exists so the example dataflow exercises all three inputs without a camera or a detector, and so CI can run the dataflow rather than only validate it. SOURCE_FRAMES bounds the run, which is what lets CI wait for a clean exit instead of killing it on a timeout.
  • dora-node.yml — Node manifest (apiVersion: 1). dora validate injects these types into any dataflow that reaches the node by path:; a git:-sourced node does not pick it up, which is why the example builds from the checkout. image and text carry type URNs naming the element type because each payload is a raw buffer described by its metadata, not an Arrow struct. bbox is deliberately untyped: senders disagree on whether its numeric fields are 32- or 64-bit, and the node reads either.
  • dataflow.yml — The example and the CI gate, with strict_types: true. source carries output_types: because it has no manifest of its own; bbox is annotated on neither side, matching the manifest.
  • .gitea/workflows/validate.yml — CI: validates and runs the dataflow headless, and runs the unit tests. Needs no camera and no display.

A caveat on typed optional inputs

dora validate --strict injects a contract type for every typed manifest input and then warns input_types key "..." not found in inputs list for any the dataflow does not wire. So a typed optional input forces the example dataflow to wire it. If a typed input is added to the manifest, either wire it in dataflow.yml or leave it untyped.

Rules

  • Do not mention AI tools in commit messages or documentation.