Record code runs with pull, commit and push - #4
Conversation
Implement the recorded code run workflow from issue #2: - dat pull <path>: unidirectional rclone copy from DATA into RUN - dat commit -m <message>: write title/body plus automatic info (status running, start time) to metadata.json in eLabFTW standard and create a database entry with status running - dat push: set status finished, update the database and unidirectionally copy RUN to DATA via rclone Add pytest coverage for pull, commit and push, including message parsing, status transitions and the rclone syncs.
|
Review verdict: Request changes Summary: The workflow is broadly implemented, but the eLabFTW metadata layout and push failure handling contain release-blocking correctness issues. No CI runs were available, and local pytest could not run because pytest is not installed. Findings:
Verdict: Request changes — the core metadata persistence and push consistency guarantees are not currently reliable. |
|
Review verdict: Request changes Summary: The workflow is mostly coherent, but Findings:
Verdict: Request changes — |
|
Review verdict: Request changes Summary: The workflow is implemented and path/metadata fixes are present, but Findings:
Verdict: Request changes — failed pushes can falsely finalize runs and lose synchronization with DATA. |
Mark the run finished only after rclone_copy succeeds, so a failed transfer leaves the run state running and retryable instead of falsely finalizing runs that never reached DATA.
|
Review verdict: Request changes Summary: The PR adds the requested commands and basic tests, but several core acceptance and data-safety requirements remain unmet. GitHub reports no CI checks, and local tests cannot collect without Findings:
Verdict: Request changes — the current implementation can overwrite data and persist incorrect run status, while the eLabFTW dependency is obsolete. |
…adata, elabapi-python
There was a problem hiding this comment.
Review verdict: Request changes
Summary: This PR replaces the experimental elabapy interface with the official elabapi-python v2 client and turns dat into a pull/commit/push workflow: pull copies a path from DATA, commit -m records a running run, and push syncs results and marks the run finished. It replaces the unsafe globals()-lookup dispatch with an explicit COMMANDS whitelist, hardens pull against path traversal, adds rclone --ignore-existing/--immutable flags, and adds a 12-case test suite (all pass) with faked eLab storage and rclone. The design and tests are solid; the main defect is in the real eLabFTW authentication setup, invisible to the faked tests.
Findings:
-
[major] src/dat/journal.py:83-86 —
ElabStorage.__init__setsconfiguration.api_key["Authorization"] = ELAB_KEYbut never setsconfiguration.api_key_prefix["Authorization"] = "Bearer". The library'sget_api_key_with_prefix(confirmed in installed client) emits only the raw key without a prefix, so requests go out asAuthorization: <token>instead ofAuthorization: Bearer <token>. The official elabapi-python usage requires the Bearer prefix for eLabFTW v2; without it the server rejects (401) every request. Sincecommit/pushswallow eLab exceptions into aWarning:, the tool silently never mirrors to eLabFTW while reporting success. Fix: addconfiguration.api_key_prefix["Authorization"] = "Bearer"and add a test that the config is wired correctly. -
[minor] src/dat/dat.py:71-92 (commit) — If
elab.create()succeeds but the subsequentelab.save()fails, theidis never persisted locally, and a retry ofcommitcallscreate()again, leaving an orphaned/duplicate experiment on the server. Persist the id locally immediately aftercreate(). -
[minor] src/dat/journal.py:104-107 — Patching with
metadata=entry.get("metadata")replaces the whole server metadata body, overwriting eLabFTW-managed fields. UsingmetadatamergeonEntityEditableto merge onlyextra_fieldswould be non-destructive. -
[minor] tests/test_dat.py:207-213 —
test_unknown_command_exits_2is not robust:dat.main()alwayssys.exits, sodat.COMMANDS["os"]is dead code that never runs; the test passes only incidentally becausesys.argv[1]during pytest is an unrecognized token. Callmain()with a controlledsys.argv(["dat", "os"]) and assert the exit code, or drop the dead line.
Verdict: Request changes — the data-sync design, path hardening, and dispatch refactor are good, but the missing Bearer auth prefix means the eLabFTW mirroring (a core goal of this PR) silently fails against a real server, and the tests cannot catch it because ElabStorage is faked.
Closes #2
Problem
A scientist running a recorded code run needs commands to manage their
work across a local working directory (RUN) and long-term storage (DATA).
Issue #2 specifies a workflow where the current directory is RUN:
dat pull <path>— pull required inputs/templates from DATA to RUNslurm <run_code>)dat commit -m <message>— record the started run in the database withstatus
runningdat push— set statusfinished, update the database, and pushresults from RUN to DATA
Changes
dat pull <path>: unidirectional copy ofDATA/<path>into thecurrent directory via
rclone copy.dat commit -m <message>: writes the title (and optional body aftera newline) plus automatically retrieved information (status
running,start time) to
metadata.json, and creates a database entry with statusrunningthrough the eLabFTW API.dat push: sets statusfinished, records the finish time, updatesthe eLabFTW database entry, and unidirectionally copies the current
directory from RUN to DATA via rclone.
metadata.jsonusing the eLabFTW standard(
elabftw.extra_fields). DATA location is configurable viaDAT_DATA(file system path or rclone remote); eLabFTW credentials come from
ELAB_URL/ELAB_KEYenvironment variables.pull,commit, andpush, including messageparsing, the running/finished status transition, and the rclone syncs.
Tests
python -m pytest tests/ -q— 7 tests pass.