CLI to incrementally sync a QuicLabel COCO dataset (annotations + images) from quiclabel-admin
Project description
quiclabel-coco-sync
CLI to incrementally sync a QuicLabel COCO dataset (annotations + images)
from quiclabel-admin. Pulls a fresh annotations-YYYYMMDD-HHMMSS.json
next to your existing dataset and multi-threadedly downloads only the
images you don't already have.
Prerequisites
- uv — Python package & runtime manager. Install:
- macOS / Linux:
curl -LsSf https://astral.sh/uv/install.sh | sh - Windows:
winget install astral-sh.uv(orirm https://astral.sh/uv/install.ps1 | iex) - via pipx:
pipx install uv
- macOS / Linux:
- An API key — get one from quiclabel-admin: Settings → API Keys → New key.
Copy the
qk_...value immediately (it's only shown once).
Quick start (from PyPI — recommended)
No clone, no install — uvx downloads, caches and runs in one shot:
uvx quiclabel-coco-sync path/to/annotations.json \
--admin-url https://quiclabel-admin.example.com \
--api-key qk_xxxxxxxxxxxxxxxxxxxxxx
Or set env vars and call it bare:
export QUICLABEL_ADMIN_URL=https://quiclabel-admin.example.com
export QUICLABEL_API_KEY=qk_xxxxxxxxxxxxxxxxxxxxxx
uvx quiclabel-coco-sync path/to/annotations.json
Prefer a persistent install? Use uv tool:
uv tool install quiclabel-coco-sync
quiclabel-coco-sync path/to/annotations.json --admin-url ... --api-key ...
From the monorepo (contributors)
# From the repo root
pnpm sync-project-coco path/to/annotations.json \
--admin-url https://quiclabel-admin.example.com \
--api-key qk_xxxxxxxxxxxxxxxxxxxxxx
Or directly with uv against this app directory:
cd apps/quiclabel-sync-project-coco
uv sync
uv run quiclabel-coco-sync path/to/annotations.json \
--admin-url https://quiclabel-admin.example.com \
--api-key qk_xxxxxxxxxxxxxxxxxxxxxx
What it does
- Reads
path/to/annotations.jsonand itsmetablock (added by the COCO exporter). - Calls
GET /api/v1/projects/<project_id>/cocowith the same filters, paging by cursor — so 10k+ task projects don't blow up server memory. - Writes
path/to/annotations-20260519-143045.json(timestamped — never overwrites your input). - Diffs
task_idsets, downloads any missing images topath/to/images/using a thread pool. Files already on disk are skipped by file name.
The old annotations.json and the existing images/* files are never touched.
Configuration priority
Each value is resolved in this order — first wins:
- CLI flag (
--project-id,--statuses, …) - Env var (
QUICLABEL_ADMIN_URL,QUICLABEL_API_KEY) metablock of the input json
If anything required is missing from all three, the CLI exits with a clear message naming the missing key and where to provide it.
Recovery
- Partial failure (some images failed mid-run): just re-run the same command. Already-downloaded files are skipped by file name, so retry only fetches the remaining ones. The CLI tells you this in the failure summary.
- Corrupt image file: delete it, then re-run.
- A
.partfile inimages/indicates a crashed download. Safe to delete.
Development
cd apps/quiclabel-sync-project-coco
uv sync --group dev
uv run pytest
Releasing to PyPI (maintainers)
Releases are tag-driven. Pushing a coco-sync-v<version> tag triggers
.github/workflows/coco-sync-release.yml, which builds, runs tests, and
publishes to PyPI via Trusted Publishers (OIDC — no API token needed).
cd apps/quiclabel-sync-project-coco
# 1. bump version in pyproject.toml (e.g. 0.0.1 -> 0.0.2)
# 2. add a section in CHANGELOG.md
# 3. commit, then tag the exact same version
git add pyproject.toml CHANGELOG.md
git commit -m "coco-sync: release v0.0.2"
git tag coco-sync-v0.0.2
git push && git push origin coco-sync-v0.0.2
The release workflow asserts git tag ↔ pyproject.toml agreement and
fails the publish if they drift.
One-time PyPI Trusted Publisher setup
In https://pypi.org/manage/project/quiclabel-coco-sync/settings/publishing/, add a publisher with:
| Field | Value |
|---|---|
| Owner | weavejam |
| Repository | quiclabel |
| Workflow name | coco-sync-release.yml |
| Environment | pypi |
Also create a pypi environment in GitHub repo settings (optional protection
rules: required reviewers, branch restrictions).
Manual fallback
If the workflow is unavailable, publish from your machine. Note that
uv publish does not read ~/.pypirc (unlike twine) — pass the
token via UV_PUBLISH_TOKEN or --token:
cd apps/quiclabel-sync-project-coco
uv build
# Powershell: extract token from ~/.pypirc and publish
$env:UV_PUBLISH_TOKEN = (Get-Content (Join-Path $env:USERPROFILE '.pypirc') |
Where-Object { $_ -match '^password\s*=' } |
ForEach-Object { ($_ -replace '^password\s*=\s*','').Trim() } |
Select-Object -First 1)
uv publish
# bash equivalent:
export UV_PUBLISH_TOKEN=$(grep '^password' ~/.pypirc | head -1 | sed 's/^password *= *//')
uv publish
Get a PyPI API token at https://pypi.org/manage/account/token/.
⚠️ PyPI versions are immutable. Once a version is published it cannot be overwritten or re-uploaded — even after
yank. Every release must bump theversioninpyproject.toml(e.g.0.0.1→0.0.2).
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file quiclabel_coco_sync-0.0.4.tar.gz.
File metadata
- Download URL: quiclabel_coco_sync-0.0.4.tar.gz
- Upload date:
- Size: 33.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
93f8657a3eee939c389bbb9c9deb72eaa4cf9430a7773fe3757fbe9e24ef233f
|
|
| MD5 |
e84a7eb67e7aec458ee8d5b42f05ac69
|
|
| BLAKE2b-256 |
6d48b1ab11875fdbf80759560f30d94bed579d9fabd11502fcc798ab4910273b
|
Provenance
The following attestation bundles were made for quiclabel_coco_sync-0.0.4.tar.gz:
Publisher:
coco-sync-release.yml on weavejam/quiclabel
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
quiclabel_coco_sync-0.0.4.tar.gz -
Subject digest:
93f8657a3eee939c389bbb9c9deb72eaa4cf9430a7773fe3757fbe9e24ef233f - Sigstore transparency entry: 1624647655
- Sigstore integration time:
-
Permalink:
weavejam/quiclabel@44f5c9a39a664686bc14db2ddb83eff0b8d98e20 -
Branch / Tag:
refs/tags/coco-sync-v0.0.4 - Owner: https://github.com/weavejam
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
coco-sync-release.yml@44f5c9a39a664686bc14db2ddb83eff0b8d98e20 -
Trigger Event:
push
-
Statement type:
File details
Details for the file quiclabel_coco_sync-0.0.4-py3-none-any.whl.
File metadata
- Download URL: quiclabel_coco_sync-0.0.4-py3-none-any.whl
- Upload date:
- Size: 13.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7a0154d803caefcd7b8b107203f014430e72b89e01755863a9e42166eaad5629
|
|
| MD5 |
01effc48d6ee1ccd249d1f6d323dbf73
|
|
| BLAKE2b-256 |
50d0e20fe821ab5b8e331703744b45d890cae8b69a2eb5431e0fc334efe590a9
|
Provenance
The following attestation bundles were made for quiclabel_coco_sync-0.0.4-py3-none-any.whl:
Publisher:
coco-sync-release.yml on weavejam/quiclabel
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
quiclabel_coco_sync-0.0.4-py3-none-any.whl -
Subject digest:
7a0154d803caefcd7b8b107203f014430e72b89e01755863a9e42166eaad5629 - Sigstore transparency entry: 1624647686
- Sigstore integration time:
-
Permalink:
weavejam/quiclabel@44f5c9a39a664686bc14db2ddb83eff0b8d98e20 -
Branch / Tag:
refs/tags/coco-sync-v0.0.4 - Owner: https://github.com/weavejam
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
coco-sync-release.yml@44f5c9a39a664686bc14db2ddb83eff0b8d98e20 -
Trigger Event:
push
-
Statement type: