Server (browser tab + local HTTP server)#

This page documents server-mode usage: open Cellucid in a browser tab while a local server serves the data.

You have three equivalent entry points:


Fast path (beginner-friendly)#

A) Serve anything (auto-detected) from the terminal#

# Exported folder, .h5ad, or .zarr are all supported:
cellucid serve /path/to/data
cellucid serve /path/to/data.h5ad --dataset-name "My dataset" --dataset-id my-dataset
cellucid serve /path/to/data.zarr --dataset-name "My dataset" --dataset-id my-dataset

Then open the printed URL (or let it auto-open).

B) Serve an exported dataset from Python#

from cellucid import serve

serve("./my_export")  # blocks until Ctrl+C

Practical path (deployment patterns)#

1) Exported dataset vs AnnData mode#

Exported dataset (recommended for speed + reproducibility):

AnnData mode (convenient, often slower):

  • Serve with serve_anndata() or cellucid serve data.h5ad --dataset-name "My dataset" --dataset-id my-dataset

  • Useful during exploratory analysis when you don’t want to write an export yet

2) Local machine vs remote server (HPC / cloud VM)#

Local machine:

  • Keep default host 127.0.0.1 (only accessible on your machine).

Remote server + SSH tunnel (recommended for HPC):

  1. On the remote machine (where the data lives):

    cellucid serve /path/to/data --host 127.0.0.1 --port 8765 --no-browser
    
  2. On your laptop:

    ssh -L 8765:127.0.0.1:8765 user@remote
    
  3. In your laptop browser:

    • Open the printed prepared-export Viewer URL: http://127.0.0.1:8765/?source=remote

Direct LAN access (use carefully):

  • Bind to 0.0.0.0 to make the server accessible to other machines on the network:

    cellucid serve /path/to/data --host 0.0.0.0
    
  • Do this only if you understand your network/security posture.


Deep path (how server mode works)#

What the server provides#

  • Static or virtual endpoints for dataset files (exported data or AnnData-backed “virtual files”)

  • CORS headers so the viewer UI can request data

  • Health/info endpoints:

    • /_cellucid/health

    • /_cellucid/info

    • /_cellucid/datasets

Viewer UI hosting and source requirements#

By default, Cellucid establishes and serves the exact verified viewer UI generation from the same server origin. This avoids:

  • mixed-content issues (HTTPS notebook + HTTP localhost)

  • cross-origin iframe restrictions

If the runtime cannot fetch and verify the exact source generation, startup raises before binding the server. Use --web-cache-dir PATH or the web_cache_dir= argument to select its publication directory.


API reference#

Functions#

cellucid.serve(data_dir, port=8765, host='127.0.0.1', open_browser=True, quiet=False, *, serve_web_ui=True, web_source_url='https://www.cellucid.com', web_cache_dir=None)[source]#

Serve a cellucid dataset directory.

This is the main entry point for serving data. It starts an HTTP server that serves the dataset files with CORS headers enabled.

Parameters:
  • data_dir (str | Path) – Path to the dataset directory

  • port (int) – Port to serve on (default: 8765)

  • host (str) – Host to bind to (default: 127.0.0.1)

  • open_browser (bool) – Whether to open the viewer in browser (default: True)

  • quiet (bool) – Suppress info messages

  • serve_web_ui (bool) – Establish and serve the exact current web build.

  • web_source_url (str) – Origin publishing the web asset inventory.

  • web_cache_dir (str | Path | None) – Directory holding the active verified web build.

Example

>>> from cellucid import serve
>>> serve("/path/to/my_dataset")

# For remote server access via SSH: >>> serve(“/path/to/data”, host=”0.0.0.0”) # Then on local machine: ssh -L 8765:localhost:8765 remote-server

cellucid.serve_anndata(data, port=8765, host='127.0.0.1', open_browser=True, quiet=False, *, latent_key=None, gene_id_column=None, normalize_embeddings=True, centroid_outlier_quantile=0.95, centroid_min_points=10, dataset_name, dataset_id, vector_field_default=None, serve_web_ui=True, web_source_url='https://www.cellucid.com', web_cache_dir=None)[source]#

Serve an AnnData object or h5ad file directly.

This is a convenience function for quickly visualizing AnnData. For production use, consider using prepare instead.

Parameters:
  • data (str, Path, or AnnData) – Path to h5ad file or AnnData object.

  • port (int) – Port to serve on (default: 8765).

  • host (str) – Host to bind to (default: 127.0.0.1).

  • open_browser (bool) – Whether to open browser (default: True).

  • quiet (bool) – Suppress info messages.

  • latent_key (str, optional) – Explicit key in obsm for the latent space.

  • gene_id_column (str, optional) – Exact column in var containing gene identifiers. If None, identifiers come from var.index.

  • normalize_embeddings (bool) – Whether to normalize embeddings into the viewer coordinate range.

  • centroid_outlier_quantile (float) – Quantile used when computing categorical centroids.

  • centroid_min_points (int) – Minimum category size used for centroid computation.

  • dataset_name (str) – Explicit human-readable dataset name.

  • dataset_id (str) – Explicit stable dataset identifier.

  • vector_field_default (str, optional) – Exact field id required when multiple UMAP vector fields exist.

  • serve_web_ui (bool) – Establish and serve the exact current web build.

  • web_source_url (str) – Origin publishing the web asset inventory.

  • web_cache_dir (str or Path, optional) – Directory holding the active verified web build.

Returns:

The running server instance.

Return type:

AnnDataServer

Example

>>> from cellucid import serve_anndata
>>> serve_anndata(
...     "/path/to/data.h5ad",
...     dataset_name="Example",
...     dataset_id="example",
... )
>>> # Or with in-memory AnnData
>>> import anndata as ad
>>> adata = ad.read_h5ad("data.h5ad")
>>> serve_anndata(
...     adata,
...     dataset_name="Example",
...     dataset_id="example",
... )

Classes#

class cellucid.CellucidServer(data_dir, port=8765, host='127.0.0.1', open_browser=False, quiet=False, *, serve_web_ui=True, web_source_url='https://www.cellucid.com', web_cache_dir=None)[source]#

Bases: object

Cellucid data server for serving datasets over HTTP.

Supports multiple deployment modes: - Local: Direct browser access on localhost - SSH tunnel: Access via port forwarding from remote server - Jupyter: Embedded in notebook environment

Example

server = CellucidServer(“/path/to/data”) server.start() # Blocking

# Or non-blocking: server.start_background() # … do other things … server.stop()

Parameters:
  • data_dir (str | Path)

  • port (int)

  • host (str)

  • open_browser (bool)

  • quiet (bool)

  • serve_web_ui (bool)

  • web_source_url (str)

  • web_cache_dir (str | Path | None)

__init__(data_dir, port=8765, host='127.0.0.1', open_browser=False, quiet=False, *, serve_web_ui=True, web_source_url='https://www.cellucid.com', web_cache_dir=None)[source]#

Initialize the server.

Parameters:
  • data_dir (str | Path) – Path to the dataset directory (single dataset or multi-dataset)

  • port (int) – Port to serve on (default: 8765)

  • host (str) – Host to bind to (default: 127.0.0.1 for localhost only)

  • open_browser (bool) – Whether to open the browser on start

  • quiet (bool) – Suppress info messages

  • serve_web_ui (bool) – Establish and serve the exact current web build.

  • web_source_url (str) – Origin publishing the web asset inventory.

  • web_cache_dir (str | Path | None) – Directory holding the active verified web build.

property url: str#

Get the URL of the currently running server.

property viewer_url: str#

Open this server’s prepared-data catalog in the verified viewer.

The viewer selects the sole declared dataset when the catalog is unique. A multi-dataset catalog requires an exact dataset selection; this URL never embeds or guesses an arbitrary catalog entry.

start(blocking=True)[source]#

Start this single-use server.

Parameters:

blocking (bool)

start_background()[source]#

Start the server in a background thread.

stop()[source]#

Stop this server and release its socket.

is_running()[source]#

Check if the server is running.

Return type:

bool

wait()[source]#

Wait for the background server to stop.

class cellucid.AnnDataServer(data, port=8765, host='127.0.0.1', open_browser=False, quiet=False, *, latent_key=None, gene_id_column=None, normalize_embeddings=True, centroid_outlier_quantile=0.95, centroid_min_points=10, dataset_name, dataset_id, vector_field_default=None, serve_web_ui=True, web_source_url='https://www.cellucid.com', web_cache_dir=None)[source]#

Bases: object

Server for serving AnnData data in Cellucid format.

Examples

Start a blocking server:

AnnDataServer(
    adata,
    dataset_name="Example",
    dataset_id="example",
).start()

Start and stop a background server:

server = AnnDataServer(
    adata,
    dataset_name="Example",
    dataset_id="example",
)
server.start_background()
server.stop()
Parameters:
  • data (str | Path | anndata.AnnData)

  • port (int)

  • host (str)

  • open_browser (bool)

  • quiet (bool)

  • latent_key (str | None)

  • gene_id_column (str | None)

  • normalize_embeddings (bool)

  • centroid_outlier_quantile (float)

  • centroid_min_points (int)

  • dataset_name (str)

  • dataset_id (str)

  • vector_field_default (str | None)

  • serve_web_ui (bool)

  • web_source_url (str)

  • web_cache_dir (str | Path | None)

__init__(data, port=8765, host='127.0.0.1', open_browser=False, quiet=False, *, latent_key=None, gene_id_column=None, normalize_embeddings=True, centroid_outlier_quantile=0.95, centroid_min_points=10, dataset_name, dataset_id, vector_field_default=None, serve_web_ui=True, web_source_url='https://www.cellucid.com', web_cache_dir=None)[source]#

Initialize the server.

