Command-line interface¶
flowbio exposes the Flow upload operations from the terminal, for both
humans (concise lines) and automated agents (--json output with stable exit
codes). It is a thin layer over the flowbio.v2.Client — anything the
CLI does, the library can do programmatically.
flowbio <resource> <verb> [options]
flowbio --version
flowbio [--help | <resource> --help | <resource> <verb> --help]
Resources are data, samples, and api. Run flowbio --help,
flowbio <resource> --help, or flowbio <resource> <verb> --help for
self-documenting usage at every level.
Authentication¶
Credentials are resolved in this order (highest priority first):
--login— force an interactive username/password login.--token TOKEN, or theFLOW_API_TOKENenvironment variable — use this token directly.--token-file PATH, or theFLOW_TOKEN_FILEenvironment variable — read the token from this file.The default token file
~/.config/flow/api-token— used only when none of the above is supplied.An interactive username/password prompt (TTY only).
The base URL is resolved as --base-url URL > the FLOW_API_URL
environment variable > the library default (https://app.flow.bio/api). For
both tokens and the base URL, an explicit flag always beats the environment
variable, which beats the default.
The password is only ever read from an interactive prompt — never from a
flag or environment variable. If a prompt would be required but stdin is not a
terminal (e.g. in a non-interactive pipeline), the command fails fast with exit
code 2 rather than hanging.
A named token file (--token-file/FLOW_TOKEN_FILE) that is missing or
empty, and combining --token with --login, are both usage errors
(exit 2).
Output modes¶
Mode |
stdout |
stderr |
|---|---|---|
Human (default) |
concise result lines |
progress, advisories, errors |
|
exactly one JSON document |
a JSON error document on failure |
Under --json, stdout carries a single document and nothing else, so it can
be piped straight into a parser. On error, a JSON document is written to
stderr carrying message and, where applicable, a status_code.
Global options are accepted identically before and after the verb:
flowbio --json data upload ./counts.tsv and
flowbio data upload ./counts.tsv --json are equivalent.
Progress is shown on stderr during uploads; pass --no-progress to disable
it.
Exit codes¶
Code |
Meaning |
|---|---|
|
Success |
|
API/runtime error (including a batch with any failed upload) |
|
Usage / configuration / input error (including batch pre-flight failure, non-CSV sheet) |
|
Authentication failed |
|
Not found |
|
Bad request / validation error |
The server is the source of truth: values such as --data-type are sent
as-is and validated server-side, surfacing as exit 5 on rejection.
Commands¶
data upload¶
Upload a generic data file.
flowbio data upload PATH [--filename NAME] [--data-type TYPE] [--directory]
Run flowbio data upload --help for the full option list. Note that
--data-type is sent as-is and validated server-side — the CLI does not
pre-check it.
Output — human: a confirmation line with the data identifier on stdout.
--json: {"id": "<data_id>"} on stdout.
Exit codes — 0 success; 5 server rejection (e.g. an unknown data
type or a filename containing spaces); 3 authentication failure; otherwise
the standard mapping above.
Example
$ flowbio data upload ./counts.tsv
Uploaded data data_xyz
$ flowbio data upload ./counts.tsv --json
{"id": "data_xyz"}
samples upload¶
Upload a single demultiplexed sample — single-ended (--reads1) or
paired-end (add --reads2).
flowbio samples upload --name NAME --sample-type TYPE --reads1 PATH
[--reads2 PATH] [--project ID] [--organism ID]
[--metadata KEY=VALUE ...] [--metadata-json JSON]
Run flowbio samples upload --help for the full option list. The sample type
is sent as-is and validated server-side.
Metadata can be supplied two ways, which are merged:
--metadata KEY=VALUE, repeatable. The split is on the first=, so a value may itself contain=(--metadata formula=a=b+c).--metadata-json '{"identifier": "value", ...}', a single JSON object — handy for an agent that already holds a dictionary. Values must be strings; a non-string value is a usage error (exit2).
Supplying the same key through both is a usage error (exit 2) raised before
any upload. A free-text annotation companion to an attribute is an ordinary key
of the form <identifier>__annotation, passed through unchanged.
Output — human: a confirmation line with the sample identifier on stdout.
--json: {"id": "<sample_id>"} on stdout.
Exit codes — 0 success; 2 conflicting metadata keys; 5 server
rejection (e.g. an unknown sample type or missing required metadata); 3
authentication failure; otherwise the standard mapping above.
Example
$ flowbio samples upload --name liver_r1 --sample-type RNA-Seq \
--reads1 ./liver_R1.fastq.gz --reads2 ./liver_R2.fastq.gz \
--metadata strandedness=reverse
Uploaded sample samp_abc
$ flowbio samples upload --name liver_r1 --sample-type RNA-Seq \
--reads1 ./liver_R1.fastq.gz --json
{"id": "samp_abc"}
samples annotation-template¶
Download the server-generated annotation sheet template for a sample type, to
fill in before samples upload-multiplexed.
flowbio samples annotation-template [--sample-type TYPE] [-o PATH | --output PATH]
The template is an Excel workbook (.xlsx) keyed by metadata-attribute
display names. It is a different artefact from the batch sample sheet (the
CLI-built CSV used by upload-batch) and the two are not interchangeable.
--sample-type is optional and defaults to generic (the base columns
shared by all types); a type-specific value adds that type’s metadata columns.
It is sent as-is and validated server-side.
The body is a binary workbook, so -o/--output PATH is required — it is
never written to stdout (which carries human result lines or the single JSON
document).
Output — human: the workbook is written to --output; a confirmation
(path and sample type) goes to stderr, leaving stdout empty. --json:
{"output": "<path>", "sample_type": "<type>"} on stdout — never the
spreadsheet bytes.
Exit codes — 0 success; 2 no --output, or an unwritable output
path; 4 unknown sample type; 3 authentication failure; otherwise the
standard mapping above.
Example
$ flowbio samples annotation-template --sample-type RNA-Seq -o sheet.xlsx
Wrote RNA-Seq annotation template to sheet.xlsx
$ flowbio samples annotation-template --sample-type RNA-Seq -o sheet.xlsx --json
{"output": "sheet.xlsx", "sample_type": "RNA-Seq"}
samples upload-multiplexed¶
Upload multiplexed reads plus a completed annotation sheet for server-side
demultiplexing — single-ended (--reads1) or paired-end (add --reads2).
flowbio samples upload-multiplexed --reads1 PATH --annotation PATH
[--reads2 PATH] [--reject-warnings]
The annotation sheet is the filled-in workbook from annotation-template. By
default annotation warnings are reported but the upload proceeds;
--reject-warnings makes warnings reject it.
Output — human: a confirmation line with the data identifiers and
annotation identifier on stdout, with any warnings on stderr. --json:
{"data_ids": [...], "annotation_id": "<id>", "warnings": [...]} on stdout.
Exit codes — 0 success (including with reported warnings); 5
annotation fails server validation, or warnings with --reject-warnings;
3 authentication failure; otherwise the standard mapping above.
Example
$ flowbio samples upload-multiplexed --reads1 ./mux_R1.fastq.gz \
--annotation ./sheet.xlsx
Uploaded multiplexed data mux_1 with annotation ann_1
$ flowbio samples upload-multiplexed --reads1 ./mux_R1.fastq.gz \
--annotation ./sheet.xlsx --json
{"data_ids": ["mux_1"], "annotation_id": "ann_1", "warnings": []}
samples batch-template¶
Emit a sample-sheet template for a sample type, to fill in and feed to
samples upload-batch.
flowbio samples batch-template --sample-type TYPE [-o PATH | --output PATH]
Run flowbio samples batch-template --help for the full option list. The
sample type decides which metadata columns are marked required. It is validated
against the available types up front: an unrecognised type fails with a usage
error (exit 2) listing the valid identifiers.
Sample-sheet schema — the columns, in order:
The reserved columns
name,reads1,reads2,project,organism(nameandreads1are always required;reads1/reads2are reads file paths).One column per metadata attribute, keyed by its identifier. An attribute is required when it is globally required or required for the chosen sample type.
A
<identifier>__annotationcompanion column immediately after each attribute that permits a free-text annotation.
There is no sample_type column — the type is supplied via
--sample-type to both this command and upload-batch. This CSV is
distinct from the annotation sheet produced by samples annotation-template.
Output — human: the CSV header row on stdout (or written to --output),
plus a summary of required-vs-optional columns on stderr. --json: a
per-column descriptor list on stdout (name, kind of reserved/
metadata/annotation, required, closed-value options or
null, and description) and no CSV — so an agent can build rows
directly.
Exit codes — 0 success; 2 missing --sample-type, or an unknown
sample type (the error lists the available types); 3 authentication
failure; otherwise the standard mapping above.
Example
$ flowbio samples batch-template --sample-type RNA-Seq
name,reads1,reads2,project,organism,cell_type,source,source__annotation
$ flowbio samples batch-template --sample-type RNA-Seq --json
[{"name": "name", "kind": "reserved", "required": true, "options": null, "description": "..."}, ...]
samples upload-batch¶
Upload many samples from a filled-in CSV sample sheet, applying one sample type to every row.
flowbio samples upload-batch --sheet PATH --sample-type TYPE
[--skip-invalid] [--stop-on-error]
Run flowbio samples upload-batch --help for the full option list. The sheet
is the CSV produced by samples batch-template (see that command for the
schema); it must be a .csv — an .xlsx or .tsv is a usage error
directing you to export to CSV. Reads paths in the sheet are resolved relative
to the sheet file’s own directory (absolute paths are used as-is), and
empty cells are omitted rather than sent as empty values. The sample type is
sent as-is and validated server-side.
Validation is up front. Every row is validated before any upload, and all
problems on a row are reported together — a missing name/reads1, a
reads file that is not on disk, a name containing spaces, a value outside a
closed-option attribute’s allowed values, metadata required for the chosen type
that is missing, or a <identifier>__annotation companion set without its
value or on an attribute that does not permit annotations.
By default, any invalid row aborts the whole run: every row’s errors are reported (with its 1-based row number and name), nothing is uploaded, exit
2.--skip-invalidskips the invalid rows (reporting why) and uploads the rest.
Valid rows upload sequentially in sheet order. By default a row that fails
to upload is recorded and the run continues; --stop-on-error aborts on the
first failing row, reporting the rows already uploaded.
Output — human: each row’s outcome on stderr, then a final counts summary
on stdout. --json: a single document on stdout with uploaded,
failed, and skipped lists plus a counts summary:
{
"uploaded": [{"row_number": 1, "name": "s1", "sample_id": "samp_1"}],
"failed": [{"row_number": 2, "name": "s2", "message": "..."}],
"skipped": [{"row_number": 3, "name": "s3", "reasons": ["..."]}],
"counts": {"uploaded": 1, "failed": 1, "skipped": 1}
}
Exit codes — 0 every row uploaded; 2 a pre-flight validation failure
(without --skip-invalid) or a non-CSV sheet; 1 any upload failure; 3
authentication failure; otherwise the standard mapping above.
Example
$ flowbio samples upload-batch --sheet ./samples.csv --sample-type RNA-Seq
Row 1 (liver_r1): uploaded samp_1
Row 2 (liver_r2): uploaded samp_2
Uploaded 2, failed 0, skipped 0.
$ flowbio samples upload-batch --sheet ./samples.csv --sample-type RNA-Seq --json
{"uploaded": [{"row_number": 1, "name": "liver_r1", "sample_id": "samp_1"}], "failed": [], "skipped": [], "counts": {"uploaded": 1, "failed": 0, "skipped": 0}}
api get¶
Issue a GET to any path under the Flow API base URL and print the raw
response body to stdout. It is a read-only passthrough — it never changes
remote state.
flowbio api get PATH [--param KEY=VALUE ...]
Query values are supplied only through --param (repeatable), which
URL-encodes each value; a ? in PATH is rejected as a usage error
directing you to --param instead.
Unlike the upload commands, api get does not require credentials. When a
token is available it is used (following the standard precedence above — with
a token file at ~/.config/flow/api-token, no flags are needed) and the
response includes any private resources you can see; when no token is
present, the request is made anonymously and returns only public resources.
Pass --login to force authentication.
Output — a successful response body is written verbatim to stdout in
both human and --json mode; --json does not reshape it. Errors always
go to stderr (never stdout, so a piped stdout stays clean) regardless of
mode: by default as an Error: <message> line, or — under --json — as a
{"message": ..., "status_code": ...} document.
Exit codes — 0 success; 2 usage error (e.g. a ? in PATH);
3 authentication failure; 4 not found; 5 bad request; otherwise the
standard mapping above.
Example
$ flowbio api get /samples/search --param name=rna-seq --param count=100 | jq '.count'
42