Skip to main content
Pre-release

This release is a pre-release and may not be stable for production use.

qualia-cli — terminal client for the Qualia robotics data and VLA platform

Status: beta (0.3.0rc2) · Published: PyPI, qualia-cli

Wraps the public Qualia API: authenticate once, then manage projects, import datasets, launch fine-tuning jobs and follow their progress from a shell. Every command takes --json, so the same surface works interactively and in CI.

The CLI and the endpoint it talks to negotiate the upload protocol exactly, so a deployment running ahead of the public release needs the matching pre-release wheel. See Install below.

Install

pip install qualia-cli

Or with uv:

uv tool install qualia-cli

Pre-release builds

Pin the wheel that matches the endpoint's generation. The current release candidate is 0.3.0rc2; if your deployment is on a different one, swap it in.

pip install 'qualia-cli==0.3.0rc2'

uv does not resolve a pre-release through a dependency, even one that names it, so uv needs the flag as well as the pin:

uv tool install --prerelease=allow 'qualia-cli==0.3.0rc2'

Usage

# Authenticate (pick one)
qualia auth login                        # interactive, saves to config
export QUALIA_API_KEY="your-api-key"     # env var
qualia --token <KEY> <command>           # inline, for CI/scripts

# List available models
qualia model list

# List GPU instances
qualia instance list

# Create a project
qualia project create "My Robot"

# Start a fine-tuning job
qualia job launch \
  --project-id <id> \
  --vla-type pi05 \
  --model-id lerobot/pi05_base \
  --dataset-version-id <DATASET_VERSION_UUID> \
  --hours 2.0 \
  --camera-mappings '{"cam_1": "observation.images.top"}'

# Check job status
qualia job get <job-id>
# A failed job also prints who caused it (your side or ours), what, why, and its credits

# Upload a recorded MCAP session; a session no bag can derive is refused
# before upload unless you pass --allow-underivable
qualia dataset upload ./session dk1-kitchen --source-format mcap_ros2
# exits 0 published/degraded, 1 nothing uploaded, 3 stored but no episode derived

# A teleop arm needs no config when its state is a JointState topic named
# joint_state(s) and its action is a JointTrajectory topic, or a JointState or
# MultiArray topic named cmd, command or action. In <session>/meta/ingest.toml,
# declare [actions] alone when a topic named like a command is operator input
# (a joystick), and both [state] and [actions] when a second JointState topic
# (a leader arm) would be read as state, or the rig publishes poses and has no
# JointState:
#   schema = 1
#   [state]
#   topics = ["/controller/left/pose", "/controller/right/pose"]
#   [actions]
#   topics = []   # no action column
# Fields are carried as recorded, with no rotation conversion. [clock] takes
# row_clock_topic or fixed_hz, not both.
# Guide: https://docs.qualiastudios.dev/global/guides/data-collection
# A successful upload prints the topics that fed state and action, and says
# "action: none (no action column)" when there is none. --quiet still prints them.

# LeRobot trees are checked before upload too. A structural problem the server
# always refuses (bad meta/info.json, codebase_version not matching
# --source-format, no parquet under data/, v2.1 without episodes.jsonl or
# tasks.jsonl) exits 1 with nothing uploaded; --allow-underivable cannot
# override it. A missing video only warns, naming the episode and camera; the
# upload continues and that episode will be flagged (you should probably
# exclude it).
qualia dataset upload ./my-recording my-dataset --source-format lerobot_v3

# List your uploads; Verdict is published | degraded | underivable. With your account set
# (see Tasks below) it reads qualia.v1 and --json prints qualia.v1 Datasets (reason:
# verdict_reason); without one it reads the older route (reason: qds.verdict_reason).
qualia dataset list

# Filter the account-scoped list by any canonical method tag.
qualia dataset list --method umi --method teleop

# Replace the canonical method-tag set on an upload or merged dataset. A
# merged dataset writes the same set to every upload it holds; --clear records
# an explicit Unknown rather than leaving tags unset.
qualia dataset methods <dataset-uuid> --method umi --method teleop
qualia dataset methods <dataset-uuid> --clear

# Cut episodes into child episodes at their markers, or, where the recorder
# marked nothing, at instants (seconds from the start of the recording, the
# same instants in each named episode). --dry-run plans without writing;
# `qualia dataset unsplit` undoes it. A request cuts at markers or at
# instants, not both.
qualia dataset split <episode> -d <dataset> --cut-at success --dry-run
qualia dataset split <episode> -d <dataset> --at 12.5 --at 31 --dry-run

