Modern CLI for XNAT neuroimaging server administration
Project description
xnatctl
A modern command-line interface for XNAT neuroimaging server administration.
What is xnatctl?
xnatctl is a command-line tool for managing neuroimaging data on XNAT servers. It lets you browse projects and subjects, download and upload imaging sessions, run processing pipelines, and perform administrative tasks -- all from your terminal. Whether you are a researcher downloading data for analysis or a system administrator managing hundreds of subjects, xnatctl provides a consistent, scriptable interface to your XNAT server.
Features
-
Resource-centric commands -- interact with XNAT the way you think about it:
xnatctl project list,xnatctl session download,xnatctl scan show. Every command follows the patternxnatctl <resource> <action> [args]. -
Profile-based configuration -- manage multiple XNAT servers with named profiles and switch between them instantly. Keep separate profiles for production, development, and collaboration servers in a single config file.
-
Consistent output formats -- every command supports
--output json|tableand--quiet(IDs only), so you can pipe results into scripts or read them in a human-friendly table without changing your workflow. -
Parallel operations -- batch uploads and downloads run across multiple workers with real-time progress tracking. Large transfers stay fast without extra scripting.
-
Session authentication -- log in once with
xnatctl auth loginand your session token is cached locally. Expired tokens are refreshed automatically, so you stay authenticated without repeated prompts. -
Pure HTTP -- xnatctl talks directly to the XNAT REST API using httpx. Existing Python libraries like pyxnat and xnatpy inspired this project, but they are importable libraries that require writing Python code. xnatctl is a standalone CLI that ships as a single binary -- no Python environment required.
Installation
Standalone Binary (no Python required)
If you do not have Python installed or prefer a single executable, download a pre-built binary. On Linux and macOS, the install script auto-detects your OS and architecture:
# One-line install (Linux/macOS only, auto-detects platform)
curl -fsSL https://github.com/rickyltwong/xnatctl/raw/main/install.sh | bash
# Install a specific version
XNATCTL_VERSION=v0.1.0 curl -fsSL https://github.com/rickyltwong/xnatctl/raw/main/install.sh | bash
# Custom install directory (default: ~/.local/bin)
XNATCTL_INSTALL_DIR=/usr/local/bin curl -fsSL https://github.com/rickyltwong/xnatctl/raw/main/install.sh | bash
Or download manually from GitHub Releases:
| Platform | Asset |
|---|---|
| Linux (x86_64) | xnatctl-linux-amd64.tar.gz |
| macOS (x86_64) | xnatctl-darwin-amd64.tar.gz |
| Windows (x86_64) | xnatctl-windows-amd64.zip |
Linux / macOS:
tar -xzf xnatctl-<platform>-amd64.tar.gz
chmod +x xnatctl
mv xnatctl ~/.local/bin/
Windows (PowerShell):
Expand-Archive xnatctl-windows-amd64.zip -DestinationPath .
New-Item -ItemType Directory -Force -Path "$env:LOCALAPPDATA\bin"
Move-Item xnatctl.exe "$env:LOCALAPPDATA\bin\"
Note: On Windows, make sure
%LOCALAPPDATA%\binis on your PATH. You can add it via Settings > System > About > Advanced system settings > Environment Variables, or see the Installation guide for a PowerShell command.
Python Package
If you already have Python 3.11+ and want to install xnatctl as a package, use pip or uv:
# From PyPI (recommended)
pip install xnatctl
# With uv
uv pip install xnatctl
# For DICOM utilities (optional -- adds pydicom and pynetdicom)
pip install "xnatctl[dicom]"
# From source
pip install git+https://github.com/rickyltwong/xnatctl.git
Docker
For containerized environments or CI pipelines where you want to avoid local installation entirely:
docker run --rm ghcr.io/rickyltwong/xnatctl:main --help
For full installation instructions including shell completion and troubleshooting, see the Installation guide.
Quick Start
Once installed, you can be up and running in four steps.
1. Create a configuration file. This stores your XNAT server URL and default settings so you do not have to pass them on every command:
xnatctl config init --url https://xnat.example.org
2. Authenticate. Log in with your XNAT credentials. The session token is cached locally, so subsequent commands authenticate automatically:
xnatctl auth login
3. Browse your data. List the projects you have access to and inspect their contents:
xnatctl project list
4. Download a session. Pull imaging data to your local machine for analysis. Use an experiment accession number or, if you have a default project set, a session label:
xnatctl session download -E XNAT_E00001 --out ./data
For a detailed walkthrough, see the Quick Start guide.
Commands
| Command | Description |
|---|---|
xnatctl config |
Manage configuration profiles |
xnatctl auth |
Authentication (login/logout/status) |
xnatctl project |
Project operations (list/show/create) |
xnatctl subject |
Subject operations (list/show/rename/delete) |
xnatctl session |
Session operations (list/show/download/upload) |
xnatctl scan |
Scan operations (list/show/delete/download) |
xnatctl resource |
Resource operations (list/upload/download) |
xnatctl prearchive |
Prearchive management (list/archive/delete/move) |
xnatctl pipeline |
Pipeline execution (list/run/status/cancel) |
xnatctl admin |
Administrative operations (users/catalogs/audit) |
xnatctl api |
Raw API access (escape hatch for any endpoint) |
xnatctl local |
Offline operations (extract downloaded ZIPs) |
xnatctl dicom |
DICOM utilities (requires xnatctl[dicom]) |
For complete usage and examples, see the CLI Reference.
Configuration
Config file location: ~/.config/xnatctl/config.yaml
default_profile: production
output_format: table
profiles:
production:
url: https://xnat.example.org
username: myuser # optional -- can also use env vars
password: mypassword # optional -- can also use env vars
verify_ssl: true
timeout: 30
default_project: MYPROJECT
development:
url: https://xnat-dev.example.org
verify_ssl: false
Working with Profiles
Profiles let you store connection details for each XNAT server you work with. You can create, add, and switch profiles from the command line:
# Create an initial config (prompts for URL and optional defaults)
xnatctl config init --url https://xnat.example.org
# Add additional profiles
xnatctl config add-profile dev --url https://xnat-dev.example.org --no-verify-ssl
# Switch the active profile
xnatctl config use-context dev
# Show the active profile and config
xnatctl config show
Authentication Flow
Log in once and your session token is cached. xnatctl reuses the cached token and refreshes it automatically when it expires:
# Login and cache a session token
xnatctl auth login
# Check current user and session context
xnatctl whoami
Credential priority (highest to lowest):
- CLI arguments (
--username,--password) - Environment variables (
XNAT_USER,XNAT_PASS) - Profile config (
username,passwordin config.yaml) - Interactive prompt
Session tokens are cached at ~/.config/xnatctl/.session and used
automatically until they expire.
Environment Variables
You can override any profile setting with environment variables. This is especially useful for CI pipelines and non-interactive scripts:
| Variable | Description |
|---|---|
XNAT_URL |
Server URL |
XNAT_USER |
Username |
XNAT_PASS |
Password |
XNAT_TOKEN |
Session token (highest auth priority) |
XNAT_PROFILE |
Config profile name |
Notes:
XNAT_TOKENtakes precedence over cached sessions and username/password credentials. Use it when you already have a valid token from another tool.XNAT_URLandXNAT_PROFILEoverride values fromconfig.yamlfor the current shell session.- Use
XNAT_USERandXNAT_PASSfor non-interactive authentication in CI jobs and automated scripts.
Documentation
Complete documentation is available in the docs/ directory. Topics include installation, key concepts, configuration, CLI reference, downloading, uploading, workflows, and XNAT compatibility.
Development
# Clone and install
git clone https://github.com/rickyltwong/xnatctl.git
cd xnatctl
uv sync --dev
# Run tests
uv run pytest tests/ -v
# Lint and format
uv run ruff check xnatctl scripts
uv run ruff format xnatctl scripts
# Type check
uv run mypy xnatctl
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file xnatctl-0.1.3.tar.gz.
File metadata
- Download URL: xnatctl-0.1.3.tar.gz
- Upload date:
- Size: 263.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f2872b83561c428704ca694b789c1bdf9b2e5f729daa1e99881af722876a28ae
|
|
| MD5 |
41738ac64c133d9211f589ffced6dcfb
|
|
| BLAKE2b-256 |
8e5ff51373a32c54b23b985c151b1cc5c043a9cda99756b0baa364e8d2fc9c00
|
Provenance
The following attestation bundles were made for xnatctl-0.1.3.tar.gz:
Publisher:
ci.yml on rickyltwong/xnatctl
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
xnatctl-0.1.3.tar.gz -
Subject digest:
f2872b83561c428704ca694b789c1bdf9b2e5f729daa1e99881af722876a28ae - Sigstore transparency entry: 992466418
- Sigstore integration time:
-
Permalink:
rickyltwong/xnatctl@0fb751bfe7d2645fedd963a4b5fde0d8a79b8593 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/rickyltwong
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
ci.yml@0fb751bfe7d2645fedd963a4b5fde0d8a79b8593 -
Trigger Event:
push
-
Statement type:
File details
Details for the file xnatctl-0.1.3-py3-none-any.whl.
File metadata
- Download URL: xnatctl-0.1.3-py3-none-any.whl
- Upload date:
- Size: 116.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a56d161d2c16de74a04fd1ba702d87c949af2317e3a24f61818093ac85ec9e44
|
|
| MD5 |
79a74d6f5403c446f11cf636bc131e53
|
|
| BLAKE2b-256 |
db34e83b89c72150d0ee449f6497c38273894d96edc24e304d49669c51d819ed
|
Provenance
The following attestation bundles were made for xnatctl-0.1.3-py3-none-any.whl:
Publisher:
ci.yml on rickyltwong/xnatctl
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
xnatctl-0.1.3-py3-none-any.whl -
Subject digest:
a56d161d2c16de74a04fd1ba702d87c949af2317e3a24f61818093ac85ec9e44 - Sigstore transparency entry: 992466426
- Sigstore integration time:
-
Permalink:
rickyltwong/xnatctl@0fb751bfe7d2645fedd963a4b5fde0d8a79b8593 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/rickyltwong
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
ci.yml@0fb751bfe7d2645fedd963a4b5fde0d8a79b8593 -
Trigger Event:
push
-
Statement type: