Export runs and their curves as tables an analysis reads

`fluksio export metrics` is the long table — a row per run, metric and step —
and `fluksio export runs` the wide one, a row per run with the inputs that
*vary* across the selection as columns beside its final numbers, status,
duration and the commit and digest of the code it ran. Both carry the run id
on every row, which is the join back to the run page and what makes an
exported file auditable. `Client.export_metrics`/`export_runs` answer the same
rows to a notebook.

The engine streams csv or jsonl from two routes declared above `/{run_id}`;
parquet is a client-side conversion behind the new `fluksio[parquet]` extra,
so nobody pays for pyarrow who does not want dtypes kept. The long export
reads each run through `_series`, so a cached node's curve comes with it, and
`--stride` thins each series rather than the concatenation of all of them.

Two things they needed on the way: `GET /runs` takes `?since=` and `?before=`,
so a long history pages by the last row's own timestamp instead of an offset
that shifts under it; and a read that reaches no engine now says so in half a
second rather than seven, because `runs`, `flavors`, `export` and an unwatched
`status` pass `retries=0`. Everything that submits keeps them.
This commit is contained in:
2026-08-27 17:43:30 +02:00
parent dc2714f740
commit 8f66b6f90b
12 changed files with 813 additions and 9 deletions
+16
View File
@@ -605,6 +605,22 @@ curl -s "$FLUKSIO/runs/series/compare?ids=$A,$B,$C&metric=train.loss" \
which answers in exactly the shape a chart widget draws.
## Take it into a dataframe
The analysis itself wants a table, and `export` writes the two an analysis
asks for — the curves long, and one row per run with the parameters that
varied beside its final numbers:
```sh
fluksio export metrics --flow train --name train.loss -o curves.csv
fluksio export runs --flow train --status ok -o arms.csv
```
Both carry the run id on every row, and `arms.csv` carries the commit and the
code digest beside it, so an exported file still says what produced its
numbers. `Client.export_metrics()` and `Client.export_runs()` answer the same
rows to a notebook, ready for `pandas.DataFrame`.
## Looking at them in the portal
None of the above needs a browser, but there is one. **Runs** is the table of