feat(cli): add samples upload-batch from a CSV sample sheet#16
Conversation
Implements User Story 4 (Phase 7) of the flowbio CLI: upload many samples from a CSV sample sheet, applying one sample type to every row. Adds `flowbio/cli/_sheet.py` — CSV-only parsing that separates reserved columns from metadata identifiers, resolves reads paths relative to the sheet's own directory, drops empty cells, and collects every per-row pre-flight error up front (missing required values, reads files not on disk, names with spaces, closed-option violations, required-for-type metadata, and annotation-companion rules) so a batch never half-uploads before surfacing a fixable mistake. Adds the `upload-batch` handler and `_BatchResult` to `_samples.py`: validate all rows first, then upload the valid rows sequentially in sheet order. `--skip-invalid` skips invalid rows instead of aborting; `--stop-on-error` aborts on the first upload failure. Exit codes follow the contract — 0 all uploaded, 2 pre-flight failure (or non-CSV sheet), 1 any upload failure — and `--json` emits the uploaded/failed/skipped/counts document on stdout while the pre-flight abort writes a JSON error document to stderr. The `__annotation` suffix is now a single shared constant in `_sheet.py`, used by both the batch-template producer and the sheet parser so the sheet round-trips without silent divergence. Sample type is sent as-is (validated server-side), consistent with the CLI's "server is source of truth" convention. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
@claude please review this PR |
|
Claude finished @mhusbynflow's task in 2m 3s —— View job PR Review:
|
Spreadsheet tools — notably Excel's "CSV UTF-8" export — prepend a UTF-8 BOM. parse_sheet opened the file with the default encoding, so the BOM survived and the first header parsed as "name"; that fell out of the reserved-column set, so `name` was treated as a metadata column and every row reported "missing required value: name" on the documented happy path (fill in the template in a spreadsheet, export to CSV). Open with utf-8-sig, which transparently strips a leading BOM and is otherwise identical to UTF-8. Also wrap the closed-option validation condition to match the file's wrap style. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
What changed
Implements User Story 4 (Phase 7) of the flowbio CLI —
flowbio samples upload-batch --sheet x.csv --sample-type T: upload many samples from a CSV sample sheet, applying one sample type to every row.flowbio/cli/_sheet.py(new) — CSV-only parsing: separates reserved columns (name,reads1,reads2,project,organism) from metadata identifiers, resolves reads paths relative to the sheet's own directory, drops empty cells, andvalidate_row()collects all per-row pre-flight errors up front (missing required values, reads files not on disk, names with spaces, closed-option violations, required-for-type metadata, annotation-companion rules).flowbio/cli/_samples.py—upload-batchhandler +_BatchResult: validate every row before any upload, then upload valid rows sequentially in sheet order.--skip-invalidskips invalid rows instead of aborting;--stop-on-erroraborts on the first upload failure. The__annotationsuffix is now a single shared constant used by both the batch-template producer and the sheet parser.docs/cli.md—samples upload-batchsection (concepts + worked example).Exit-code / output contract
0all uploaded ·2pre-flight validation failure or non-CSV sheet ·1any upload failure.--jsonemits the{uploaded, failed, skipped, counts}document on stdout; the pre-flight abort writes a JSON error document to stderr with stdout empty.Verification
tests/unit/cli/test_sheet.py(17) +TestSamplesUploadBatchintest_samples.py(10, covering all 7 US4 scenarios incl. JSON-mode abort).--sample-type", and unified the__annotationsuffix constant.Out of scope
flowbio/v2library changes.🤖 Generated with Claude Code