Thibaut's picture
Add complete metrics evaluation subproject structure
b7d2408
# CVAT API Client
A comprehensive Python client for interacting with the CVAT (Computer Vision Annotation Tool) REST API.
## Features
βœ… **Complete API Coverage** - All core CVAT operations supported
βœ… **Type-Safe** - Full Pydantic model validation
βœ… **Automatic Retries** - Built-in retry logic for transient errors
βœ… **Well-Tested** - 30 validation tests, all passing
βœ… **Well-Documented** - Comprehensive guides and examples
## Installation
```bash
pip install -r requirements.txt
```
Required packages: `requests`, `pydantic`, `python-dotenv`
## Quick Start
```python
from cvat_api import CvatApiClient
# Initialize client
client = CvatApiClient(
cvat_host="https://app.cvat.ai",
cvat_username="your_username",
cvat_password="your_password",
cvat_organization="your_organization"
)
# Get project details
project = client.projects.get_project_details(project_id=239220)
print(f"Project: {project.name}")
# Download annotations
annotations = client.annotations.get_job_annotations(job_id=2355063)
print(f"Found {len(annotations.shapes)} shapes")
# Modify and upload annotations
for shape in annotations.shapes:
if shape.label_id == 5:
shape.occluded = True
updated = client.annotations.put_job_annotations(
job_id=2355063,
annotations=annotations
)
print(f"βœ… Updated {len(updated.shapes)} shapes")
```
## Available Methods
The client is organized into method groups:
### Authentication
- `client.auth.get_auth_token()` - Get authentication token
### Projects
- `client.projects.get_project_details(project_id)` - Get project info
- `client.projects.get_project_labels(project_id)` - Get all labels
- `client.projects.get_project_job_ids(project_id)` - Get all job IDs
- `client.projects.get_project_tasks(project_id)` - Get all task IDs
### Tasks
- `client.tasks.get_task_details(task_id)` - Get task info
- `client.tasks.get_task_media_metainformation(task_id)` - Get media metadata
- `client.tasks.get_task_job_ids(task_id)` - Get job IDs
- `client.tasks.update_task(task_id, task_data)` - **Update task metadata**
### Jobs
- `client.jobs.list_jobs(request)` - List jobs with filtering
- `client.jobs.get_job_details(job_id)` - Get job info
- `client.jobs.get_job_media_metainformation(job_id)` - Get media metadata
- `client.jobs.update_job(job_id, job_data)` - **Update job metadata**
### Annotations
- `client.annotations.get_job_annotations(job_id)` - Get annotations
- `client.annotations.get_task_annotations(task_id)` - Get annotations
- `client.annotations.put_job_annotations(job_id, annotations)` - **Update annotations**
- `client.annotations.put_task_annotations(task_id, annotations)` - **Update annotations**
### Downloads
- `client.downloads.download_job_image(job_id, frame_number, output_path)` - Download single image
- `client.downloads.download_task_image(task_id, frame_number, output_path)` - Download single image
- `client.downloads.download_job_images(job_id, output_dir)` - Download all images
- `client.downloads.download_task_images(task_id, output_dir)` - Download all images
- `client.downloads.download_job_data_chunk(job_id, chunk_number, output_path)` - Download chunk
- `client.downloads.download_task_data_chunk(task_id, chunk_number, output_path)` - Download chunk
- `client.downloads.download_all_job_chunks(job_id, output_dir)` - Download all chunks
- `client.downloads.download_all_task_chunks(task_id, output_dir)` - Download all chunks
### Labels
- `client.labels.get_label_details(label_id)` - Get label definition
## Complete Workflow Example
Download task, modify annotations, and upload:
```python
from cvat_api import CvatApiClient
from pathlib import Path
# 1. Initialize
client = CvatApiClient(...)
# 2. Download task data
task_id = 1322143
task_details = client.tasks.get_task_details(task_id)
annotations = client.annotations.get_task_annotations(task_id)
images = client.downloads.download_task_images(
task_id=task_id,
output_dir=Path("./images")
)
# 3. Modify annotations
for shape in annotations.shapes:
if shape.label_id == 5: # Filter by label
shape.occluded = True # Mark as occluded
# 4. Upload modified annotations
updated = client.annotations.put_task_annotations(
task_id=task_id,
annotations=annotations
)
print(f"βœ… Updated {len(updated.shapes)} shapes")
```
## Documentation
- **[Usage Guide](./USAGE_GUIDE.md)** - Complete workflows and examples
- **[API Reference](./client.py)** - Detailed method documentation
- **[Test Suite](../tests/test_cvat_api/)** - 30 validation tests
- **[Test Results](../tests/test_cvat_api/TEST_RESULTS.md)** - Latest test results
## Testing
Run the validation test suite:
```bash
# Run all tests
pytest tests/test_cvat_api/ -v
# Run specific test category
pytest tests/test_cvat_api/test_projects.py -v
pytest tests/test_cvat_api/test_updates.py -v
# Current status: 30/30 tests passing βœ…
```
## Error Handling
The client includes automatic retry logic with exponential backoff:
- **General errors**: 3 retries with 1-60 second delays
- **Transient errors (500/502/503/504)**: Up to 10 retries with 10-300 second delays
- **Jitter**: Random delay variation to prevent thundering herd
```python
# Automatic retries on failure
try:
annotations = client.annotations.get_job_annotations(job_id)
except requests.HTTPError as e:
print(f"Request failed after retries: {e}")
```
## Environment Configuration
Set environment variables in `.env`:
```env
CVAT_URL=https://app.cvat.ai
CVAT_USERNAME=your_username
CVAT_PASSWORD=your_password
CVAT_ORGANIZATION=your_organization
```
## Architecture
```
cvat_api/
β”œβ”€β”€ client.py # Main CvatApiClient class
β”œβ”€β”€ auth.py # Authentication methods
β”œβ”€β”€ projects.py # Project operations
β”œβ”€β”€ tasks.py # Task operations (GET + UPDATE)
β”œβ”€β”€ jobs.py # Job operations (GET + UPDATE)
β”œβ”€β”€ annotations.py # Annotation operations (GET + PUT)
β”œβ”€β”€ downloads.py # Image/chunk download operations
β”œβ”€β”€ labels.py # Label operations
└── retry.py # Retry logic with backoff
```
## Pydantic Models
All data structures are validated using Pydantic models from `shared/schema/cvat/`:
- `CvatApiProjectDetails` - Project metadata
- `CvatApiTaskDetails` - Task metadata
- `CvatApiJobDetails` - Job metadata
- `CvatApiJobList` - Job annotations (shapes, tracks, tags)
- `CvatApiTaskList` - Task annotations
- `CvatApiShape` - Individual shape annotations
- `CvatApiTag` - Frame-level tags
- `CvatApiLabelDefinition` - Label definitions
## Contributing
When adding new features:
1. Add the method to the appropriate method group class
2. Add retry decorator if needed
3. Add comprehensive tests in `tests/test_cvat_api/`
4. Update this README and the Usage Guide
5. Run tests: `pytest tests/test_cvat_api/ -v`
## License
Part of the road_ai_analysis project.
## See Also
- [Official CVAT API Documentation](https://app.cvat.ai/api/docs/)
- [CVAT SDK](https://github.com/opencv/cvat/tree/develop/cvat-sdk)