> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/cvat-ai/cvat/llms.txt
> Use this file to discover all available pages before exploring further.

# Core Operations

> Working with projects, tasks, jobs, and annotations in the CVAT SDK

This guide covers the core operations for managing CVAT resources using the Python SDK.

## Projects

Projects group related tasks and define shared labels.

### Creating Projects

```python theme={null}
from cvat_sdk import Client, models

client = Client(url="cvat.example.com")
client.login(("username", "password"))

# Define project specification
project_spec = models.ProjectWriteRequest(
    name="Self-Driving Car Dataset",
    labels=[
        models.PatchedLabelRequest(
            name="car",
            color="#ff0000",
            type="rectangle"
        ),
        models.PatchedLabelRequest(
            name="pedestrian",
            color="#00ff00",
            type="rectangle"
        ),
        models.PatchedLabelRequest(
            name="traffic_light",
            color="#0000ff",
            type="rectangle"
        )
    ]
)

project = client.projects.create(spec=project_spec)
print(f"Created project {project.id}: {project.name}")
```

### Creating Projects with Dataset

Import a dataset when creating a project:

```python theme={null}
project = client.projects.create_from_dataset(
    spec=project_spec,
    dataset_path="annotations.zip",
    dataset_format="COCO 1.0",
    conv_mask_to_poly=False  # Keep masks as is
)
```

### Listing Projects

```python theme={null}
# List all projects
projects = client.projects.list()

for project in projects:
    print(f"Project {project.id}: {project.name}")
    print(f"  Owner: {project.owner.username}")
    print(f"  Created: {project.created_date}")
    print(f"  Tasks: {len(project.tasks) if hasattr(project, 'tasks') else 'N/A'}")
```

### Retrieving a Project

```python theme={null}
project = client.projects.retrieve(project_id=123)

print(f"Name: {project.name}")
print(f"Labels: {len(project.labels)}")
print(f"Status: {project.status}")
```

### Updating Projects

```python theme={null}
# Update project name
project.update(models.PatchedProjectWriteRequest(name="Updated Project Name"))

# Refresh project data from server
project.fetch()
```

### Working with Project Resources

```python theme={null}
# Get project tasks
tasks = project.get_tasks()
for task in tasks:
    print(f"Task {task.id}: {task.name}")

# Get project labels
labels = project.get_labels()
for label in labels:
    print(f"Label: {label.name} (ID: {label.id})")

# Get project annotations
annotations = project.get_annotations()
print(f"Total shapes: {len(annotations.shapes)}")
print(f"Total tags: {len(annotations.tags)}")

# Get project preview
preview = project.get_preview()
from PIL import Image
im = Image.open(preview)
im.show()
```

### Exporting Project Dataset

```python theme={null}
# Export in various formats
project.export_dataset(
    format_name="COCO 1.0",
    filename="project_export.zip"
)

# Export with custom save image parameter
project.export_dataset(
    format_name="YOLO 1.1",
    filename="yolo_export.zip",
    save_images=True
)
```

### Importing Dataset to Project

```python theme={null}
project.import_dataset(
    format_name="COCO 1.0",
    filename="dataset.zip",
    conv_mask_to_poly=True  # Convert masks to polygons
)
```

### Project Backup and Restore

```python theme={null}
# Download project backup
project.download_backup("project_backup.zip")

# Restore project from backup
restored_project = client.projects.create_from_backup(
    filename="project_backup.zip"
)
```

### Deleting Projects

```python theme={null}
# Delete a single project
project.remove()

# Delete multiple projects by ID
client.projects.remove_by_ids([123, 456, 789])
```

## Tasks

Tasks contain the actual data (images/videos) to be annotated.

### Creating Tasks

```python theme={null}
from cvat_sdk.core.proxies.tasks import ResourceType

# Define task specification
task_spec = models.TaskWriteRequest(
    name="Street Images - Batch 1",
    project_id=project.id,  # Optional: link to project
    # If not in project, define labels here:
    # labels=[...]
)

# Create task with local files
task = client.tasks.create_from_data(
    spec=task_spec,
    resources=["img1.jpg", "img2.jpg", "img3.jpg"],
    resource_type=ResourceType.LOCAL,
    data_params={
        "image_quality": 95,
        "chunk_size": 100,
        "sorting_method": "lexicographical"
    }
)

print(f"Created task {task.id}: {task.name}")
```

### Resource Types

Tasks support three resource types:

```python theme={null}
from cvat_sdk.core.proxies.tasks import ResourceType

# Local files from your machine
task = client.tasks.create_from_data(
    spec=task_spec,
    resources=["path/to/images/img1.jpg", "path/to/images/img2.jpg"],
    resource_type=ResourceType.LOCAL
)

# Remote files (URLs)
task = client.tasks.create_from_data(
    spec=task_spec,
    resources=[
        "https://example.com/image1.jpg",
        "https://example.com/image2.jpg"
    ],
    resource_type=ResourceType.REMOTE
)

# Server share files
task = client.tasks.create_from_data(
    spec=task_spec,
    resources=[
        "share/dataset1/img1.jpg",
        "share/dataset1/img2.jpg"
    ],
    resource_type=ResourceType.SHARE
)
```

