This release is a pre-release and may not be stable for production use.
bloomctl
Command-line tool for the Bloom Database (Salk Harnessing Plants Initiative) — log in, find cylinder experiments, download their images and metadata, and work with cylinder trait datasets.
Install
Releases are still pre-releases (0.1.0aN), so install by asking for the version by name:
uv tool install "bloomctl==0.1.0a6" # isolated CLI tool (recommended)
uvx bloomctl@0.1.0a6 --help # one-off, no install
pip install "bloomctl==0.1.0a6" # into the active environment
bloomctl --version
Don't add
--preor--prerelease=allow. Those flags aren't specific tobloomctl— they let every dependency install an unfinished dev version too.
Quickstart for Cylinder Image Downloads
# 1. Log in once (prompts for your Bloom email + password; saves to ~/.bloom)
bloomctl login
# 2. Find an experiment — pick a species from a menu, grab its id
bloomctl cyl experiments list --species-menu
# 3. Download it — by id, or just by name
bloomctl cyl download ./out --experiment-id 42
bloomctl cyl download ./out --experiment-name "drought 2024"
That writes ./out/scans.csv (metadata) and the per-frame images.
Downloads run 8 frames at a time. On a fast connection you can raise that:
bloomctl cyl download ./out --experiment-id 42 --workers 16 # up to 64
If a download stops part-way, run the same command again. It keeps whatever is already on disk and fetches only what is missing, so nothing is downloaded twice.
Every command takes -p/--profile to target a different login (default prod), and the list
commands take --output csv|json for machine-readable output.
Quickstart for Plate Image Downloads
Plate (GraviScan) experiments work the same way, with plate in place of cyl:
# 1. Log in once, if you have not already
bloomctl login
# 2. Download a whole plate experiment — by id, or just by name
bloomctl plate download ./gravi --experiment-id 12
bloomctl plate download ./gravi --experiment-name "gravitropism" --species Arabidopsis
That writes ./gravi/plates.csv and plate_sections.csv (metadata) and the plate images.
Narrow it down when you do not want the whole experiment:
bloomctl plate download ./gravi --experiment-id 12 --plate-id PLATE-001 # one plate
bloomctl plate download ./gravi --experiment-id 12 --wave-number 3 # one wave
bloomctl plate download ./gravi --experiment-id 12 --meta-only # csv only, no images
Start with --meta-only. A continuous plate session captures one image per plate per
cycle, so a multi-day experiment is thousands of files — the metadata tells you what you are
about to pull. --workers raises the download concurrency here too, and --limit fetches at
most that many scans, for looking at a sample — it is not a way to export an experiment in
parts, so give a sample and a full download separate directories.
Resume works as it does for cylinder downloads, and a little better: plate images record their size, so a file is skipped only when its size matches the database. A download truncated by a dropped connection is re-fetched rather than treated as complete.
plate downloadneeds thegravi_scans_extendedview on the server, andgravi_experiment_searchif you select by--experiment-name.
Commands
Find & download (any logged-in user):
| Command | What it does |
|---|---|
cyl experiments list |
List experiments (species · name · id); filter with --species NAME or --species-menu |
cyl accessions list |
Accessions in an experiment (--experiment-id, or pick from a menu) |
cyl accessions sample-counts |
Plant count per accession/species (--species NAME, or --species-menu) |
cyl datasets list / get |
List trait datasets (--experiment menu) / show one dataset's traits |
cyl qc list-sets |
List cylinder QC sets |
cyl download <dir> |
Download an experiment/scan:scans.csv + images. Select by --experiment-id, --scan-id, or --experiment-name |
plate download <dir> |
Download a plate (GraviScan) experiment/scan:plates.csv + plate_sections.csv + images. Same selectors, narrowed with --plate-id or --wave-number |
Pipeline (stage-in / write-back):
| Command | What it does |
|---|---|
cyl download-for-predict / batch-download-for-predict |
Stage scan(s) into the predict-ready layout |
cyl ingest-result / batch-ingest-result |
Write per-scan pipeline results back to Bloom*(needs write access)* |
cyl datasets create |
Create a trait dataset*(needs write access)* |
Run bloomctl <command> --help for the full options of any command.
The download log
Every cyl download writes download_log.txt next to scans.csv, with one line per frame and
a summary at the bottom. It is the file to send us if something looks wrong.
OK scan=1 frame=0 cyl-images/0.png
SKIP scan=1 frame=1 cyl-images/1.png
FAIL scan=1 frame=3 cyl-images/3.png error=[Errno 28] No space left on device
UNLISTED scan=5 (frame count unknown) error=...
NOFRAMES scan=7 (no images recorded for this scan)
Summary: 3/8 frames present (3 downloaded this run, 0 already on disk), 5 failed
| Status | What it means |
|---|---|
OK |
Downloaded during this run |
SKIP |
Already on disk, so it was not fetched again — this is a resumed run working |
FAIL |
This frame is missing; error= says why |
UNLISTED |
The scan's frame list could not be fetched, so an unknown number is missing |
NOFRAMES |
The scan has no images recorded in Bloom — nothing to download, not a failure |
A log full of SKIP is normal: it means every frame was already on disk from an earlier run.
UNLISTED is the one to look out for. A FAIL is a single missing frame, but an UNLISTED
scan means we do not know how many of its frames are missing — which is why a run can report
all its frames present and still be incomplete. Re-running picks up both.
The summary line ends with the reason when the run stopped for one, such as the disk filling up.
Run as a container
Prefer a container (e.g. a pipeline step) over a pip install? The same CLI is published to GHCR:
ghcr.io/salk-harnessing-plants-initiative/bloomctl
docker run --rm ghcr.io/salk-harnessing-plants-initiative/bloomctl:staging \
cyl ingest-result path/to/scan.result.json
Tags: :staging (latest staging build) · :<version> (matches the PyPI release of the same name) ·
:sha-<git-sha> (immutable, one per commit). Image provenance and build details are in the
repo docs.
Notes
- Species selector —
--species NAMEfilters by species (typed, scriptable);--species-menupicks from a menu. Same on every command; the two are mutually exclusive. - Interactive menus (
--species-menu,--experiment) need a terminal; in a pipe/CI they abort rather than guess. For scripting, pass the typed value/id and use--output json. - Read vs write — browsing/downloading works for any account; the write commands
(
ingest-result,datasets create) need an account with write access. -n/--workers— how many framescyl downloadfetches at once. Default8, maximum64,1for one at a time. Large experiments run tens of thousands of frames, and this is what makes them quick. More is not always better: if the server starts refusing requests you will see frames fail, and the fix is a lower number, not a higher one.- Resuming — a download that stops for any reason (interrupted, connection dropped, failed frames) picks up where it left off when you re-run the same command in the same directory. Frames already on disk are skipped. One experiment per output directory.
Documentation
Full docs — per-command detail, the container image, and access roles — are in the project repository.
Tutorials
Download an experiment, from login to files
A start-to-finish walkthrough for the common task — "get me the images + metadata for the soybean drought experiment."
# 1. Log in (once). Defaults to prod; use --server + -p for a named staging/local profile.
bloomctl login
# → prompts for email + password; writes credentials to ~/.bloom
# 2. Find the experiment — browse by species from a menu (menu prints to stderr):
bloomctl cyl experiments list --species-menu
# Select a species:
# 0) All species
# 1) Arabidopsis
# 2) Soybean
# → prints the table; note the experiment_id you want, e.g. 42
# (or skip this and let `download` resolve the name — see step 4)
# 3. (optional) Sanity-check the contents before pulling gigabytes of images:
bloomctl cyl accessions list --experiment-id 42 # which accessions are in it
bloomctl cyl accessions sample-counts --species-menu # plant count per accession (pick a species)
bloomctl cyl datasets list --experiment-id 42 # any trait datasets already built
# 4. Download it — metadata only first to preview, then the full pull:
bloomctl cyl download ./soy-drought --experiment-id 42 --meta-only # scans.csv only
bloomctl cyl download ./soy-drought --experiment-id 42 # scans.csv + all frames
# …or without ever looking up the id:
bloomctl cyl download ./soy-drought --experiment-name "drought" --species Soybean
Result: ./soy-drought/scans.csv (one row per scan) plus ./soy-drought/images/Wave{n}/… (the
frames). For scripting, swap the menus for explicit ids and add --output json.
Metadata
Release files for bloomctl 0.1.0a6
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| bloomctl-0.1.0a6.tar.gz | 79.2 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| bloomctl-0.1.0a6-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 173.9 kB
Release files / bloomctl-0.1.0a6.tar.gz
| Download URL | bloomctl-0.1.0a6.tar.gz |
|---|---|
| Size | 79.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
c4833bbd737b84553c301234ce7bd8926a214e2c7bce8323f4a45bed910c0caf
|
|
BLAKE2b-256 checksum How to use checksums |
bb21b83331ccb3307f4707b1b9f555df1ad09f2bff6468755250273876f32939
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.12.20 {"installer":{"name":"uv","version":"0.12.20","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / bloomctl-0.1.0a6-py3-none-any.whl
| Download URL | bloomctl-0.1.0a6-py3-none-any.whl |
|---|---|
| Size | 94.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
c3cc29d26f7d754ca6d091d39e800782ecaae1eacc700972d6302d4ff5806cf6
|
|
BLAKE2b-256 checksum How to use checksums |
d93fd9e85af22ce6d89d0dff4b79fa304d09d6f4eb90929e3763ff94f1fdcd72
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.12.20 {"installer":{"name":"uv","version":"0.12.20","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|