datnvt-cvat-cli 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,574 @@
1
+ Metadata-Version: 2.4
2
+ Name: datnvt-cvat-cli
3
+ Version: 0.1.0
4
+ Summary: CLI and Python API for managing CVAT annotations: download, upload, and inspect tasks
5
+ Author-email: datnvt <thanhdatnv2712@gmail.com>
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/datvtn/datnvt-cvat-cli
8
+ Project-URL: Bug Tracker, https://github.com/datvtn/datnvt-cvat-cli/issues
9
+ Keywords: cvat,annotations,computer-vision,cli,dataset
10
+ Classifier: Development Status :: 3 - Alpha
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: Intended Audience :: Science/Research
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Programming Language :: Python :: 3.9
15
+ Classifier: Programming Language :: Python :: 3.10
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
19
+ Requires-Python: >=3.9
20
+ Description-Content-Type: text/markdown
21
+ Requires-Dist: requests>=2.28.0
22
+ Requires-Dist: pydantic>=2.0.0
23
+ Requires-Dist: typer>=0.9.0
24
+ Requires-Dist: pyyaml>=6.0
25
+ Requires-Dist: rich>=13.0.0
26
+ Provides-Extra: dev
27
+ Requires-Dist: pre-commit>=3.0.0; extra == "dev"
28
+ Requires-Dist: ruff>=0.4.0; extra == "dev"
29
+
30
+ # datnvt-cvat-cli
31
+
32
+ A focused CLI tool and Python library for managing annotations on a [CVAT](https://www.cvat.ai/) server.
33
+
34
+ ## Features
35
+
36
+ | Feature | CLI command | Python API |
37
+ |---|---|---|
38
+ | Download annotations (without images) | `datnvt-cvat-cli download` | `client.download_tasks(...)` |
39
+ | Download full dataset (annotations + images) | `datnvt-cvat-cli download --save-images` | `client.download_tasks(..., save_images=True)` |
40
+ | Upload annotations to CVAT tasks | `datnvt-cvat-cli upload` | `client.upload_tasks(...)` |
41
+ | List tasks for a project | `datnvt-cvat-cli list-tasks` | `client.get_tasks(...)` |
42
+ | List all projects | `datnvt-cvat-cli list-projects` | `client.get_projects()` |
43
+ | Inspect task metadata | `datnvt-cvat-cli task-info` | `client.get_task_info(task_id)` |
44
+ | Verify server credentials | `datnvt-cvat-cli check-connection` | `client.check_connection()` |
45
+ | Check project availability | — | `client.check_project(project_id)` |
46
+ | Run batch operations from YAML | `datnvt-cvat-cli run config.yaml` | — |
47
+
48
+ ## Installation
49
+
50
+ ```bash
51
+ pip install datnvt-cvat-cli
52
+ ```
53
+
54
+ Or from source:
55
+
56
+ ```bash
57
+ git clone https://github.com/datvtn/datnvt-cvat-cli.git
58
+ cd datnvt-cvat-cli
59
+ pip install -e .
60
+ ```
61
+
62
+ Requires Python ≥ 3.9.
63
+
64
+ ## Configuration
65
+
66
+ Server credentials can be supplied in three ways (highest priority first):
67
+
68
+ ### 1. CLI flags
69
+
70
+ ```bash
71
+ datnvt-cvat-cli --url https://cvat.example.com \
72
+ --username myuser \
73
+ --password mypassword \
74
+ --project-id 11 \
75
+ list-tasks
76
+ ```
77
+
78
+ ### 2. YAML config file
79
+
80
+ ```yaml
81
+ # config/server.yaml
82
+ url: "https://cvat.example.com"
83
+ username: "myuser"
84
+ password: "mypassword"
85
+ project_id: 11
86
+ ```
87
+
88
+ ```bash
89
+ datnvt-cvat-cli --config config/server.yaml list-tasks
90
+ # or
91
+ export CVAT_SERVER_CONFIG=config/server.yaml
92
+ datnvt-cvat-cli list-tasks
93
+ ```
94
+
95
+ ### 3. Environment variables
96
+
97
+ ```bash
98
+ export CVAT_URL=https://cvat.example.com
99
+ export CVAT_USERNAME=myuser
100
+ export CVAT_PASSWORD=mypassword
101
+ export CVAT_PROJECT_ID=11
102
+ ```
103
+
104
+ ---
105
+
106
+ ## CLI Reference
107
+
108
+ ### Global options (apply to all commands)
109
+
110
+ ```
111
+ datnvt-cvat-cli [OPTIONS] COMMAND [ARGS]
112
+
113
+ Options:
114
+ --config, -c FILE Server config YAML [env: CVAT_SERVER_CONFIG]
115
+ --url TEXT CVAT server URL [env: CVAT_URL]
116
+ --username, -u TEXT CVAT username [env: CVAT_USERNAME]
117
+ --password, -p TEXT CVAT password [env: CVAT_PASSWORD]
118
+ --project-id INTEGER Default project ID [env: CVAT_PROJECT_ID]
119
+ --verbose, -v Enable debug logging
120
+ ```
121
+
122
+ ---
123
+
124
+ ### `download` — Download CVAT tasks
125
+
126
+ Downloads annotations (and optionally images) for one or more tasks.
127
+
128
+ ```
129
+ datnvt-cvat-cli download [OPTIONS]
130
+
131
+ Options:
132
+ --task-id, -t INTEGER Task ID (repeat for multiple) [required]
133
+ --out-dir, -o PATH Output directory; tasks saved as task{id}/ subdirs
134
+ --out-path PATH Explicit output path per task (repeat to match --task-id)
135
+ --format, -f TEXT Annotation format [default: CVAT for images 1.1]
136
+ --save-images / --no-save-images
137
+ Also download raw images [default: no-save-images]
138
+ --skip-existing / --no-skip-existing
139
+ Skip tasks already on disk [default: skip-existing]
140
+ --folder-prefix TEXT Output folder prefix per task [default: task]
141
+ e.g. --folder-prefix data_ → data_147/ instead of task147/
142
+ ```
143
+
144
+ **Supported formats:**
145
+ - `CVAT for images 1.1` (XML, **default**)
146
+ - `COCO 1.0` (JSON)
147
+
148
+ **Output structure (CVAT format, default):**
149
+ ```
150
+ out_dir/
151
+ task147/
152
+ annotations.xml
153
+ images/ ← only when --save-images
154
+ frame_000001.jpg
155
+ ...
156
+ task150/
157
+ annotations.xml
158
+ ```
159
+
160
+ **Examples:**
161
+
162
+ ```bash
163
+ # Download annotations only for tasks 147 and 150
164
+ datnvt-cvat-cli --config server.yaml download -t 147 -t 150 --out-dir data/raw
165
+
166
+ # Download with images (default CVAT XML format)
167
+ datnvt-cvat-cli --config server.yaml download -t 147 --out-dir data/raw --save-images
168
+
169
+ # Download as COCO JSON instead
170
+ datnvt-cvat-cli --config server.yaml download -t 147 --out-dir data/raw \
171
+ --format "COCO 1.0"
172
+
173
+ # Force re-download even if files exist
174
+ datnvt-cvat-cli --config server.yaml download -t 147 --out-dir data/raw --no-skip-existing
175
+
176
+ # Rename output folders: data_147/ instead of task147/
177
+ datnvt-cvat-cli --config server.yaml download -t 147 -t 150 --out-dir data/raw \
178
+ --folder-prefix data_
179
+
180
+ # Custom output path per task
181
+ datnvt-cvat-cli --config server.yaml download -t 147 -t 150 \
182
+ --out-path data/task_a --out-path data/task_b
183
+ ```
184
+
185
+ ---
186
+
187
+ ### `upload` — Upload annotations to CVAT
188
+
189
+ Pushes local annotation files to the corresponding CVAT tasks.
190
+
191
+ ```
192
+ datnvt-cvat-cli upload [OPTIONS]
193
+
194
+ Options:
195
+ --task-id, -t INTEGER Task ID (repeat for multiple) [required]
196
+ --in-dir, -i PATH Input directory containing task{id}/ subdirs [required]
197
+ --format, -f TEXT Annotation format [default: CVAT for images 1.1]
198
+ ```
199
+
200
+ **File lookup (in order of preference):**
201
+
202
+ | Format | Primary | Fallback |
203
+ |--------|---------|----------|
204
+ | CVAT 1.1 | `<in_dir>/task{id}/annotations_pseudo.xml` | `annotations.xml` |
205
+ | COCO 1.0 | `<in_dir>/task{id}/annotations/instances_default_pseudo.json` | `instances_default.json` |
206
+
207
+ **Examples:**
208
+
209
+ ```bash
210
+ # Upload CVAT XML annotations from data/processed/ for tasks 147 and 150 (default format)
211
+ datnvt-cvat-cli --config server.yaml upload -t 147 -t 150 --in-dir data/processed
212
+
213
+ # Upload COCO JSON annotations
214
+ datnvt-cvat-cli --config server.yaml upload -t 147 --in-dir data/processed \
215
+ --format "COCO 1.0"
216
+ ```
217
+
218
+ ---
219
+
220
+ ### `list-tasks` — List tasks
221
+
222
+ ```
223
+ datnvt-cvat-cli list-tasks [OPTIONS]
224
+
225
+ Options:
226
+ --project-id INTEGER Filter by project ID (defaults to config project_id)
227
+ --output TEXT Output format: table (default) or json
228
+ ```
229
+
230
+ **Examples:**
231
+
232
+ ```bash
233
+ # List all tasks in the default project
234
+ datnvt-cvat-cli --config server.yaml list-tasks
235
+
236
+ # List tasks for a specific project in JSON
237
+ datnvt-cvat-cli --config server.yaml list-tasks --project-id 15 --output json
238
+ ```
239
+
240
+ **Sample output:**
241
+ ```
242
+ Tasks (project_id=11)
243
+ ┌──────┬──────────────────────────┬────────────┬───────┬──────────────┐
244
+ │ ID │ Name │ Status │ Size │ Mode │
245
+ ├──────┼──────────────────────────┼────────────┼───────┼──────────────┤
246
+ │ 147 │ Training batch 1 │ completed │ 500 │ annotation │
247
+ │ 150 │ Validation set │ annotation │ 200 │ annotation │
248
+ └──────┴──────────────────────────┴────────────┴───────┴──────────────┘
249
+ Total: 2 task(s)
250
+ ```
251
+
252
+ ---
253
+
254
+ ### `list-projects` — List projects
255
+
256
+ ```
257
+ datnvt-cvat-cli list-projects [OPTIONS]
258
+
259
+ Options:
260
+ --output TEXT Output format: table (default) or json
261
+ ```
262
+
263
+ **Examples:**
264
+
265
+ ```bash
266
+ datnvt-cvat-cli --config server.yaml list-projects
267
+ datnvt-cvat-cli --config server.yaml list-projects --output json
268
+ ```
269
+
270
+ ---
271
+
272
+ ### `task-info` — Inspect task details
273
+
274
+ ```
275
+ datnvt-cvat-cli task-info [OPTIONS]
276
+
277
+ Options:
278
+ --task-id, -t INTEGER Task ID (repeat for multiple) [required]
279
+ --output TEXT Output format: table (default) or json
280
+ ```
281
+
282
+ **Examples:**
283
+
284
+ ```bash
285
+ # Show details for tasks 147 and 150
286
+ datnvt-cvat-cli --config server.yaml task-info -t 147 -t 150
287
+
288
+ # Get raw JSON for task 147
289
+ datnvt-cvat-cli --config server.yaml task-info -t 147 --output json
290
+ ```
291
+
292
+ **Sample output:**
293
+ ```
294
+ Task 147: Training batch 1
295
+ Status : completed
296
+ Size : 500 frame(s)
297
+ Mode : annotation
298
+ Project : 11
299
+ Labels : door, window, wall
300
+ Created : 2024-01-10T09:00:00Z
301
+ Updated : 2024-03-15T14:22:00Z
302
+ ```
303
+
304
+ ---
305
+
306
+ ### `check-connection` — Verify credentials
307
+
308
+ ```bash
309
+ datnvt-cvat-cli --config server.yaml check-connection
310
+ # Connection OK.
311
+ ```
312
+
313
+ ---
314
+
315
+ ### `run` — Batch operations from YAML
316
+
317
+ Run multiple operations defined in a single YAML file. Before executing any tasks, `run` performs **pre-flight checks**: it verifies the CVAT server is reachable and that the configured project is accessible. The run aborts with a non-zero exit code if either check fails.
318
+
319
+ ```bash
320
+ datnvt-cvat-cli --config server.yaml run config/cvat/tasks.yaml
321
+ # or embed server credentials directly in the YAML (see format below)
322
+ datnvt-cvat-cli run config/cvat/tasks.yaml
323
+ ```
324
+
325
+ **Supported task names:**
326
+
327
+ | YAML task name | Operation |
328
+ |---|---|
329
+ | `download_cvat_tasks` | Download annotations (and optionally images) |
330
+ | `upload_anno_with_cvat_tasks` | Upload local annotations to CVAT |
331
+
332
+ ---
333
+
334
+ ## YAML Configuration Files
335
+
336
+ ### Download — `config/download.yaml`
337
+
338
+ ```yaml
339
+ # Download annotations (and optionally images) for a list of tasks.
340
+ # Run with: datnvt-cvat-cli --config server.yaml run config/download.yaml
341
+
342
+ - task: download_cvat_tasks
343
+ parameters:
344
+ # List of CVAT task IDs to download.
345
+ task_ids: [147, 150, 151]
346
+
347
+ # Output directory. Each task is saved under <out_dir>/task{id}/.
348
+ out_dir: data/raw
349
+
350
+ # Annotation format: "CVAT for images 1.1" (XML, default) or "COCO 1.0" (JSON).
351
+ dataset_format: "CVAT for images 1.1"
352
+
353
+ # Set true to also download the raw image files alongside annotations.
354
+ save_images: false
355
+
356
+ # Set false to force re-download even when annotation files already exist.
357
+ skip_existing: true
358
+
359
+ # Optional: rename output folders using a custom prefix instead of "task".
360
+ # Default: task147/, task150/, ... | "data_" → data_147/, data_150/, ...
361
+ # folder_prefix: "data_"
362
+ ```
363
+
364
+ Output layout for CVAT XML format (default):
365
+ ```
366
+ data/raw/
367
+ task147/
368
+ annotations.xml
369
+ images/ ← only when save_images: true
370
+ task150/
371
+ annotations.xml
372
+ ```
373
+
374
+ Output layout for COCO JSON format:
375
+ ```
376
+ data/raw/
377
+ task147/
378
+ annotations/
379
+ instances_default.json
380
+ images/ ← only when save_images: true
381
+ ```
382
+
383
+ ---
384
+
385
+ ### Upload — `config/upload.yaml`
386
+
387
+ Each task specifies its own annotation file path. The format can be set globally and overridden per task.
388
+
389
+ ```yaml
390
+ # Upload annotation files to CVAT — one explicit path per task.
391
+ # Run with: datnvt-cvat-cli --config server.yaml run config/upload.yaml
392
+
393
+ - task: upload_anno_with_cvat_tasks
394
+ parameters:
395
+ # Default annotation format for all tasks below.
396
+ # Can be overridden individually with a "dataset_format" key on any task entry.
397
+ dataset_format: "CVAT for images 1.1" # "CVAT for images 1.1" (default) or "COCO 1.0"
398
+
399
+ tasks:
400
+ - task_id: 147
401
+ annotation_path: data/processed/task147_annotations.xml
402
+
403
+ - task_id: 150
404
+ annotation_path: data/processed/task150_annotations.xml
405
+
406
+ # Override format for a single task (COCO JSON instead of CVAT XML)
407
+ - task_id: 151
408
+ annotation_path: data/processed/task151_annotations.json
409
+ dataset_format: "COCO 1.0"
410
+ ```
411
+
412
+ **Directory-convention fallback** — if you prefer the auto-resolved path layout, omit `tasks` and use `in_dir` instead:
413
+
414
+ ```yaml
415
+ - task: upload_anno_with_cvat_tasks
416
+ parameters:
417
+ task_ids: [147, 150, 151]
418
+ in_dir: data/processed # looks for task{id}/ subdirs
419
+ dataset_format: "CVAT for images 1.1"
420
+ # CVAT: <in_dir>/task{id}/annotations_pseudo.xml
421
+ # (falls back to annotations.xml)
422
+ # COCO: <in_dir>/task{id}/annotations/instances_default_pseudo.json
423
+ # (falls back to instances_default.json)
424
+ ```
425
+
426
+ ---
427
+
428
+ ### Combined download + upload — `config/tasks.yaml`
429
+
430
+ ```yaml
431
+ # Run both download and upload steps in sequence.
432
+ # Run with: datnvt-cvat-cli --config server.yaml run config/tasks.yaml
433
+ #
434
+ # To embed server credentials directly (overrides --config / env vars),
435
+ # add a "server" key to any entry:
436
+ #
437
+ # - task: download_cvat_tasks
438
+ # server:
439
+ # url: "https://cvat.example.com"
440
+ # username: "myuser"
441
+ # password: "mypassword"
442
+ # project_id: 11
443
+ # parameters:
444
+ # ...
445
+
446
+ # Step 1: download existing annotations from CVAT
447
+ - task: download_cvat_tasks
448
+ parameters:
449
+ task_ids: [147, 150, 151]
450
+ out_dir: data/raw
451
+ dataset_format: "CVAT for images 1.1"
452
+ save_images: false
453
+ skip_existing: true
454
+
455
+ # Step 2: upload revised annotations back to CVAT (per-task explicit paths)
456
+ - task: upload_anno_with_cvat_tasks
457
+ parameters:
458
+ dataset_format: "CVAT for images 1.1"
459
+ tasks:
460
+ - task_id: 147
461
+ annotation_path: data/processed/task147_annotations.xml
462
+ - task_id: 150
463
+ annotation_path: data/processed/task150_annotations.xml
464
+ - task_id: 151
465
+ annotation_path: data/processed/task151_annotations.xml
466
+ ```
467
+
468
+ ---
469
+
470
+ ## Python API
471
+
472
+ ```python
473
+ from datnvt_cvat_cli import CVATClient, DatasetFormat, ServerConfig
474
+
475
+ # Instantiate
476
+ client = CVATClient(
477
+ url="https://cvat.example.com",
478
+ username="myuser",
479
+ password="mypassword",
480
+ project_id=11,
481
+ )
482
+
483
+ # Or from a ServerConfig object
484
+ cfg = ServerConfig(url="...", username="...", password="...", project_id=11)
485
+ client = CVATClient.from_config(cfg)
486
+
487
+ # Pre-flight checks
488
+ ok = client.check_connection() # True if server is reachable and credentials valid
489
+ ok = client.check_project() # True if client.project_id is accessible
490
+ ok = client.check_project(project_id=5) # check a specific project
491
+
492
+ # List projects / tasks
493
+ projects = client.get_projects() # list[dict]
494
+ tasks = client.get_tasks() # all tasks in default project
495
+ tasks = client.get_tasks(project_id=15)
496
+ task_ids = client.get_task_ids() # list[int]
497
+
498
+ # Get task metadata
499
+ info = client.get_task_info(task_id=147)
500
+
501
+ # Download annotations for multiple tasks (default: CVAT for images 1.1)
502
+ client.download_tasks(
503
+ task_ids=[147, 150],
504
+ out_dir="data/raw",
505
+ fmt=DatasetFormat.CVAT, # default
506
+ save_images=False,
507
+ skip_existing=True,
508
+ folder_prefix="task", # default; use "data_" to get data_147/ instead of task147/
509
+ )
510
+
511
+ # Download a single task to a specific path
512
+ from pathlib import Path
513
+ client.download_annotations(
514
+ task_id=147,
515
+ out_path=Path("data/raw/task147"),
516
+ fmt=DatasetFormat.CVAT,
517
+ save_images=True,
518
+ )
519
+
520
+ # Upload annotations for multiple tasks (default: CVAT for images 1.1)
521
+ client.upload_tasks(
522
+ task_ids=[147, 150],
523
+ in_dir="data/processed",
524
+ fmt=DatasetFormat.CVAT, # default
525
+ )
526
+
527
+ # Upload a single annotation file
528
+ client.upload_annotations(
529
+ task_id=147,
530
+ anno_path=Path("data/processed/task147/annotations_pseudo.xml"),
531
+ fmt=DatasetFormat.CVAT,
532
+ )
533
+ ```
534
+
535
+ ---
536
+
537
+ ## Environment variables
538
+
539
+ | Variable | Description |
540
+ |---|---|
541
+ | `CVAT_SERVER_CONFIG` | Path to server YAML config file |
542
+ | `CVAT_URL` | CVAT server URL |
543
+ | `CVAT_USERNAME` | CVAT username |
544
+ | `CVAT_PASSWORD` | CVAT password |
545
+ | `CVAT_PROJECT_ID` | Default project ID |
546
+
547
+ ---
548
+
549
+ ## Annotation file paths
550
+
551
+ After download the expected file layout is:
552
+
553
+ **CVAT for images 1.1 (default):**
554
+ ```
555
+ task{id}/
556
+ annotations.xml
557
+ images/ ← only when save_images=True
558
+ ```
559
+
560
+ **COCO 1.0:**
561
+ ```
562
+ task{id}/
563
+ annotations/
564
+ instances_default.json
565
+ images/ ← only when save_images=True
566
+ ```
567
+
568
+ When uploading, the client looks for `annotations_pseudo.xml` / `instances_default_pseudo.json` first, then falls back to the non-pseudo variants.
569
+
570
+ ---
571
+
572
+ ## License
573
+
574
+ MIT