Fetch a run's artifacts from the CLI

`save_artifact` had no download counterpart: the run detail listed a run's
files and nothing in `fluksio --help` fetched one. `fluksio artifacts RUN`
lists them, `fluksio artifacts RUN NAME` writes one — under the name the
node saved it as, since the message name is chosen for the graph. The run
detail now carries that filename, which it held in the table and did not
report.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019Hra4ndWMCLU5F3KjUuVAc
This commit is contained in:
2026-08-29 13:48:23 +02:00
co-authored by Claude Opus 5
parent 73cd37a608
commit 9286573f38
3 changed files with 93 additions and 0 deletions
+37
View File
@@ -390,6 +390,43 @@ def test_the_metric_names_are_asked_for_rather_than_guessed() -> None:
assert _list_names(Engine(), args) == 0
def test_a_runs_artifact_is_listed_and_downloaded(tmp_path, monkeypatch) -> None:
"""`save_artifact` had no counterpart: the bytes were API-only."""
from fluksio.cli import _parser
from fluksio.sdk.cli import _artifacts
row = {
"name": "weights",
"node": "fit",
"digest": "sha256:abc",
"size": 3,
"media_type": "application/octet-stream",
"filename": "weights.npz",
}
class Engine:
def run(self, run_id):
assert run_id == "r-1"
return {"id": run_id, "status": "ok", "artifacts": [row]}
def download(self, digest):
assert digest == "sha256:abc"
return b"abc"
parser = _parser()
monkeypatch.chdir(tmp_path)
assert _artifacts(Engine(), parser.parse_args(["artifacts", "r-1"])) == 0
# Written under the name the node saved it as, not the message's.
assert _artifacts(Engine(), parser.parse_args(["artifacts", "r-1", "weights"])) == 0
assert (tmp_path / "weights.npz").read_bytes() == b"abc"
args = parser.parse_args(["artifacts", "r-1", "weights", "-o", "here.bin"])
assert _artifacts(Engine(), args) == 0
assert (tmp_path / "here.bin").read_bytes() == b"abc"
def test_an_engine_without_the_route_is_named_rather_than_404() -> None:
"""A client ships ahead of the engine; a flat 404 does not say so."""
from fluksio.sdk.cli import _too_old