Skip to content

adata-cli 0.5.1

Choose a tag to compare

@Claptar Claptar released this 21 Sep 10:53
· 99 commits to main since this release
48fcc60

adata-cli 0.5.1

The container image now works inside a Nextflow pipeline, and copying a
row-chunked store is no longer bottlenecked on read latency.

The Python package is unchanged apart from the performance fix below — if you
use adata from PyPI and not from the image, the upgrade is optional.


⚠️ Breaking: the image no longer sets an entrypoint

You must now name the command explicitly:

-docker run --rm -v /data:/data quay.io/cellgeni/adata-cli:0.5.1 view /data/f.h5ad
+docker run --rm -v /data:/data quay.io/cellgeni/adata-cli:0.5.1 adata view /data/f.h5ad

This affects Docker and Podman users only. If you run the image through
Apptainer or Singularity, nothing changes — singularity exec has always
ignored the entrypoint, so your commands already named adata.

The entrypoint had to go because Nextflow requires /bin/bash to be the
container entrypoint. Anything that relied on the old implicit form — a shell
alias, a wrapper script, a .bashrc function — needs the extra word.

Nothing was republished under the 0.5.0 tag, so pinned workflows keep
working until you move them.


Nextflow support

The image can now be used from a process directly:

process INSPECT {
    container 'quay.io/cellgeni/adata-cli:0.5.1'

    input:  path h5ad
    output: path 'summary.txt'

    script:
    """
    adata view ${h5ad} > summary.txt
    """
}

With either runtime enabled in nextflow.config:

// Docker
docker.enabled    = true
docker.runOptions = '-u $(id -u):$(id -g)'

// or Apptainer, e.g. on an HPC farm
apptainer.enabled     = true
apptainer.autoMounts  = true

What was wrong

  • Every Docker- and Podman-backed task failed outright. Nextflow invokes
    docker run IMG /bin/bash -ue .command.sh; the old ENTRYPOINT ["adata"]
    turned that into adata /bin/bash -ue .command.sh, which died with
    No such command '/bin/bash'.
  • Task metrics were silently missing. Nextflow shells out to ps to
    collect them, and ps was not in the image — so -with-trace,
    -with-report and Seqera Platform all showed empty CPU and memory columns.
    The tools Nextflow requires (bash, ps, awk, date, grep, sed,
    tail, tee) are now installed, and asserted at build time so they cannot
    silently disappear again.
  • A bind-mounted $HOME could break the install. Apptainer mounts your
    home directory by default, so a ~/.local/lib/python3.12/site-packages
    holding a different zarr, h5py or numpy could shadow the image's own.
    The image now sets PYTHONNOUSERSITE=1.
  • Running under an arbitrary UID left no writable cache. -u $(id -u):$(id -g)
    gives a container with no writable $HOME; the image now points
    XDG_CACHE_HOME at a world-writable directory.

Verified against Nextflow 26.04.6: a pipeline completes and reports a full
trace row.


Faster copies of row-chunked stores

subset, split, concat, import and the HDF5 ⇄ Zarr conversions all
stream through the same copy path, which used to read one source chunk at a
time. For a store
chunked (1, n_cols) — common in files written row-by-row — that meant one
row per read
.

On a local disk this is merely wasteful. On Lustre or NFS every read is a
network round-trip costing milliseconds, so a million-row copy spent almost all
of its wall-clock waiting rather than working.

Reads are now sized to a 32 MiB budget, rounded down to a whole number of
source chunks:

store source chunks rows per read before after
(1_000_000, 30_000) float32 (1, 30_000) 1 279
(10_000_000,) int64 (65_536,) 65,536 4,194,304

Variable-length string columns are sized correctly too. h5py reports
itemsize 8 for them because the value is a pointer rather than the text,
which previously overestimated how many rows fit in memory by an order of
magnitude.

No output changes — this is purely how much is read per call.


Also in this release

  • Added a .dockerignore. Building the image locally no longer copies your
    working .venv, .git and .pytest_cache into the build context.
  • The image's layers are ordered so that editing source no longer re-downloads
    duckdb on every rebuild.
  • README.md and the documentation site were updated for the entrypoint
    change.

Upgrading

# PyPI
pip install --upgrade pyadata-cli

# Container
docker pull quay.io/cellgeni/adata-cli:0.5.1

quay.io/cellgeni/adata-cli:latest now points at 0.5.1.

Full changelog: https://github.com/cellgeni/adata-cli/blob/main/CHANGELOG.md