Python: serve_anndata() quickstart#
This page is for running Cellucid servers from Python code (scripts, pipelines, interactive Python).
If you’re in a notebook and want an embedded viewer, go to Jupyter: show_anndata() quickstart instead.
At a glance#
Audience
Computational users: scripted workflows and reproducibility.
Developers: embedding Cellucid into larger systems.
Time
Minimal server: ~5 minutes
Prerequisites
pip install cellucid
Quick start#
Use this when you have a .h5ad, a Zarr store (folder or .zip), any other
file or folder Cellucid reads (Every loading route), or an in-memory
AnnData or MuData. The viewer reads the store itself, in place, with range
requests where the format allows it; the server serves its bytes. An in-memory
AnnData, and an AnnData, MuData, Loom or 10x file not in priority order, are
served as a store in priority order made as the viewer reads it, so a
subsample transfers only its cells; so is a MuData object. An object’s
expression matrices, and a cell-major X of a file, are laid out gene-major
in the background, so the viewer opens at once.
from cellucid import serve_anndata
serve_anndata(
"/path/to/data.h5ad",
dataset_name="My study",
dataset_id="my-study-v1",
)
# A Zarr store (folder or .zip) or an in-memory AnnData uses the same call shape.
This starts a local server and opens the viewer in your default browser
(unless open_browser=False). A file written by cellucid.prepare() declares
its own name and id in uns['cellucid']; any other AnnData is named after
its file (or, in memory, as AnnData (N cells)), and the id made so is
printed. dataset_name and dataset_id name it otherwise.
Note
serve_anndata(...) blocks while serving and returns its closed
AnnDataServer only after serving has ended. Use the class below with
start_background() when you need a running server object or programmatic
lifecycle control.
What a start prints#
Four numbered steps — Detecting format, Reading metadata,
Checking launch choices, Starting server — then the banner with the Viewer
URL. No step reads an array.
Full transcript: Server Mode (CLI + Python).
Controlling host/port and browser opening#
serve_anndata and AnnDataServer accept:
port(default8765, bound exactly: a taken port raises;0asks the operating system for a free one)host(default127.0.0.1)open_browser(defaultTrueforserve_anndata,FalseforAnnDataServer)quiet(defaultFalse)
Example:
from cellucid import serve_anndata
serve_anndata(
"data.h5ad",
port=9000,
host="127.0.0.1",
open_browser=False,
quiet=False,
dataset_name="My study",
dataset_id="my-study-v1",
)
Binding to every interface (host="0.0.0.0")#
Use it when the client cannot reach this machine directly — typically an HPC compute node whose tunnel terminates on a login node. Two things to know:
urlandviewer_urlreport the loopback origin, because the wildcard is not an address anything can open.network_urlscarries the machine’s own name for clients elsewhere on the network, and the banner prints both.Through a tunnel you still open
http://127.0.0.1:<port>/…: the near end of the tunnel is your own machine.
A non-loopback bind has no authentication of any kind. See Security, privacy, CORS, and networking and HPC clusters: Slurm, compute nodes, and --host 0.0.0.0.
Non-blocking servers (recommended for scripts/tools)#
AnnDataServer#
from cellucid import AnnDataServer
server = AnnDataServer(
"data.h5ad",
open_browser=False,
quiet=False,
latent_key="X_pca", # optional; see below
dataset_name="My study",
dataset_id="my-study-v1",
)
server.start_background()
print(server.url) # e.g. http://127.0.0.1:8765
print(server.viewer_url) # e.g. http://127.0.0.1:8765/?anndata=true
# ... do other work ...
server.stop()
Use server.viewer_url when opening the application. Its exact anndata=true
marker identifies this user-served launch before the first paint, so the
ordinary sample-catalog welcome overlay is not shown, and the viewer opens the
one dataset the server lists at /_cellucid/datasets. The data and viewer
remain on the same server origin.
Options you can pass#
Every option is optional. Each one you set is checked against the store’s
metadata before the server binds (a name the store does not have is an error;
for a format Python does not read — an R object, Loom, 10x, MatrixMarket — the
viewer checks it when it opens the data) and handed to the viewer as a launch
default. One you leave unset is taken from
the store’s own uns['cellucid']['defaults'], else the viewer’s default rule
(see How the viewer reads AnnData (show_anndata() / serve_anndata())).
dataset_name: non-empty, unpadded human-readable identity without control characters; Unicode is preserved. Defaults touns['cellucid']['name']; required when the store has nonedataset_id: portable 1–180 character ASCII identity (letter or digit first; then letters, digits,.,_, or-; no trailing.or reserved Windows device name). Defaults touns['cellucid']['id']; required when the store has nonelatent_key: theobsmlatent space (scVI, PCA) the outlier filter measures in, never a 2D/3D layout. The viewer reads the outlier quantiles the store holds for it, or computes them on first use (Outlier filtering (per categorical field))normalize_embeddings: whether the viewer scales embeddings into its coordinate rangecentroid_min_points: the fewest cells a category needs to get outlier quantiles (10 when None)obs_keys: exactadata.obscolumns the viewer shows, in this order; every column is shown when omitted. Use it to leave out a column Cellucid cannot show, such as adatetime64collection datevector_field_default: the vector field the overlay opens on, by its field id (velocityforobsm['velocity_umap'])embedding_keys: theobsmarray of a dimension slot, such as{"2d": "X_tsne"}or{"2d": ("X_pca", [0, 1])}with 0-based columns; see belowknn_key: theobspmatrix the viewer draws as the neighbor graph, such as"connectivities"; read only when a view draws itgene_id_column: the column of the gene axis that names genes (default: its index); empty values take the index name and repeated names are made unique (MATR3,MATR3-1)expression_source:"X","raw", or"layer:<name>"(default:X, or withoutXthe guess described in How the viewer reads AnnData (show_anndata() / serve_anndata()))modality: for a multimodal dataset (a MuData), the modality the viewer opens on (one ofmdata.mod); when None, the first gene-expression modality (rna,gex, …), else the first. Refused for data with one feature space
Which obsm key becomes the embedding#
A slot named in embedding_keys shows that array. Every other slot follows the
default rule: X_umap_1d / X_umap_2d / X_umap_3d each fill their own
dimension, and with none of them present, a plain X_umap of 1, 2, or 3 columns
fills the slot of its own column count, so a Scanpy object is shown as written.
Only when neither fills any slot does the viewer make a deterministic best guess
from the other obsm arrays, and marks it as guessed.
server = cellucid.serve_anndata(
"data.h5ad",
dataset_name="My study",
dataset_id="my-study-v1",
embedding_keys={"2d": ("X_pca", [0, 1])},
)
The neighbor graph: knn_key=#
server = cellucid.serve_anndata(
"data.h5ad",
dataset_name="My study",
dataset_id="my-study-v1",
knn_key="connectivities",
)
Without knn_key the viewer uses obsp['connectivities'] when the store has
it. Either way the graph is read only when a view draws it, so it costs nothing
at startup. Naming a graph the store does not carry stops the server before it
binds; one that is not symmetric (such as distances) is refused by the viewer
when it reads it.
Both rules in full: How the viewer reads AnnData (show_anndata() / serve_anndata()).
Edge cases (high-signal)#
Remote machine: prefer an SSH tunnel over binding to
0.0.0.0(see Remote servers, SSH tunneling, and cloud).Huge
AnnDatain memory: the viewer opens at once; its expression matrices are laid out gene-major into memory-mapped files on disk in the background (never a second copy in memory; about two seconds per 100 million stored values), read-only until they are, so later edits to the object do not show; open a subsample in the viewer (Session › Subsampling) to read only some of the cells.Gene IDs not found: set
gene_id_columnifvar.indexis not what you search by.
Troubleshooting#
Server starts but UI shows an error page: Troubleshooting (viewing)
Data requirements (UMAP keys, vectors): How the viewer reads AnnData (show_anndata() / serve_anndata())