### Listing Tasks

```python theme={null}
# List all tasks
tasks = client.tasks.list()

# Filter tasks by project
project_tasks = [t for t in tasks if t.project_id == project.id]

for task in tasks:
    print(f"Task {task.id}: {task.name}")
    print(f"  Size: {task.size} frames")
    print(f"  Status: {task.status}")
    print(f"  Mode: {task.mode}")
```

### Retrieving a Task

```python theme={null}
task = client.tasks.retrieve(task_id=456)

print(f"Name: {task.name}")
print(f"Project ID: {task.project_id}")
print(f"Size: {task.size}")
print(f"Mode: {task.mode}")
print(f"Owner: {task.owner.username}")
```

### Updating Tasks

```python theme={null}
# Update task properties
task.update(models.PatchedTaskWriteRequest(
    name="Updated Task Name",
    subset="train"  # Set dataset subset
))

# Fetch latest data
task.fetch()
```

### Adding Data to Existing Tasks

```python theme={null}
# Upload additional images
task.upload_data(
    resources=["new_img1.jpg", "new_img2.jpg"],
    resource_type=ResourceType.LOCAL,
    params={
        "image_quality": 90,
        "sorting_method": "natural"
    },
    wait_for_completion=True
)
```

### Working with Task Frames

```python theme={null}
# Get task metadata
meta = task.get_meta()
print(f"Total frames: {len(meta.frames)}")
print(f"Image quality: {meta.image_quality}")

# Get frame information
frames_info = task.get_frames_info()
for frame in frames_info[:5]:  # First 5 frames
    print(f"Frame {frame.frame}: {frame.name} ({frame.width}x{frame.height})")

# Get a specific frame
frame_bytes = task.get_frame(frame_id=0, quality="original")
from PIL import Image
img = Image.open(frame_bytes)
img.show()

# Get task preview
preview_bytes = task.get_preview()
preview = Image.open(preview_bytes)
preview.show()

# Download multiple frames
task.download_frames(
    frame_ids=[0, 1, 2, 3, 4],
    outdir="downloaded_frames",
    quality="original",
    filename_pattern="frame_{frame_id:06d}{frame_ext}"
)

# Download a chunk
with open("chunk_0.zip", "wb") as f:
    task.download_chunk(chunk_id=0, output_file=f, quality="compressed")
```

### Removing Frames

```python theme={null}
# Remove specific frames by ID
task.remove_frames_by_ids([5, 10, 15])
```

### Working with Task Jobs

```python theme={null}
# Get all jobs in a task
jobs = task.get_jobs()

for job in jobs:
    print(f"Job {job.id}")
    print(f"  Status: {job.status}")
    print(f"  Stage: {job.stage}")
    print(f"  Start frame: {job.start_frame}")
    print(f"  Stop frame: {job.stop_frame}")
    print(f"  Assignee: {job.assignee.username if job.assignee else 'Unassigned'}")
```

### Working with Task Labels

```python theme={null}
# Get task labels
labels = task.get_labels()

for label in labels:
    print(f"Label: {label.name} (ID: {label.id})")
    print(f"  Type: {label.type}")
    print(f"  Color: {label.color}")
    if label.attributes:
        print(f"  Attributes: {[a.name for a in label.attributes]}")
```

### Task Annotations

```python theme={null}
# Get annotations
annotations = task.get_annotations()

print(f"Shapes: {len(annotations.shapes)}")
print(f"Tags: {len(annotations.tags)}")
print(f"Tracks: {len(annotations.tracks)}")

# Set (replace all) annotations
new_annotations = models.LabeledDataRequest(
    shapes=[
        models.LabeledShapeRequest(
            type="rectangle",
            frame=0,
            label_id=labels[0].id,
            points=[100.0, 100.0, 200.0, 200.0],
            attributes=[]
        )
    ],
    tags=[],
    tracks=[]
)
task.set_annotations(new_annotations)

# Update (add/modify/delete) annotations
from cvat_sdk.core.proxies.annotations import AnnotationUpdateAction

# Add new shapes
task.update_annotations(
    models.PatchedLabeledDataRequest(
        shapes=[
            models.LabeledShapeRequest(
                type="polygon",
                frame=1,
                label_id=labels[0].id,
                points=[10.0, 10.0, 20.0, 10.0, 20.0, 20.0, 10.0, 20.0],
                attributes=[]
            )
        ]
    ),
    action=AnnotationUpdateAction.CREATE
)

# Update existing annotations
task.update_annotations(
    models.PatchedLabeledDataRequest(
        shapes=[
            models.LabeledShapeRequest(
                id=12345,  # Existing shape ID
                type="rectangle",
                frame=0,
                label_id=labels[0].id,
                points=[150.0, 150.0, 250.0, 250.0],
                attributes=[]
            )
        ]
    ),
    action=AnnotationUpdateAction.UPDATE
)

# Delete specific annotations
task.remove_annotations(ids=[12345, 67890])

# Delete all annotations
task.remove_annotations()
```

