Skip to content

Latest commit

 

History

History
259 lines (196 loc) · 10.6 KB

File metadata and controls

259 lines (196 loc) · 10.6 KB

Installation

How to install and configure the NiChart Project API and its nichart CLI, for each execution backend (local Docker, local Singularity/Apptainer, SLURM, and AWS Batch/cloud).

  • New to the project / local Docker dev? docs/getting-started.md is the quick start.
  • Cloud (AWS Batch) testing? docs/cloud-local-testing.md.
  • Validating the CLI on a SLURM cluster? docs/cli-slurm-testing.md.
  • Driving NiChart from an LLM agent (Claude Desktop, etc.)? docs/mcp.md.

1. Execution backends

The server runs one job backend, chosen from config (see §4). Pick your target before installing so you know which prerequisites you need.

Backend When Runs tools via Needs
docker Local dev / single workstation Docker daemon Docker
singularity Workstation/cluster without Docker Apptainer/Singularity + prebuilt .sif apptainer, SIF images
slurm Shared HPC cluster sbatch → Apptainer on compute nodes SLURM CLIs, apptainer, SIF images, shared FS
batch Cloud AWS Batch via Lambda AWS account/creds (see cloud-local doc)

docker and batch have their own docs; this file focuses on the Singularity and SLURM paths, which is where installation is non-obvious.


2. Prerequisites

Common:

  • Python 3.11+ (3.12 is the reference).
  • Git checkout of this repository.

Per backend, additionally:

  • docker → a working Docker daemon (and NICHART_HOST_DATA_ROOT if the server itself runs in a container — DooD).
  • singularityapptainer (or singularity) on PATH, and SIF images built (see §5).
  • slurmsbatch/squeue/sacct on PATH on the submit host; apptainer on the compute nodes; SIF images; and a filesystem shared between submit host and compute nodes for the data root and SLURM logs.
  • batch → see docs/cloud-local-testing.md.

3. Install the package

Install editable, from the repo root:

python -m venv .venv && source .venv/bin/activate    # or conda
pip install -e .

Editable (-e) is the recommended development install. It gives you both the server (app.main, FastAPI/uvicorn) and the nichart CLI, and keeps your working copy as the source of truth. A packaged install (a wheel, or uv) also works: the resources/ catalog ships inside the package and config is read from ~/.nichart/.env / environment variables (not the working directory), so the server runs from any directory. Use -e for dev; use a packaged install for distribution.

Verify:

nichart --help
python -c "from app.config import Settings; s=Settings(); print('resources:', s.resources_path, s.resources_path.is_dir())"

4. Configuration (.env)

