A command-line interface for RSpace covering both the electronic lab notebook and the inventory system. Built on the rspace-client Python SDK.
Status: Alpha — not yet published to PyPI. Install locally using the instructions below.
- Verb-first command structure —
rspace list documents,rspace get SA123,rspace create sample - Full ELN coverage — documents, notebooks, folders, forms, files, groups, users, activity
- Full Inventory coverage — samples, subsamples, containers, templates, workbenches
- Smart
getcommand — infers resource type from GlobalID prefix (SD,SA,SS,IC, …) - Tagging — set tags on any resource type with a single
rspace tagcommand - Inventory snapshots —
rspace migrate export/importto move whole inventories, individual containers (with full subtree), templates, or samples between RSpace instances. Preserves attachments, preview images, IMAGE-container backgrounds, and the container hierarchy. - Multiple output formats — rich tables (default), JSON, CSV, quiet (IDs only, for piping)
- Pagination — all list commands support
--page/--page-sizewith a result footer - Named profiles — manage multiple RSpace instances with
--profile - Keychain storage — store credentials in the OS keychain, never in a plain-text file
- Python 3.9 or later
- Poetry (for local installation)
The package is not yet published to PyPI. Install it directly from the repository using Poetry or pip.
git clone https://github.com/rspace-os/rspacectl.git
cd rspacectl
poetry installThis installs the rspace command into a Poetry-managed virtual environment. Run commands via:
poetry run rspace --helpOr activate the environment first and use rspace directly:
poetry shell
rspace --helpgit clone https://github.com/rspace-os/rspacectl.git
cd rspacectl
pip install -e .
rspace --helpWith optional keychain support:
pip install -e ".[keychain]"rspace configureSaves credentials to ~/.rspacectl with permissions 600.
Manage multiple RSpace instances (e.g. production and staging) with named profiles:
rspace configure --profile staging # saves to ~/.rspacectl.staging
rspace --profile staging list samples # uses staging credentials
rspace configure --list # show all configured profilesThe default profile (~/.rspacectl) is used when --profile is omitted — fully backward compatible.
For better security, store credentials in the OS keychain (macOS Keychain, Windows Credential Manager, Linux Secret Service) instead of a plain-text file. Requires the optional keyring dependency:
pip install -e ".[keychain]" # or: poetry install -E keychain
rspace configure --keychain # store default profile in keychain
rspace configure --profile prod --keychain # named profile in keychainCredentials stored in the keychain never appear in files, environment variables, or process arguments — recommended for agentic and CI use.
For every invocation, credentials are resolved in this order (first match wins):
--url/--api-keyCLI flagsRSPACE_URL/RSPACE_API_KEYenvironment variables- OS keychain
- Profile dotenv file (
~/.rspacectlor~/.rspacectl.<profile>)
Create ~/.rspacectl:
RSPACE_URL=https://your-rspace-instance.com
RSPACE_API_KEY=your-api-key-hererspace statusEvery command accepts -o / --output:
| Format | Flag | Description |
|---|---|---|
| Table | -o table |
Rich formatted table (default) |
| JSON | -o json |
Pretty-printed JSON |
| CSV | -o csv |
RFC 4180 CSV to stdout |
| Quiet | -o quiet |
IDs only, one per line — useful for piping |
# Pipe document IDs into another command
rspace list documents -o quiet | xargs -I{} rspace get {}rspace list documents
rspace list documents --query "CRISPR" --tag "methods" --page 1 --page-size 50
rspace list documents --order-by name --sort-order asc
rspace list notebooks
rspace list folders --parent FL123
rspace list samples
rspace list samples --query "buffer" --owned-by alice --page 0 --page-size 20
rspace list subsamples --query "aliquot"
rspace list containers --query "freezer"
rspace list templates
rspace list files --type document
rspace list forms
rspace list groups
rspace list users # sysadmin only
rspace list activity --from 2024-01-01 --to 2024-03-31 --action CREATE
rspace list workbenchesA pagination footer is shown after every paginated result:
Showing 1–20 of 143 (page 0, use --page / --page-size to navigate)
The resource type is inferred automatically from the GlobalID prefix:
rspace get SD123 # document
rspace get NB456 # notebook
rspace get FL789 # folder
rspace get SA101 # sample
rspace get SS202 # subsample
rspace get IC303 # container
rspace get BE404 # workbench
rspace get IT505 # sample template
rspace get FM606 # form
rspace get GL707 # gallery fileFor plain numeric IDs, provide the type explicitly:
rspace get document 123
rspace get sample 456Additional flags for richer output:
rspace get SA101 --subsamples # sample detail + subsample list
rspace get IC303 --content # container detail + contents
rspace get BE404 --content # workbench detail + contents
rspace get NB456 --content # notebook detail + document list
rspace get FL789 --content # folder detail + document listrspace create document --name "My Experiment" --form FM123
rspace create notebook --name "Project Alpha"
rspace create folder --name "Data" --parent FL456
rspace create sample --name "Buffer A"
rspace create sample --name "Buffer A" --template IT101 # use a template
# populate template fields (use `rspace get template IT101` to see field names)
rspace create sample --name "Enzyme X" --template IT101 \
--field "pH=7.4" --field "Source=Commercial"
rspace create sample --from-csv samples.csv # bulk create from CSV
rspace create container --name "Freezer 1" --type list
rspace create container --name "Box A" --type grid --rows 9 --cols 9
rspace create user --username jdoe --email j.doe@example.com \
--first-name Jane --last-name Doe # sysadmin only; prompts for passwordrspace update document SD123 --name "Revised Experiment"
rspace update document SD123 --tag "lab,2024,validated"
rspace update document SD123 --append "<p>Additional notes</p>"
# Target a specific form field
rspace update document SD123 --content "<p>New text</p>" --field-id 456
rspace update document SD123 --append "<p>Addendum</p>" --field-index 2
rspace update sample SA456 --name "Buffer A v2" --description "pH 7.4"
rspace update sample SA456 --tag "reagent,validated"--field-id targets a field by its numeric ID (use rspace get SD123 -o json to find IDs).
--field-index targets a field by 0-based position (for --append / --prepend).
rspace tag SD123 "lab,experiment,2024"
rspace tag NB456 "methods,protocols"
rspace tag SA789 "reagent,validated"
rspace tag SS101 "aliquot,stock"
rspace tag IC202 "freezer,-80C"
rspace tag IT303 "template,approved"Accepts any GlobalID — the resource type is inferred from the prefix. Replaces all existing tags.
rspace delete document SD123 SD456 SD789 # batch delete
rspace delete sample SA101
rspace delete subsample SS202 SS203
rspace delete container IC303rspace search "CRISPR protocol"
rspace search "buffer" --type inventory
rspace search "PCR" --type eln# List container
rspace move SS101 SS102 --target IC303
# Grid container — auto-fill by row or column
rspace move SS101 SS102 --target IC404 --strategy row
rspace move SS101 SS102 --target IC404 --strategy column
# Grid container — exact placement
rspace move SS101 --target IC404 --row 2 --col 3# Upload a file to the gallery
rspace upload file ./data.csv
# Attach a file to an inventory item
rspace upload attachment ./spec.pdf SS101
# Download a gallery file
rspace download file GL606 --output-dir ./downloads
# Download an inventory attachment
rspace download attachment IF707 --output-dir ./downloadsrspace split SS202 --count 4 # split into 4 equal parts
rspace split SS202 --count 4 --target IC303 # split and place in containerrspace share SD123 --group-id 5 --permission readrspace export --format xml --scope user
rspace export --format html --scope selection --id SD123 --id SD456
rspace export --format xml --scope user --no-wait # start job, don't waitrspace import word report.docx notes.docx --folder FL123
rspace import tree ./my-lab-data --folder FL123Take a snapshot of inventory on one server and recreate it on another. Useful for:
- Selective transfers — copy a freezer rack and its samples to a collaborator's instance, share a curated set of templates with a sister lab, or seed a test server with realistic data
- Full migrations — move everything when consolidating instances or upgrading
- Snapshots — keep a local file-system copy of an inventory subtree
Templates, containers (full hierarchy), samples, subsamples, attachments, preview images, template icons, and IMAGE-container backgrounds with marker locations are all preserved.
# Selective: a single container and everything inside it
rspace --profile source migrate export --container IC123 --output ./freezer_a
rspace --profile target migrate import ./freezer_a
# Selective: pick specific templates and samples (referenced templates auto-included)
rspace --profile source migrate export --template IT5 --sample SA42 --output ./partial
# Multiple selectors compose
rspace --profile source migrate export \
--container IC100 --container IC200 --template IT5 \
--output ./teams_handoff
# Full inventory
rspace --profile source migrate export --all --output ./full_snapshot
rspace --profile target migrate import ./full_snapshot
# Preview an import without making any changes
rspace --profile target migrate import ./freezer_a --dry-runWhen you select a container, the entire subtree (sub-containers, subsamples, and the parent samples those subsamples belong to) is included automatically. When you select samples, the templates they depend on are pulled in too.
my_snapshot/
snapshot.json inventory data (templates, containers, samples)
attachments/SA123/... per-item file attachments
images/SA123_preview.png preview images for samples / subsamples / containers / templates
icons/IT12_icon template icons
image_containers/ IMAGE-container backgrounds + marker positions
checkpoint.json created during import; auto-deleted on success
The importer runs in ordered phases, writing a checkpoint after each so an interrupted run can resume cleanly:
- Templates — created with id-mapping recorded
- Containers (flat) — all containers created at the top level (IMAGE containers get their background image + markers via a separate PUT)
- Container hierarchy — containers moved into their parents
- Samples — created from the mapped template; field values, tags, subsample names, quantities, notes restored
- Subsample placements — subsamples moved to their original containers (grid coords for GRID, marker index for IMAGE)
- Attachments — files re-uploaded to their new owner globalIds
- Preview images —
set_imagecalled for templates / samples / subsamples / containers (default thumbnails are deduplicated) - Template icons —
set_sample_template_iconcalled per template
# Resume an interrupted import
rspace migrate import ./freezer_a --checkpoint ./freezer_a/checkpoint.json
# Skip phases (e.g. data-only, no files)
rspace migrate import ./freezer_a --skip-files
rspace migrate import ./freezer_a --skip-templates --skip-containers
# Data-only export (no attachments / images / icons)
rspace migrate export --container IC123 --output ./data_only --no-files--outputsemantics differ from other commands: inmigrate export,--outputis the snapshot directory (not an output format). The-o/--outputtable/json/csv/quiet flag does not apply.- Workbench items (
BEprefix) cannot be migrated — workbenches are per-user. Subsamples on a source workbench are reported and remain unplaced after import. - Selecting a container pulls its full subtree. Sub-containers, subsamples, and the parent samples those subsamples belong to are auto-included so the imported subtree is internally consistent.
- Backward compat: legacy plain-JSON snapshots produced before the directory format are still importable via
rspace migrate import old_snapshot.json(no attachments will be restored). - Default thumbnails are skipped: RSpace's content-addressed image storage reuses the same hash for every item without a custom preview, so the migrator deduplicates these to avoid re-uploading hundreds of identical placeholders.
| Prefix | Resource type |
|---|---|
SD |
Document |
NB |
Notebook |
FL |
Folder |
SA |
Sample |
SS |
Subsample |
IC |
Container |
IT |
Sample template |
IF |
Inventory file (attachment) |
FM |
Form |
GL |
Gallery file |
BE |
Workbench |
# Install with dev dependencies
poetry install
# With optional keychain support
poetry install -E keychain
# Run tests
poetry run pytest
# Format and lint
poetry run black rspacectl tests
poetry run ruff check rspacectl tests