# Import an exact Hugging Face dataset commit. HF_TOKEN is read from the
# environment or the Hub's protected local credential store, never an argv flag.
export HF_TOKEN="..."  # omit for public datasets
qualia dataset import-hf \
  qualia-robotics/openarm-cube-in-box-v1 \
  17c29c487d886878ddcb3c5649101b2860fbc047 \
  openarm-cube-in-box \
  --source-format lerobot_v3

Tasks

Tasks say what a robot should do and how success shows, as five pieces of prose: description, scene, steps (one per line), success and failure. They live under your account: pass --account <UUID>, set QUALIA_ACCOUNT, or save it with qualia auth login --account <UUID>.

qualia task create --name "Restock shelf" -d "Move every box from the tray to the shelf"
qualia task edit <task-id> --steps $'Pick a box from the tray\nPlace it upright on the shelf' \
  --success "The tray is empty and every box stands upright"
                                               # just those fields; "" clears one

# Or author the five fields as a file, as `qualia task get <id> --json` prints
# a task (displayName, etag, draft) or as a bare spec:
cat > shelf.yaml <<'EOF'
description: Move every box from the tray to the shelf
scene: A tray of six boxes beside a two-level wire shelf
steps: |
  Pick a box from the tray
  Place it upright on the shelf
success: The tray is empty and every box stands upright
failure: A box falls over or drops to the floor
EOF
qualia task edit <task-id> shelf.yaml          # replaces the whole draft

# A spec file may also hold an optional procedure: the task as a state machine of
# steps and transitions, checked when the task is published.
cat >> shelf.yaml <<'EOF'
procedure:
  steps:
    - {id: start, kind: START, description: Boxes in the tray}
    - {id: place, description: Place a box upright on the shelf, min_count: 6, max_count: 6}
    - {id: shelved, kind: SUCCESS, description: All boxes shelved}
    - {id: fallen, kind: FAILURE, description: A box fell over}
  transitions:
    - {source: start, target: place}
    - {source: place, target: shelved}
    - {source: place, target: fallen}
EOF
qualia task edit <task-id> shelf.yaml

qualia task get <task-id>                      # each field under its heading, then the procedure
qualia task publish <task-id> -m "first cut"   # needs a description and a success
qualia task revisions <task-id>
qualia task get <task-id> --revision 1
qualia task list
qualia task delete <task-id> [--force]         # account owners only

JSON output

All commands support --json for machine-readable output:

qualia project list --json
qualia credit --json

API

The CLI is a client for the public Qualia API. Request and response shapes for every command are in the API reference: https://docs.qualiastudios.dev

Working in the repo instead? sdk/cli/qualia-cli.spec.md carries the same contract, and the gateway generates the OpenAPI spec it is drawn from. Neither ships in the wheel.

License

MIT, Qualia Studios.

Metadata

Release files for qualia-cli 0.3.0rc2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for qualia-cli 0.3.0rc2
File Size Uploaded Provenance
qualia_cli-0.3.0rc2.tar.gz 113.7 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for qualia-cli 0.3.0rc2
File Interpreter ABI Platform
qualia_cli-0.3.0rc2-py3-none-any.whl Python 3 none any Details

Total release size: 152.8 kB

Release files / qualia_cli-0.3.0rc2.tar.gz

Download URL qualia_cli-0.3.0rc2.tar.gz
Size 113.7 kB
Tags Source
SHA-256 checksum
How to use checksums
55fd2a94d4da67e83c0c4d79679814ac2a996f24ca0ed40ddb7dbdfa9f34077d
BLAKE2b-256 checksum
How to use checksums
6b4044cb620c04ec66066ad4095d7a5c7858e2c2c0e698dfb28089c14f7b396d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.9.17 {"installer":{"name":"uv","version":"0.9.17","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Alpine Linux","version":"3.23.0","id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / qualia_cli-0.3.0rc2-py3-none-any.whl

Download URL qualia_cli-0.3.0rc2-py3-none-any.whl
Size 39.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
5d41c267ae31dfc69d57618e1c1bd4d9df04fd7de425c2e54e0ff574c0043745
BLAKE2b-256 checksum
How to use checksums
62badaa1fa1de3b93120d9db7dd68677e51a0f1888e21487780551bf22408a09
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.9.17 {"installer":{"name":"uv","version":"0.9.17","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Alpine Linux","version":"3.23.0","id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Security for qualia-cli 0.3.0rc2

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page