Manage experiments, artifacts, and metadata from your terminal with diffuse.
The CLI mirrors the web interface and provides scriptable access to all Diffuse functionality.
uv first: brew install uvInstall the Diffuse CLI in two simple steps:
git clone https://github.com/diff-use/webapp.git
cd webapp/cli
uv tool install .
diffuse --help
Authenticate with GitHub to access private experiments and perform write operations:
| Command | Description |
|---|---|
diffuse auth login |
Login via GitHub device flow |
diffuse auth status |
Check authentication and API health |
diffuse auth logout |
Clear stored credentials |
$ diffuse auth login
============================================================
Visit: https://github.com/login/device
Enter code: ABCD-1234
============================================================
Waiting for authorization (expires in 900s)...
✓ Authentication successful!
# Get your token from ~/.diffuse/config.json
TOKEN=$(cat ~/.diffuse/config.json | jq -r '.github_token')
# Check authentication status
curl -H "Authorization: Bearer $TOKEN" \
https://dev.diffuse.science/api/whoami
Create, view, edit, and manage experiments from the command line:
| Command | Description |
|---|---|
diffuse list |
List all experiments |
diffuse view <id> |
View experiment details |
diffuse create |
Create a new experiment |
diffuse edit <id> |
Edit an experiment |
diffuse delete <id> |
Delete an experiment |
diffuse publish <id> |
Publish to public catalog |
diffuse unpublish <id> |
Unpublish from catalog |
# List all experiments
diffuse list
# Filter by public/private
diffuse list --public
diffuse list --private
# Sort experiments
diffuse list --sort recent
diffuse list --sort title
# Filter by metadata
diffuse list --filter dataset:mnist --filter epoch:100
# Output as JSON
diffuse list --format json
curl https://dev.diffuse.science/api/experiments
# Interactive prompt
diffuse create
# With flags
diffuse create \
--title "ResNet Training Run" \
--summary "Training ResNet-50 on ImageNet" \
--tags "vision,resnet,imagenet"
# With markdown file
diffuse create \
--title "Experiment Log" \
--markdown ./experiment.md
curl -X POST https://dev.diffuse.science/api/experiments \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"title": "ResNet Training Run",
"summary": "Training ResNet-50 on ImageNet",
"tags": ["vision", "resnet", "imagenet"]
}'
# View experiment details
diffuse view EXP-123
# Output as JSON
diffuse view EXP-123 --format json
curl https://dev.diffuse.science/api/experiments/EXP-123
# Update title or summary
diffuse edit EXP-123 --title "Updated Title"
diffuse edit EXP-123 --summary "New summary"
# Update tags
diffuse edit EXP-123 --tags "new,tags,here"
# Open markdown in $EDITOR
diffuse edit EXP-123 --editor
# Update from markdown file
diffuse edit EXP-123 --markdown ./updated.md
curl -X PATCH https://dev.diffuse.science/api/experiments/EXP-123 \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"title": "Updated Title",
"summary": "New summary"
}'
# Publish experiment
diffuse publish EXP-123
# Unpublish experiment
diffuse unpublish EXP-123
# Publish
curl -X POST https://dev.diffuse.science/api/experiments/EXP-123/publish \
-H "Authorization: Bearer $TOKEN"
# Unpublish
curl -X POST https://dev.diffuse.science/api/experiments/EXP-123/unpublish \
-H "Authorization: Bearer $TOKEN"
Upload artifacts and download experiment data:
| Command | Description |
|---|---|
diffuse upload <id> <file> |
Upload a file to experiment |
diffuse download <id> <name> |
Download an artifact |
# Upload a file
diffuse upload EXP-123 ./model.pth
# Upload with metadata
diffuse upload EXP-123 ./model.pth \
--metadata ./metadata.json \
--content-type "application/octet-stream"
# 1. Create upload session
curl -X POST https://dev.diffuse.science/api/uploads/session \
-H "Content-Type: application/json" \
-d '{
"experiment_id": "EXP-123",
"filename": "model.pth",
"content_type": "application/octet-stream",
"size_bytes": 102400,
"metadata_document": {}
}'
# 2. Upload chunks to presigned URLs (from response above)
# Upload each part to its presigned URL
curl -X PUT "$PRESIGNED_URL_PART_1" \
--data-binary @model.pth.part1 \
-H "Content-Type: application/octet-stream"
# Capture ETag from response headers for finalization
# ETag: "abc123..."
# 3. Finalize upload
curl -X POST https://dev.diffuse.science/api/uploads/sess_xyz/finalize \
-H "Content-Type: application/json" \
-d '{
"session_id": "sess_xyz",
"parts": [
{"part_number": 1, "etag": "abc123"},
{"part_number": 2, "etag": "def456"}
],
"metadata_document": {}
}'
# Download artifact
diffuse download EXP-123 model.pth
# Save to specific location
diffuse download EXP-123 model.pth --output ./downloads/model.pth
# Get presigned download URL
curl https://dev.diffuse.science/api/experiments/EXP-123/artifacts/model.pth/download \
-H "Authorization: Bearer $TOKEN"
# Download file using the presigned URL from response
curl -o model.pth "$PRESIGNED_DOWNLOAD_URL"
View and manage experiment metadata fields:
| Command | Description |
|---|---|
diffuse metadata get <id> |
Get experiment metadata |
diffuse metadata set <id> <key> <value> |
Set a metadata field |
diffuse metadata apply <id> -f <file> |
Apply metadata from file |
diffuse metadata fields |
List available field definitions |
# Set individual field
diffuse metadata set EXP-123 learning_rate 0.001
# Get all metadata
diffuse metadata get EXP-123
# Apply from JSON file
echo '{"learning_rate": 0.001, "batch_size": 32}' > metadata.json
diffuse metadata apply EXP-123 -f metadata.json
# Set metadata
curl -X PATCH https://dev.diffuse.science/api/experiments/EXP-123/metadata \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"metadata": {
"learning_rate": 0.001,
"batch_size": 32
}
}'
# Get metadata
curl https://dev.diffuse.science/api/experiments/EXP-123/metadata
# View last 20 activities
diffuse activity
# Limit results
diffuse activity --limit 50
# Output as JSON
diffuse activity --format json
curl -H "Authorization: Bearer $TOKEN" \
https://dev.diffuse.science/api/activity
Manage CLI configuration stored in ~/.diffuse/config.json:
| Command | Description |
|---|---|
diffuse config view |
View current configuration |
diffuse config set <key> <value> |
Set configuration value |
diffuse config reset |
Reset configuration |
# View config
diffuse config view
# Set custom API server
diffuse config set api_url https://diffuse.mycompany.com
# Use custom server with --server flag
diffuse list --server https://diffuse.mycompany.com
# Or set DIFFUSE_API_URL environment variable
export DIFFUSE_API_URL=https://diffuse.mycompany.com
diffuse list
~/.diffuse/config.json with restricted permissions (0600). Never commit this file to version control.The CLI is designed for scripting and CI/CD integration:
#!/bin/bash
# Create experiment and upload results
EXP_ID=$(diffuse create \
--title "Automated Run $(date +%Y%m%d)" \
--tags "automation,ci" \
--format json | jq -r '.id')
echo "Created experiment: $EXP_ID"
# Upload training artifacts
diffuse upload $EXP_ID ./model.pth
diffuse upload $EXP_ID ./metrics.json
# Set metadata
diffuse metadata set $EXP_ID commit_sha $GITHUB_SHA
diffuse metadata set $EXP_ID build_number $BUILD_NUMBER
# Publish if successful
if [ $? -eq 0 ]; then
diffuse publish $EXP_ID
fi
name: Train and Track
on: [push]
jobs:
train:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Install uv
run: curl -LsSf https://astral.sh/uv/install.sh | sh
- name: Install Diffuse CLI
run: |
git clone https://github.com/diff-use/webapp.git /tmp/diffuse
cd /tmp/diffuse/cli
uv tool install .
- name: Authenticate
run: |
mkdir -p ~/.diffuse
echo '{"github_token": "${{ secrets.DIFFUSE_TOKEN }}"}' > ~/.diffuse/config.json
- name: Create experiment
run: |
EXP_ID=$(diffuse create --title "Run ${{ github.run_number }}" --format json | jq -r '.id')
echo "EXP_ID=$EXP_ID" >> $GITHUB_ENV
- name: Train model
run: python train.py
- name: Upload results
run: diffuse upload ${{ env.EXP_ID }} ./model.pth