File size: 8,794 Bytes
b7d2408 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 |
# CVAT API Usage Guide
Complete guide for working with CVAT tasks, jobs, and annotations.
## Table of Contents
- [Installation](#installation)
- [Initialization](#initialization)
- [Common Workflows](#common-workflows)
- [Download and Update Job Annotations](#download-and-update-job-annotations)
- [Download and Update Task Annotations](#download-and-update-task-annotations)
- [Update Job Metadata](#update-job-metadata)
- [Update Task Metadata](#update-task-metadata)
- [Complete Examples](#complete-examples)
## Installation
```bash
pip install -r requirements.txt
```
## Initialization
```python
from cvat_api import CvatApiClient
from pathlib import Path
# Initialize client
client = CvatApiClient(
cvat_host="https://app.cvat.ai",
cvat_username="your_username",
cvat_password="your_password",
cvat_organization="your_organization"
)
```
## Common Workflows
### Download and Update Job Annotations
Complete workflow for downloading annotations, modifying them, and uploading back:
```python
# 1. Download annotations
job_id = 2355063
annotations = client.annotations.get_job_annotations(job_id)
# 2. Modify annotations
# Add a new shape
from shared.schema.cvat import CvatApiShape
new_shape = CvatApiShape(
id=0, # Will be assigned by server
type="rectangle",
frame=0,
label_id=1,
points=[100.0, 100.0, 200.0, 200.0],
occluded=False,
z_order=0,
source="manual",
attributes=[]
)
annotations.shapes.append(new_shape)
# Or modify existing shapes
for shape in annotations.shapes:
if shape.label_id == 5:
shape.occluded = True # Mark as occluded
# 3. Upload modified annotations
updated_annotations = client.annotations.put_job_annotations(
job_id=job_id,
annotations=annotations
)
print(f"✅ Updated {len(updated_annotations.shapes)} shapes")
```
### Download and Update Task Annotations
Same workflow but at task level:
```python
# 1. Download task annotations
task_id = 1322143
annotations = client.annotations.get_task_annotations(task_id)
# 2. Modify annotations (same as above)
# ... make your changes ...
# 3. Upload modified annotations
updated_annotations = client.annotations.put_task_annotations(
task_id=task_id,
annotations=annotations
)
```
### Update Job Metadata
Update job status, assignee, stage, etc.:
```python
# 1. Get current job details
job_id = 2355063
job_details = client.jobs.get_job_details(job_id)
# 2. Modify job metadata
job_details.state = "completed" # Change state
job_details.stage = "acceptance" # Change stage
# 3. Update job
updated_job = client.jobs.update_job(
job_id=job_id,
job_data=job_details
)
print(f"✅ Job {job_id} updated: {updated_job.state} / {updated_job.stage}")
```
### Update Task Metadata
Update task name, assignee, labels, etc.:
```python
# 1. Get current task details
task_id = 1322143
task_details = client.tasks.get_task_details(task_id)
# 2. Modify task metadata
task_details.name = "Updated Task Name"
# Note: Use model_dump(exclude_unset=True) in update method to only send changed fields
# 3. Update task
updated_task = client.tasks.update_task(
task_id=task_id,
task_data=task_details
)
print(f"✅ Task {task_id} updated: {updated_task.name}")
```
## Complete Examples
### Example 1: Batch Process Job Annotations
Process annotations for all jobs in a task:
```python
from cvat_api import CvatApiClient
# Initialize
client = CvatApiClient(...)
# Get all jobs in task
task_id = 1322143
job_ids = client.tasks.get_task_job_ids(task_id)
# Process each job
for job_id in job_ids:
# Download annotations
annotations = client.annotations.get_job_annotations(job_id)
# Apply your modifications
for shape in annotations.shapes:
if shape.label_id == 5: # Example: filter by label
# Modify shape properties
shape.occluded = True
# Upload modified annotations
client.annotations.put_job_annotations(job_id, annotations)
print(f"✅ Processed job {job_id}")
```
### Example 2: Download All Images and Annotations
Download complete dataset from a task:
```python
from pathlib import Path
task_id = 1322143
output_dir = Path("./output")
# 1. Download all images
images = client.downloads.download_task_images(
task_id=task_id,
output_dir=output_dir / "images"
)
print(f"Downloaded {len(images)} images")
# 2. Download annotations
annotations = client.annotations.get_task_annotations(task_id)
# 3. Save annotations to file
import json
output_file = output_dir / "annotations.json"
output_file.write_text(annotations.model_dump_json(indent=2))
print(f"Saved annotations to {output_file}")
```
### Example 3: Quality Control Workflow
Implement a QC workflow that marks reviewed jobs:
```python
from shared.schema.cvat import CvatApiJobsListRequest
# List all jobs in "annotation" stage
request = CvatApiJobsListRequest(
task_id=1322143,
stage="annotation",
state="completed"
)
response = client.jobs.list_jobs(request)
for job in response.results:
# Download and review annotations
annotations = client.annotations.get_job_annotations(job.id)
# Run your QC checks
issues_found = run_quality_checks(annotations)
# Update job based on QC results
job_details = client.jobs.get_job_details(job.id)
if not issues_found:
job_details.stage = "acceptance"
job_details.state = "completed"
else:
job_details.state = "rejected"
client.jobs.update_job(job.id, job_details)
print(f"✅ QC processed job {job.id}")
```
### Example 4: Export Annotations with Metadata
Export complete annotation dataset with metadata:
```python
# Get project details
project_id = 239220
project = client.projects.get_project_details(project_id)
labels = client.projects.get_project_labels(project_id)
# Get all tasks
task_ids = client.projects.get_project_tasks(project_id)
# Build export structure
export_data = {
"project": project.model_dump(),
"labels": [label.model_dump() for label in labels],
"tasks": []
}
# Export each task
for task_id in task_ids:
task_details = client.tasks.get_task_details(task_id)
annotations = client.annotations.get_task_annotations(task_id)
export_data["tasks"].append({
"task": task_details.model_dump(),
"annotations": annotations.model_dump()
})
# Save export
import json
Path("export.json").write_text(json.dumps(export_data, indent=2))
print(f"✅ Exported {len(task_ids)} tasks")
```
## Tips and Best Practices
### 1. Use Partial Updates
When updating jobs or tasks, use only the fields you want to change:
```python
# Good - only update specific fields
job_details = client.jobs.get_job_details(job_id)
job_details.state = "completed"
client.jobs.update_job(job_id, job_details)
```
### 2. Handle Errors
Always handle potential errors:
```python
try:
annotations = client.annotations.get_job_annotations(job_id)
except requests.HTTPError as e:
print(f"Failed to get annotations: {e}")
# Handle error appropriately
```
### 3. Batch Operations
For multiple jobs/tasks, use batch operations:
```python
job_ids = client.tasks.get_task_job_ids(task_id)
for job_id in job_ids:
try:
# Process each job
process_job(client, job_id)
except Exception as e:
print(f"Error processing job {job_id}: {e}")
continue # Continue with next job
```
### 4. Validate Before Upload
Validate annotations before uploading:
```python
annotations = client.annotations.get_job_annotations(job_id)
# Validate
for shape in annotations.shapes:
assert shape.label_id in valid_label_ids
assert len(shape.points) >= 4 # For rectangles
# Upload after validation
client.annotations.put_job_annotations(job_id, annotations)
```
## Error Handling
The client includes automatic retry logic for transient errors (500/502/503/504):
```python
# This will automatically retry up to 10 times for server errors
annotations = client.annotations.get_job_annotations(job_id)
```
For custom error handling:
```python
import requests
from requests.exceptions import Timeout, ConnectionError
try:
annotations = client.annotations.get_job_annotations(job_id)
except Timeout:
print("Request timed out")
except ConnectionError:
print("Connection failed")
except requests.HTTPError as e:
if e.response.status_code == 404:
print("Job not found")
elif e.response.status_code == 403:
print("Access denied")
else:
print(f"HTTP error: {e}")
```
## See Also
- [API Documentation](./client.py) - Complete API reference
- [Test Suite](../tests/test_cvat_api/) - Usage examples in tests
- [CVAT API Docs](https://app.cvat.ai/api/docs/) - Official CVAT API documentation
|