The server reads settings from environment variables prefixed NICHART_ and from .env files, resolved independently of the working directory. Set this up once; every launch (including the CLI's spawned server) reuses it.

Where config comes from, lowest → highest precedence:

  1. <repo>/.env — dev-checkout fallback (last resort).
  2. ~/.nichart/.env — the per-user configured location (use this for a packaged/uv install).
  3. $NICHART_ENV_FILE — an explicit path (e.g. set by a launcher/GUI).
  4. exported NICHART_* env vars — override everything.
cp .env.example .env                              # dev checkout, or…
mkdir -p ~/.nichart && cp .env.example ~/.nichart/.env   # packaged/user install
$EDITOR .env    # (or ~/.nichart/.env)

Check for stray overrides before relying on a file:

env | grep NICHART_ || echo "clean"

Key variables (see .env.example / app/config.py for the full list):

Variable Applies to Notes
NICHART_EXECUTION_MODE all local or cloud. Default local.
NICHART_JOB_BACKEND all Explicit backend: docker|singularity|slurm|batch. Overrides auto-selection.
NICHART_DATA_ROOT all Project data root. Must be on shared FS for SLURM.
NICHART_SIF_DIR singularity, slurm Directory of prebuilt .sif images (see §5).
NICHART_CONTAINER_RUNNER singularity, slurm apptainer (default) or singularity.
NICHART_SLURM_PARTITION / _ACCOUNT slurm Partition / account to charge.
NICHART_SLURM_LOGS_DIR slurm Job logs. Defaults to <data_root>/_slurm_logs. Must be on shared FS.
NICHART_SLURM_EXTRA_SBATCH_ARGS slurm JSON list, e.g. ["--constraint=h100"].
NICHART_INACTIVITY_TIMEOUT_SECONDS all Idle auto-shutdown: server exits after this many seconds with no API activity and no in-progress runs. Default 0 = disabled (a manually-launched/systemd server stays up). The CLI's auto-spawned servers enable this themselves (default 30 min). Set -1/0 to disable.

Backend auto-selection when NICHART_JOB_BACKEND is unset: execution_mode=cloudbatch; local + NICHART_SIF_DIR set → singularity; local (default) → docker.

So a minimal SLURM .env looks like:

NICHART_JOB_BACKEND=slurm
NICHART_SIF_DIR=/shared/nichart/sif
NICHART_CONTAINER_RUNNER=apptainer
NICHART_DATA_ROOT=/shared/nichart/data
NICHART_SLURM_LOGS_DIR=/shared/nichart/slurm_logs
NICHART_SLURM_PARTITION=gpu
NICHART_SLURM_ACCOUNT=my_alloc

5. Building SIF images (Singularity / SLURM)

The Singularity and SLURM backends do not pull Docker at run time. Instead, each tool's Docker image is converted once into a Singularity/Apptainer .sif file, and the backend runs those. You must build this registry before the first run (and refresh it when tool container versions change).

scripts/build-sif-registry.py reads every resources/tools/*.yaml, extracts its container.image tag, and builds one .sif per unique image into --sif-dir:

alpine:3.19                          →  alpine_3.19.sif
cbica/nichart_dlmuse:1.0.10-wrapped  →  cbica_nichart_dlmuse_1.0.10-wrapped.sif

The naming is canonical — the server locates SIFs by this same convention, so don't rename them.

Usage

# Preview what would be built (no network, no build):
python scripts/build-sif-registry.py --dry-run

# Build into $NICHART_SIF_DIR (or ./sif):
python scripts/build-sif-registry.py --sif-dir /shared/nichart/sif --runner apptainer

# Refresh after a tool image bump:
python scripts/build-sif-registry.py --sif-dir /shared/nichart/sif --force

Options: --tools-dir (default resources/tools or $NICHART_RESOURCES_PATH/tools), --sif-dir (default $NICHART_SIF_DIR or ./sif), --runner apptainer|singularity, --force, --dry-run.

Requirements: apptainer/singularity on PATH, pyyaml, outbound network to pull the Docker images, and support for unprivileged builds (the script uses apptainer build --fakeroot).

⚠️ On many clusters you must build as a SLURM job

Interactive/login nodes frequently disallow apptainer build / --fakeroot (and often lack outbound network or enough scratch). If python scripts/build-sif-registry.py fails on the login node with a fakeroot/permission or network error, run it on a compute node via sbatch. Example build-sifs.sbatch:

#!/bin/bash
#SBATCH --job-name=nichart-sif-build
#SBATCH --partition=<a-partition-that-allows-builds-and-has-network>
#SBATCH --time=03:00:00
#SBATCH --mem=16G
#SBATCH --cpus-per-task=4
#SBATCH --output=nichart-sif-build-%j.log

set -euo pipefail
module load apptainer          # cluster-specific; may be `singularity` or nothing
source /path/to/NiChart_Project_API/.venv/bin/activate
cd /path/to/NiChart_Project_API

export NICHART_SIF_DIR=/shared/nichart/sif
python scripts/build-sif-registry.py --sif-dir "$NICHART_SIF_DIR" --runner apptainer
sbatch build-sifs.sbatch
squeue -u "$USER"          # watch it
tail -f nichart-sif-build-*.log

The specifics (which partition allows builds, whether --fakeroot works or you need a different unprivileged-build setup, module names, network/proxy) are cluster-dependent — that's a call for whoever does the install. The point of this doc is that the step exists and where it fits: build the SIF registry to a shared NICHART_SIF_DIR (readable by compute nodes), then set that path in .env.


6. Running the server

  • Local Docker (dev): docker compose up (see docs/getting-started.md).
  • Singularity / SLURM (bare-metal, no compose): run uvicorn — from any directory; config and resources/ are resolved independently of the cwd (§4):
    uvicorn app.main:app --host 127.0.0.1 --port 8000
    (In a dev checkout the repo .env is picked up automatically; for a packaged install, configure ~/.nichart/.env.) For a shared, long-lived server, run it under tmux/systemd. For one-off CLI use you usually don't start it yourself — see §7.
  • Cloud (Batch): see docs/cloud-local-testing.md.

Verify: curl http://127.0.0.1:8000/health{"status":"ok","execution_mode":"local",…}.


7. The nichart CLI

Installed with the package (§3). Full reference: app/CLI.md; the all-in-one run command: app/CLI_run.md.

  • Point it at a server with --url or NICHART_API_URL (default http://localhost:8000).
  • nichart run can start a server for you. With --server auto (default) it attaches to a running server if one answers, otherwise it spawns an ephemeral local one (using the configured install — the bundled resources/ and your .env from §4), runs, waits for completion, and shuts it down. --server attach requires an existing server; --server spawn always starts a fresh one.
# One shot: create a project, upload, verify, submit — spawning a local
# (SLURM-backed, per your .env) server automatically:
nichart run run_dlmuse --project study1 --t1 /shared/data/t1 --participants demo.csv --wait-until-done

Multi-user note: in local mode the server has no auth and treats every request as the OS user running the server process. The per-user ephemeral spawn (default) therefore isolates users naturally (each runs as themselves). Do not stand up one shared local-mode server for a team expecting per-user isolation.


8. Post-install verification checklist

  1. nichart --help and python -c "import app.cli; print(app.cli.REPO_ROOT)" → repo root with .env + resources/.
  2. env | grep NICHART_ → no stray overrides masking .env.
  3. Backend prerequisites present (sbatch/apptainer for SLURM, etc.).
  4. NICHART_SIF_DIR populated (ls $NICHART_SIF_DIR/*.sif) for singularity/slurm.
  5. NICHART_DATA_ROOT and NICHART_SLURM_LOGS_DIR on shared storage (SLURM).
  6. End-to-end smoke test: docs/cli-slurm-testing.md.