### Importing Annotations

```python theme={null}
# Import annotations from file
task.import_annotations(
    format_name="YOLO 1.1",
    filename="annotations.zip"
)

# With mask to polygon conversion
task.import_annotations(
    format_name="COCO 1.0",
    filename="coco_annotations.json",
    conv_mask_to_poly=True
)
```

### Exporting Task Dataset

```python theme={null}
# Export annotations and data
task.export_dataset(
    format_name="CVAT for images 1.1",
    filename="task_export.zip"
)

# Export only annotations
task.export_dataset(
    format_name="COCO 1.0",
    filename="coco_export.json",
    save_images=False
)
```

### Task Backup and Restore

```python theme={null}
# Download task backup
task.download_backup("task_backup.zip")

# Create task from backup
restored_task = client.tasks.create_from_backup(
    filename="task_backup.zip"
)
```

### Deleting Tasks

```python theme={null}
# Delete single task
task.remove()

# Delete multiple tasks
client.tasks.remove_by_ids([123, 456, 789])
```

## Jobs

Jobs are subdivisions of tasks assigned to annotators.

### Listing Jobs

```python theme={null}
# List all jobs
jobs = client.jobs.list()

# Get jobs for a specific task
task_jobs = task.get_jobs()

for job in jobs:
    print(f"Job {job.id}")
    print(f"  Task: {job.task_id}")
    print(f"  Status: {job.status}")
    print(f"  Stage: {job.stage}")
    print(f"  Assignee: {job.assignee.username if job.assignee else 'None'}")
```

### Retrieving a Job

```python theme={null}
job = client.jobs.retrieve(job_id=789)

print(f"Job {job.id}")
print(f"Task ID: {job.task_id}")
print(f"Frame range: {job.start_frame} - {job.stop_frame}")
print(f"Status: {job.status}")
print(f"Stage: {job.stage}")
```

### Updating Jobs

```python theme={null}
# Update job properties
job.update(models.PatchedJobWriteRequest(
    status="completed",
    stage="acceptance",
    assignee=user_id
))

job.fetch()
```

### Working with Job Frames

```python theme={null}
# Get job metadata
meta = job.get_meta()
frames_info = job.get_frames_info()

# Get specific frame
frame_bytes = job.get_frame(frame_id=job.start_frame)

# Download frames
job.download_frames(
    frame_ids=list(range(job.start_frame, job.stop_frame + 1)),
    outdir="job_frames"
)

# Remove frames
job.remove_frames_by_ids([10, 20])
```

### Job Annotations

```python theme={null}
# Get job annotations
annotations = job.get_annotations()

# Set annotations
job.set_annotations(new_annotations)

# Update annotations
job.update_annotations(partial_annotations)

# Import annotations
job.import_annotations(
    format_name="COCO 1.0",
    filename="job_annotations.json"
)

# Export job dataset
job.export_dataset(
    format_name="YOLO 1.1",
    filename="job_export.zip"
)
```

### Job Issues

```python theme={null}
# Get issues for a job
issues = job.get_issues()

for issue in issues:
    print(f"Issue {issue.id}: {issue.message}")
    print(f"  Frame: {issue.frame}")
    print(f"  Position: {issue.position}")
    print(f"  Resolved: {issue.resolved}")
```

### Job Labels

```python theme={null}
# Get labels available in the job
labels = job.get_labels()

for label in labels:
    print(f"Label: {label.name} (ID: {label.id})")
```

## Progress Reporting

Many operations support progress reporting with `tqdm`:

```python theme={null}
from tqdm import tqdm
from cvat_sdk.core.progress import ProgressReporter

# Create task with progress bar
with tqdm(desc="Uploading images", unit="bytes") as pbar:
    task = client.tasks.create_from_data(
        spec=task_spec,
        resources=image_files,
        pbar=pbar
    )

# Import annotations with progress
with tqdm(desc="Importing annotations") as pbar:
    task.import_annotations(
        format_name="COCO 1.0",
        filename="annotations.json",
        pbar=pbar
    )
```

## Next Steps

* [PyTorch Adapter](/sdk/pytorch-adapter) - Use CVAT tasks for training PyTorch models
* [Auto-Annotation](/sdk/auto-annotation) - Automate annotation using models
