Benchmark reporting uses a staged handoff:
raw run JSON -> jsonl_bundle/ -> report_data.json -> benchmark_report.html
The current implementation does not use DuckDB as an intermediate artifact.
input CSV (id, workspace, group, logs, fusion)
-> branch: api (SeqeraApi.fetchRunData) | external (EXTRACT_TARBALL)
-> collect JSON files
-> NORMALIZE_BENCHMARK_JSONL (raw JSON -> jsonl_bundle/)
-> AGGREGATE_BENCHMARK_REPORT_DATA (jsonl_bundle -> report_data.json)
-> RENDER_BENCHMARK_REPORT (report_data.json -> benchmark_report.html)
- API runs (
workspace != external) are fetched viaSeqeraApi.fetchRunData() - External runs (
workspace == external) are read from directory/tarball logs - Tarball inputs pass through
EXTRACT_TARBALLbefore merge
Command:
python bin/benchmark_report.py normalize-jsonl --data-dir <run_json_dir> --output-dir <jsonl_bundle>
python bin/benchmark_report.py normalize-jsonl --data-dir <run_json_dir> --costs <cur.parquet> --cost-label-map <cur_label_map.yml> --output-dir <jsonl_bundle>Responsibilities:
- read run JSON payloads
- normalize runs/tasks/metrics rows
- optionally normalize CUR parquet into
costs.jsonl - write:
runs.jsonltasks.jsonlmetrics.jsonl- optional
costs.jsonl
Command:
python bin/benchmark_report.py aggregate-report-data --jsonl-dir <jsonl_bundle> --output <report_data.json>Responsibilities:
- stream JSONL rows
- compute report sections:
benchmark_overviewrun_summaryrun_metricsrun_costsprocess_statstask_instance_usagetask_tabletask_scatter- optional
cost_overview
Command:
python bin/benchmark_report.py render-html --data <report_data.json> --output <benchmark_report.html>Responsibilities:
- load report JSON
- apply brand/logo overrides when provided
- render self-contained HTML from the Jinja template
bin/benchmark_report.py provides:
normalize-jsonlaggregate-report-datarender-htmlreport(aggregate + render convenience wrapper)fetch(standalone API fetch helper)
id,workspace,group,logs
4Bi5xBK6E2Nbhj,community/showcase,GroupA,
1JI5B1avuj3o58,external,GroupB,/path/to/run_dumps.tar.gzresults/benchmark_report/
benchmark_report.html
report_data.json
jsonl_bundle/
uv run --with typer --with pyyaml --with pyarrow \
python bin/benchmark_report.py normalize-jsonl \
--data-dir /path/to/json_data --output-dir /tmp/jsonl_bundle
uv run --with typer --with pyyaml --with pyarrow \
python bin/benchmark_report.py normalize-jsonl \
--data-dir /path/to/json_data \
--costs /path/to/cur.parquet \
--cost-label-map /path/to/cur_label_map.yml \
--output-dir /tmp/jsonl_bundle
uv run --with typer --with pyyaml \
python bin/benchmark_report.py aggregate-report-data \
--jsonl-dir /tmp/jsonl_bundle --output /tmp/report_data.json
uv run --with jinja2 --with typer --with pyyaml \
python bin/benchmark_report.py render-html \
--data /tmp/report_data.json --brand assets/brand.yml --output /tmp/report.htmluv run --with typer --with pyyaml --with jinja2 --with pyarrow --with pytest --with httpx \
pytest -v \
modules/local/aggregate_benchmark_report_data/tests/test_aggregate.py \
modules/local/normalize_benchmark_jsonl/tests/test_normalize.py \
modules/local/render_benchmark_report/tests/test_render.py \
bin/test_benchmark_report_fetch.py
nf-test test --profile=+docker --verbose- JSONL is the primary handoff for streaming-friendly processing.
report_data.jsonis the explicit boundary between aggregation and rendering.- CUR join key uses
(run_id, process, hash_short)to avoid collisions.