annotide
Python SDK and command line for the Annotide API (API-3). One
runtime dependency (httpx); responses are plain dicts typed with
TypedDicts generated from the API's OpenAPI document.
pip install annotide # or `pip install -e sdk` from a checkout
export ANNOTIDE_URL=https://annotate.example.com
export ANNOTIDE_API_KEY=... # Settings → API keys; use a service account for CI
Python
from annotide import Client, JobFailedError
with Client() as client: # reads ANNOTIDE_URL / ANNOTIDE_API_KEY
project = next(p for p in client.list_projects() if p["name"] == "Cars")
# Freeze the dataset, then export it reproducibly.
snapshot = client.take_snapshot(
project["id"],
"2026-q3",
split={"train": 0.8, "val": 0.1, "test": 0.1, "seed": 0, "group_by": "folder"},
)
client.export(project["id"], "coco", "train.zip", snapshot_id=snapshot["id"], split="train")
# Import existing labels; a dry run reports what would happen.
report = client.import_file(project["id"], "labels.json", "coco", dry_run=True)
print(report["result"])
- Errors are
ApiError(status,title,detailfrom the RFC 9457 body); a job that endsfailed/cancelledraisesJobFailedError, one that outlives itstimeoutraisesJobTimeoutError. - A 429 waits for
Retry-Afterand repeats. Gateway errors (502/503/504) repeat only when that is harmless: reads, and creates, which always carry anIdempotency-Keyso a repeat answers the first row. - Export downloads go straight to storage with the signed URL; the API key is never sent there.
client.request(method, path, ...)reaches any endpoint without a method.
Command line
annotide whoami
annotide projects list | jq -r '.name'
annotide snapshots create <project> 2026-q3 --split 0.8,0.1,0.1 --group-by folder
annotide export <project> --format coco --snapshot <id> --split train -o train.zip
annotide import <project> labels.json --format coco --class-map '{"auto": "car"}' --dry-run
annotide jobs wait <job>
Lists print as JSON Lines, single objects as JSON; errors go to stderr with
exit status 1. The key is read from ANNOTIDE_API_KEY only, so it never
lands in shell history.
MCP server for AI agents (API-8)
annotide mcp serves the Model Context Protocol
over stdio, so an AI agent (Claude Code, Claude Desktop, or any MCP client)
can pre-label a project. It calls the REST API with an API key, so the agent
can do exactly what that account may do. It can list projects and their label
schema, view items (images come back as images), read annotations, claim and
release tasks, and post pre-labels. It cannot submit, review, delete or
export.
Setup, once per agent:
- Service account. Settings → API keys → Service accounts: create one,
mint a
writekey, and add the account to the project as an annotator. - Model. Models → Register model, name it after the agent, and leave the endpoint empty. That makes it an external producer: the platform never calls it, and the agent posts the pre-labels. Add version 1 and note its id.
- Client config. For Claude Code (
.mcp.json) or Claude Desktop:
{
"mcpServers": {
"annotation": {
"command": "annotation",
"args": ["mcp"],
"env": {
"ANNOTIDE_URL": "https://annotate.example.com",
"ANNOTIDE_API_KEY": "ak_…",
"ANNOTIDE_MODEL_VERSION_ID": "<model version id>"
}
}
}
}
Install with pip install "annotide[mcp]". Pre-labels arrive as
draft versions authored by the model version. People review and submit
them as usual, and a pre-label never replaces human work (ML-10).
Development
make install # from the repository root: creates sdk/.venv
cd sdk && .venv/bin/pytest && .venv/bin/mypy annotide tests tools
make openapi # after an API change: docs/openapi.json + models.py
annotide/models.py is generated; never edit it by hand. CI fails when
it or docs/openapi.json is stale.
Metadata
Release files for annotide 0.2.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| annotide-0.2.1.tar.gz | 43.3 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| annotide-0.2.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 79.9 kB
Release files / annotide-0.2.1.tar.gz
| Download URL | annotide-0.2.1.tar.gz |
|---|---|
| Size | 43.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
4bda6e3dff46765c2df4a63b5027650b0735ffb035998bb04f2397e982bf2b96
|
|
BLAKE2b-256 checksum How to use checksums |
09f46920f27bd1c9bb5726b4bf48e484ba68c01e45ee3bf9e1a650d8e9fb873b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 16, 2026.
Transparency logRelease files / annotide-0.2.1-py3-none-any.whl
| Download URL | annotide-0.2.1-py3-none-any.whl |
|---|---|
| Size | 36.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
7c87d4efaa4d70d4b099c2bdcf5598b1c9606c3d1e5c78d508131f67c08af8ea
|
|
BLAKE2b-256 checksum How to use checksums |
d6faf66f74731b9dbbca63d4f60b66a5d50f16e09d401e4bd8e87997b5684721
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 16, 2026.
Transparency log