Skip to main content
This page provides real-world examples of using the CVAT CLI for common annotation workflows.

Prerequisites

Before running these examples:
  1. Install CVAT CLI: pip install cvat-cli
  2. Set up authentication (recommended):
    export CVAT_ACCESS_TOKEN="your-token-here"
    
  3. Have access to a CVAT server (local or remote)

Basic Workflows

Simple Image Annotation Workflow

Create a task, annotate it (manually in the web UI), then export the results.
#!/bin/bash

# Configuration
SERVER="--server-host http://localhost:8080"
AUTH="--auth admin:password"

# Create project with labels
PROJECT_ID=$(cvat-cli $AUTH $SERVER project create "Vehicle Detection" \
  --labels '[{"name": "car"}, {"name": "truck"}, {"name": "bus"}]')

echo "Created project ID: $PROJECT_ID"

# Create task with images
TASK_ID=$(cvat-cli $AUTH $SERVER task create \
  "Highway Images" \
  local \
  ./images/*.jpg \
  --project_id $PROJECT_ID \
  --image_quality 90)

echo "Created task ID: $TASK_ID"
echo "Annotate task at: http://localhost:8080/tasks/$TASK_ID"

# After annotation in web UI, export dataset
read -p "Press enter after annotation is complete..."

cvat-cli $AUTH $SERVER task export-dataset $TASK_ID \
  ./output/dataset.zip \
  --format "COCO 1.0" \
  --with-images true

echo "Dataset exported to ./output/dataset.zip"

Video Annotation Workflow

Annotate specific frames from a video.
#!/bin/bash

# Create task from video, sampling every 10th frame
TASK_ID=$(cvat-cli --auth user task create \
  "Traffic Video Analysis" \
  local \
  traffic.mp4 \
  --labels '[{"name": "vehicle"}, {"name": "pedestrian"}]' \
  --frame_step 10 \
  --start_frame 0 \
  --stop_frame 1000)

echo "Created task ID: $TASK_ID"

# Download specific frames for inspection
mkdir -p frames
cvat-cli --auth user task frames $TASK_ID 0 10 20 30 40 50 \
  --outdir ./frames \
  --quality original

echo "Frames downloaded to ./frames/"

Batch Processing Multiple Datasets

Create multiple tasks from different directories.
#!/bin/bash

# Create project
PROJECT_ID=$(cvat-cli --auth user project create "Batch Processing" \
  --labels '[{"name": "object"}]')

echo "Created project: $PROJECT_ID"

# Process multiple directories
for dir in dataset1 dataset2 dataset3; do
  echo "Processing $dir..."
  
  TASK_ID=$(cvat-cli --auth user task create \
    "Task from $dir" \
    local \
    ./$dir/*.jpg \
    --project_id $PROJECT_ID \
    --image_quality 85)
  
  echo "  Created task: $TASK_ID"
done

# List all tasks in project
echo "\nAll tasks:"
cvat-cli --auth user task ls

Advanced Workflows

Pre-annotation and Review Pipeline

Import pre-annotations, review them, then export.
#!/bin/bash

# Step 1: Create task
echo "Creating task..."
TASK_ID=$(cvat-cli --auth user task create \
  "Pre-annotated Dataset" \
  local \
  ./images/*.jpg \
  --labels '[{"name": "person"}, {"name": "vehicle"}]')

echo "Task ID: $TASK_ID"

# Step 2: Import existing annotations
echo "Importing pre-annotations..."
cvat-cli --auth user task import-dataset $TASK_ID \
  ./pre_annotations/coco.json \
  --format "COCO 1.0"

echo "Pre-annotations imported. Review at: http://localhost/tasks/$TASK_ID"

# Step 3: After manual review, export final annotations
read -p "Press enter after review is complete..."

echo "Exporting final dataset..."
cvat-cli --auth user task export-dataset $TASK_ID \
  ./output/final_annotations.zip \
  --format "YOLO 1.1" \
  --with-images false

echo "Export complete!"

Backup and Migration

Backup tasks from one server and restore to another.
#!/bin/bash

# Backup from production server
echo "Backing up from production..."
SOURCE_SERVER="--server-host https://cvat-prod.company.com"
SOURCE_AUTH="--auth user:prod_pass"

mkdir -p backups

# Backup multiple tasks
for TASK_ID in 10 11 12; do
  echo "Backing up task $TASK_ID..."
  cvat-cli $SOURCE_AUTH $SOURCE_SERVER task backup $TASK_ID \
    ./backups/task_${TASK_ID}_backup.zip
done

# Restore to development server
echo "\nRestoring to development server..."
DEST_SERVER="--server-host http://localhost:8080"
DEST_AUTH="--auth admin:dev_pass"

for backup_file in ./backups/*.zip; do
  echo "Restoring $backup_file..."
  NEW_TASK_ID=$(cvat-cli $DEST_AUTH $DEST_SERVER \
    task create-from-backup $backup_file)
  echo "  Restored as task: $NEW_TASK_ID"
done

Auto-annotation Pipeline

Create tasks, auto-annotate them, and export results. detector.py:
"""Simple auto-annotation function for CVAT."""
import cvat_sdk.auto_annotation as cvataa

def spec():
    return cvataa.DetectionFunctionSpec(
        labels=[
            cvataa.label_spec("car", 0),
            cvataa.label_spec("person", 1),
        ]
    )

def detect(context, image):
    # Your detection logic here
    # This is a placeholder example
    results = [
        cvataa.rectangle(0, [100, 100, 200, 200]),  # car
        cvataa.rectangle(1, [300, 300, 400, 400]),  # person
    ]
    return results
Pipeline script:
#!/bin/bash

# Create task
echo "Creating task..."
TASK_ID=$(cvat-cli --auth user task create \
  "Auto-annotated Task" \
  local \
  ./images/*.jpg \
  --labels '[{"name": "car"}, {"name": "person"}]')

echo "Task ID: $TASK_ID"

# Run auto-annotation
echo "Running auto-annotation..."
cvat-cli --auth user task auto-annotate $TASK_ID \
  --function-file ./detector.py \
  --clear-existing \
  --conf-threshold 0.5

echo "Auto-annotation complete!"

# Export results
echo "Exporting dataset..."
cvat-cli --auth user task export-dataset $TASK_ID \
  ./output/auto_annotated.zip \
  --format "COCO 1.0" \
  --with-images true

echo "Done! Dataset saved to ./output/auto_annotated.zip"

Multi-Organization Workflow

Work with tasks across different organizations.
#!/bin/bash

# Function to create task in organization
create_org_task() {
  local ORG=$1
  local TASK_NAME=$2
  
  echo "Creating task '$TASK_NAME' in organization '$ORG'..."
  
  TASK_ID=$(cvat-cli --auth user --org $ORG task create \
    "$TASK_NAME" \
    local \
    ./data/*.jpg \
    --labels '[{"name": "object"}]')
  
  echo "  Task ID: $TASK_ID"
}

# Create tasks in different organizations
create_org_task "team-alpha" "Alpha Dataset"
create_org_task "team-beta" "Beta Dataset"
create_org_task "team-gamma" "Gamma Dataset"

# List tasks per organization
echo "\nTasks in team-alpha:"
cvat-cli --auth user --org team-alpha task ls

echo "\nTasks in team-beta:"
cvat-cli --auth user --org team-beta task ls

# List all accessible tasks (across all orgs)
echo "\nAll accessible tasks:"
cvat-cli --auth user task ls

Format Conversion

Convert Between Annotation Formats

Export a task in one format and import into another task in a different format.
#!/bin/bash

# Export task in COCO format
echo "Exporting task 10 in COCO format..."
cvat-cli --auth user task export-dataset 10 \
  coco_export.zip \
  --format "COCO 1.0"

# Create new task for YOLO format
echo "Creating new task for YOLO..."
TASK_ID=$(cvat-cli --auth user task create \
  "YOLO Format Task" \
  local \
  ./images/*.jpg \
  --labels '[{"name": "object"}]')

# Convert and import (manual conversion needed here)
# python convert_coco_to_yolo.py coco_export.zip yolo_annotations.zip

echo "Import YOLO annotations to task $TASK_ID"
# cvat-cli --auth user task import-dataset $TASK_ID \
#   yolo_annotations.zip \
#   --format "YOLO 1.1"

Export All Tasks in a Project

Export every task in a project.
#!/bin/bash

PROJECT_ID=5

# Get list of task IDs (requires jq for JSON parsing)
TASK_IDS=$(cvat-cli --auth user task ls --json | \
  jq -r ".[] | select(.project_id == $PROJECT_ID) | .id")

echo "Found tasks: $TASK_IDS"

mkdir -p exports

# Export each task
for TASK_ID in $TASK_IDS; do
  echo "Exporting task $TASK_ID..."
  cvat-cli --auth user task export-dataset $TASK_ID \
    ./exports/task_${TASK_ID}_export.zip \
    --format "CVAT for images 1.1" \
    --with-images false
done

echo "All exports complete in ./exports/"

Environment-Specific Examples

Development Environment Script

Script configured for local development.
#!/bin/bash
# dev-workflow.sh

# Development server configuration
export CVAT_ACCESS_TOKEN="dev-token-12345"
DEV_SERVER="--server-host http://localhost:8080"

# Helper function
cvat-dev() {
  cvat-cli $DEV_SERVER "$@"
}

# Quick task creation
quick-task() {
  local TASK_NAME=$1
  shift
  cvat-dev task create "$TASK_NAME" local "$@" \
    --labels '[{"name": "object"}]'
}

# Usage examples:
# quick-task "Test Task" ./images/*.jpg
# cvat-dev task ls
# cvat-dev project create "Test Project"

Production Environment Script

Script configured for production server.
#!/bin/bash
# prod-workflow.sh

# Production server configuration
export CVAT_ACCESS_TOKEN="prod-token-67890"
PROD_SERVER="--server-host https://cvat.company.com"
PROD_ORG="--org production-team"

# Helper function
cvat-prod() {
  cvat-cli $PROD_SERVER $PROD_ORG "$@"
}

# Create project with detailed labels
create-prod-project() {
  local PROJECT_NAME=$1
  local LABELS_FILE=$2
  
  if [ ! -f "$LABELS_FILE" ]; then
    echo "Error: Labels file not found: $LABELS_FILE"
    return 1
  fi
  
  cvat-prod project create "$PROJECT_NAME" \
    --labels @"$LABELS_FILE" \
    --bug_tracker "https://jira.company.com/projects/CVAT"
}

# Usage:
# create-prod-project "Q1 Dataset" labels.json
# cvat-prod task ls

Automation Examples

Scheduled Backup Script

Automate regular backups of all tasks.
#!/bin/bash
# backup-all-tasks.sh

BACKUP_DIR="/backups/cvat/$(date +%Y-%m-%d)"
mkdir -p "$BACKUP_DIR"

echo "Starting backup to $BACKUP_DIR"

# Get all task IDs
TASK_IDS=$(cvat-cli --auth user task ls --json | jq -r '.[].id')

for TASK_ID in $TASK_IDS; do
  echo "Backing up task $TASK_ID..."
  
  cvat-cli --auth user task backup $TASK_ID \
    "$BACKUP_DIR/task_${TASK_ID}.zip" || \
    echo "Failed to backup task $TASK_ID"
done

# Clean up old backups (keep last 7 days)
find /backups/cvat -type d -mtime +7 -exec rm -rf {} \;

echo "Backup complete!"

Continuous Integration Example

Validate annotations in CI/CD pipeline.
#!/bin/bash
# .github/workflows/validate-annotations.sh

set -e

echo "Downloading task annotations..."
cvat-cli --auth $CVAT_USER:$CVAT_PASS \
  --server-host $CVAT_SERVER \
  task export-dataset $TASK_ID \
  annotations.zip \
  --format "COCO 1.0"

echo "Validating annotations..."
python validate_coco.py annotations.zip

if [ $? -eq 0 ]; then
  echo "✓ Validation passed"
  exit 0
else
  echo "✗ Validation failed"
  exit 1
fi

Tips and Best Practices

Using Configuration Files

Create a config file for common settings: cvat-config.sh:
export CVAT_ACCESS_TOKEN="your-token"
export CVAT_SERVER="https://cvat.example.com"
export CVAT_ORG="my-team"

alias cvat='cvat-cli --server-host $CVAT_SERVER --org $CVAT_ORG'
Source it before running commands:
source cvat-config.sh
cvat task ls

Error Handling

Add error handling to scripts:
#!/bin/bash

set -e  # Exit on error
set -u  # Exit on undefined variable
set -o pipefail  # Exit on pipe failure

trap 'echo "Error on line $LINENO"' ERR

# Your commands here

Logging

Add logging to track operations:
#!/bin/bash

LOG_FILE="cvat-operations.log"

log() {
  echo "[$(date +'%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE"
}

log "Starting task creation..."
TASK_ID=$(cvat-cli --auth user task create "Task" local img.jpg \
  --labels '[{"name": "obj"}]')
log "Created task: $TASK_ID"

Parallel Processing

Process multiple tasks in parallel:
#!/bin/bash

# Export multiple tasks in parallel
export_task() {
  local TASK_ID=$1
  echo "Exporting task $TASK_ID..."
  cvat-cli --auth user task export-dataset $TASK_ID \
    "task_${TASK_ID}.zip" --format "COCO 1.0"
}

export -f export_task

# Process tasks in parallel (requires GNU parallel)
echo "10 11 12 13 14" | tr ' ' '\n' | parallel -j 4 export_task

Next Steps

Build docs developers (and LLMs) love