Parameters:
  • data (str, Path, or AnnData) – Path to h5ad file or AnnData object.

  • port (int) – Port to serve on.

  • host (str) – Host to bind to.

  • open_browser (bool) – Whether to open browser on start.

  • quiet (bool) – Suppress info messages.

  • latent_key (str, optional) – Explicit key in obsm for the latent space.

  • gene_id_column (str, optional) – Exact column in var containing gene identifiers. If None, identifiers come from var.index.

  • normalize_embeddings (bool) – Whether to normalize embeddings into the viewer coordinate range.

  • centroid_outlier_quantile (float) – Quantile used when computing categorical centroids.

  • centroid_min_points (int) – Minimum category size used for centroid computation.

  • dataset_name (str) – Explicit human-readable dataset name.

  • dataset_id (str) – Explicit stable dataset identifier.

  • vector_field_default (str, optional) – Exact field id required when multiple UMAP vector fields exist.

  • serve_web_ui (bool) – Establish and serve the exact current web build.

  • web_source_url (str) – Origin publishing the web asset inventory.

  • web_cache_dir (str or Path, optional) – Directory holding the active verified web build.

Return type:

None

property url: str#

Get the URL of the currently running server.

property viewer_url: str#

Get the full URL to open the viewer.

start(blocking=True)[source]#

Start this single-use server.

Parameters:

blocking (bool)

start_background()[source]#

Start the server in a background thread.

stop()[source]#

Stop the server and cleanup resources.

is_running()[source]#

Check if the server is running.

Return type:

bool

wait()[source]#

Wait for the server to stop.


Edge cases (do not skip)#

“It works locally but not on the remote server”#

  • If the server is on a remote machine, your browser cannot directly reach its localhost.

  • Use SSH tunneling (preferred) or bind to an external interface + open firewall rules (higher risk).

“I bound to 0.0.0.0 and now anyone can access it”#

  • Binding --host 0.0.0.0 exposes the server to your network.

  • Cellucid servers are designed for local/private use (not hardened for public internet exposure).

“The dataset directory contains multiple datasets”#

  • CellucidServer supports serving a directory that contains multiple exported datasets as subfolders.

  • server.viewer_url opens that served catalog without embedding an arbitrary dataset id. One unique entry is selected automatically; multiple entries require an exact dataset-id selection.

  • Confirm the exact ids and paths by visiting /_cellucid/datasets.

  • Once any immediate child is recognized as a dataset candidate, every immediate subdirectory must be one complete current export. A stray or partial subdirectory rejects the root instead of being silently omitted.

“Exported folder missing some files”#

  • CellucidServer validates the complete declared prepared-artifact inventory during construction.

  • Missing required metadata, point files, or any artifact declared by a current manifest raises before a socket is bound.


Troubleshooting (symptom → diagnosis → fix)#

Symptom: “Port already in use”#

Fix:

  • Use --port 0 if supported by your workflow (otherwise choose a free port).

  • Or pick another port manually: --port 9000.


Symptom: “Data directory not found”#

Fix:

  • Confirm the path exists on the machine where you ran the server.

  • If you’re on a remote server, remember your local machine path is different.


Symptom: “I can open /_cellucid/health but the dataset won’t load”#

Likely causes:

  • You served a directory that is not a valid exported dataset (missing manifests/points files).

  • You served a parent folder with multiple datasets but opened the wrong path.

How to confirm:

  • Visit /_cellucid/datasets and confirm the dataset path you intended exists.

  • Try fetching dataset_identity.json and obs_manifest.json in the browser.

Fix:

  • Serve the correct dataset directory (the folder produced by prepare(...)).

  • Or re-export with prepare().


Symptom: “CORS blocked” (browser console error)#

Likely causes:

  • A corporate environment / browser extension blocks cross-origin requests.

Fix:

  • Prefer opening the viewer URL served by the same origin (default).

  • Disable the conflicting extension for the site, or verify the request in a clean profile with extensions disabled.


Symptom: web-generation startup failure#

Likely causes:

  • The configured source inventory or one of its declared objects could not be fetched or verified.

Fix:

  • Ensure source access at startup and pass a writable web_cache_dir.


Symptom: “Browser can’t connect / connection refused”#

Fix:

  • Confirm server is running and you are opening the correct URL.

  • If remote: confirm your SSH tunnel is active and mapped to the correct port.


Symptom: “It works for small datasets but crashes/gets slow for large ones”#

Likely causes:

  • AnnData mode is generating virtual files on demand and may hit memory/CPU limits.

Fix:

  • Export with prepare() (quantization + compression) and serve the exported directory.

  • Use read-only-backed .h5ad input when staying in AnnData mode; Zarr input is loaded eagerly.


Symptom: direct AnnData startup says “Importing dependencies…” and feels stuck#

What’s happening:

  • The first import may be slow in fresh environments because large scientific dependencies are loaded.

Fix:

  • Wait once (subsequent runs are faster in the same process).

  • If it truly hangs, run with --verbose and check for import errors.


See also#