client.annotations¶
Bases: SyncResource
Sync annotations namespace (client.annotations).
asset_batch_create ¶
asset_batch_create(project_id: UUID | str, asset_id: UUID | str, annotations: list[AnnotationCreateParam], *, replace: bool = False) -> list[Annotation]
Create many annotations on ONE asset in a single sync call — the
labeling submit path. All-or-nothing (any invalid row -> 422, nothing
inserted); source is always manual; replace=True clears the
asset's existing annotations first. Cap 1000 rows.
Raises:
| Type | Description |
|---|---|
UnprocessableError
|
an invalid row (details carry the index) or >1000 rows. |
ConflictError
|
PROJECT_STATE_FORBIDDEN when the asset is edit-locked. |
list ¶
list(project_id: UUID | str, *, class_id: list[UUID | str] | None = None, type: AnnotationType | str | None = None, source: AnnotationSource | str | None = None, created_by: UUID | str | None = None, asset_id: UUID | str | None = None, asset_ids: list[UUID | str] | None = None, instance_id: UUID | str | None = None, created_at_from: datetime | str | None = None, created_at_to: datetime | str | None = None, include: list[str] | None = None, include_total: bool = False, version_id: UUID | str | None = None, limit: int | None = None, cursor: str | None = None) -> Page[Annotation]
Annotation-level list, newest first (created_at DESC, id DESC);
cursor-paginated (iterate for all pages). Wide page size (server cap 200).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
class_id
|
list[UUID | str] | None
|
repeatable class filter — |
None
|
type
|
AnnotationType | str | None
|
geometry discriminator ( |
None
|
source
|
AnnotationSource | str | None
|
provenance — |
None
|
created_by
|
UUID | str | None
|
filter to annotations authored by this user (user UUID). |
None
|
asset_id
|
UUID | str | None
|
single asset; mutually exclusive with |
None
|
asset_ids
|
list[UUID | str] | None
|
repeatable, up to 100 assets (IN); mutually exclusive with
|
None
|
instance_id
|
UUID | str | None
|
filter to annotations sharing this instance id (the multi-shape instance-grouping id). |
None
|
created_at_from
|
datetime | str | None
|
lower bound on |
None
|
created_at_to
|
datetime | str | None
|
upper bound on |
None
|
include
|
list[str] | None
|
sub-resources to embed on each row — any of |
None
|
include_total
|
bool
|
also populate |
False
|
version_id
|
UUID | str | None
|
read from this version's frozen S3 manifests instead of the
live table; REQUIRES |
None
|
Raises:
| Type | Description |
|---|---|
NotFoundError
|
unknown project (PROJECT_NOT_FOUND), or unknown
|
ForbiddenError
|
caller is not a member of this project (AUTH_FORBIDDEN). |
BadRequestError
|
both |
ConflictError
|
|
UnprocessableError
|
invalid |
batch_delete ¶
Hard-delete up to 500 annotations by id, scoped to this project (member+).
Idempotent — ids that match no row in this project come back as skipped.
Live children (parent_id in ids) cascade. For larger sets, chunk.
Raises:
| Type | Description |
|---|---|
NotFoundError
|
unknown project (PROJECT_NOT_FOUND). |
ForbiddenError
|
caller is not a member of this project (AUTH_FORBIDDEN). |
UnprocessableError
|
empty |
project_batch_create ¶
project_batch_create(project_id: UUID | str, *, annotations: list[MappedAnnotationCreateParam], source: AnnotationSource | str = AnnotationSource.MANUAL, replace: bool = False) -> AnnotationBatchCreateResult
Create a flat mapped list of annotations across many assets in one sync
call (ADR-0061, Manager+); 201. Up to 1000 rows; each references its asset
by asset_id or filename. All-or-nothing: any invalid row → 422 with
its index, nothing inserted. replace=True first deletes existing
annotations on every referenced asset.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
annotations
|
list[MappedAnnotationCreateParam]
|
mapped-create row dicts ( |
required |
source
|
AnnotationSource | str
|
provenance stamped on the rows — defaults to |
MANUAL
|
Raises:
| Type | Description |
|---|---|
NotFoundError
|
unknown project (PROJECT_NOT_FOUND). |
ForbiddenError
|
caller is not a project manager (AUTH_FORBIDDEN). |
UnprocessableError
|
empty list, over 1000 rows, or an invalid row (VALIDATION_ERROR — the message names the offending index). |
import_init ¶
Mint a presigned PUT for a staged NDJSON import file (ADR-0061, Manager+);
201. The exact size_bytes is pinned at S3 (cap 256 MB). PUT the raw
NDJSON bytes to upload_url (15-min TTL), then pass the returned
import_id to :meth:bulk_create. Prefer :meth:import_ndjson, which
wires all three steps.
Raises:
| Type | Description |
|---|---|
NotFoundError
|
unknown project (PROJECT_NOT_FOUND). |
ForbiddenError
|
caller is not a project manager (AUTH_FORBIDDEN). |
RateLimitError
|
upload-init rate limit exceeded (RATE_LIMITED). |
UnprocessableError
|
|
bulk_create ¶
bulk_create(project_id: UUID | str, *, annotations: list[MappedAnnotationCreateParam] | None = None, import_id: UUID | str | None = None, source: AnnotationSource | str = AnnotationSource.IMPORTED, replace: bool = False, idempotency_key: str | None = None) -> JobHandle
Kick off an async annotation-create job (ADR-0061, Manager+); returns a
:class:JobHandle (202). Provide EXACTLY ONE of annotations inline
(bounded by the ~6 MB request payload) or import_id from
:meth:import_init (S3-staged NDJSON). The worker scans, validates, and
inserts in resumable batches, reporting per-row errors on the Job.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
source
|
AnnotationSource | str
|
provenance stamped on the rows — defaults to |
IMPORTED
|
replace
|
bool
|
delete existing annotations on referenced assets first. |
False
|
Raises:
| Type | Description |
|---|---|
NotFoundError
|
unknown project (PROJECT_NOT_FOUND); or |
ForbiddenError
|
caller is not a project manager (AUTH_FORBIDDEN). |
ConflictError
|
idempotency key reused with a different body (IDEMPOTENCY_REPLAY). |
RateLimitError
|
per-tenant active-job cap reached (JOB_PER_TENANT_CAP), or the write rate limit (RATE_LIMITED). |
UnprocessableError
|
neither or both of |
import_ndjson ¶
import_ndjson(project_id: UUID | str, rows: list[MappedAnnotationCreateParam], *, source: AnnotationSource | str = AnnotationSource.IMPORTED, replace: bool = False, idempotency_key: str | None = None) -> JobHandle
Convenience: stage rows as NDJSON and kick the async import in one
call (Manager+). Wires the three-step protocol — :meth:import_init to mint
a presigned PUT, upload the encoded NDJSON to S3, then :meth:bulk_create
with the import_id — and returns the resulting :class:JobHandle (202).
Use this instead of inline bulk_create for large imports.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
rows
|
list[MappedAnnotationCreateParam]
|
mapped-create row dicts (same shape as
:meth: |
required |
source
|
AnnotationSource | str
|
provenance stamped on the rows — defaults to |
IMPORTED
|
Raises:
| Type | Description |
|---|---|
NotFoundError / ForbiddenError / RateLimitError / UnprocessableError
|
as raised by :meth: |
batch_edit ¶
batch_edit(project_id: UUID | str, *, creates: list[AnnotationBatchEditCreateParam] | None = None, updates: list[AnnotationBatchEditUpdateParam] | None = None, deletes: list[UUID | str] | None = None) -> AnnotationBatchEditResult
Create, update, and delete annotations in ONE atomic transaction — the
editor "save" path (ADR-0070/0092, member+). At least one bucket must be
non-empty; the combined op count is capped at 1000. Applied order is
create → update → delete; the response echoes each bucket's ids.
All-or-nothing: any validation failure or edit-lock rolls back everything.
deletes is idempotent (ids already gone are no-ops).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
creates
|
list[AnnotationBatchEditCreateParam] | None
|
full new-annotation dicts (client-minted |
None
|
updates
|
list[AnnotationBatchEditUpdateParam] | None
|
partial-update dicts keyed by |
None
|
deletes
|
list[UUID | str] | None
|
annotation ids to hard-delete. |
None
|
Raises:
| Type | Description |
|---|---|
NotFoundError
|
unknown project (PROJECT_NOT_FOUND). |
ForbiddenError
|
caller is not a member of this project (AUTH_FORBIDDEN). |
ConflictError
|
one or more touched assets are edit-locked
(PROJECT_STATE_FORBIDDEN — |
PayloadTooLargeError
|
raw body over the sync cap (PAYLOAD_TOO_LARGE). |
UnprocessableError
|
empty batch, over 1000 ops, duplicate create ids, or
any invalid create/update row (VALIDATION_ERROR —
|
Response models¶
Models returned by client.annotations methods (fields, types, and what each means).
Annotation domain models (ADR-0029 / ADR-0090 / ADR-0092).
Read-side shapes for the client.annotations namespace. The one true list
endpoint (GET .../annotations) returns :class:Annotation rows — the stored
annotation plus, when ?include=asset,class is passed, the embedded
asset summary and the class it is an instance of.
Reserved word: the embedded class ref rides the wire key class (a Python
keyword), so :attr:Annotation.class_ carries BOTH a validation_alias (to
read it) and a serialization_alias (to round-trip it) of "class"
(STYLE.md §types).
Geometry is the tolerant READ union (:data:GeometryRead, ADR-0104): pixel
coordinates with no write-time value constraints re-imposed on a stored row.
ClassRef mirrors the server's flat class serialization (ADR-0090) and reuses
the keypoint/classification config shapes owned by types.classes.
ClassRef ¶
Bases: BaseModel
Flat serialization of the project class an annotation is an instance of
(ADR-0090; embedded on list items under the wire key class). Distinct
from the nested ClassResponse: no inline attributes. kind="object"
classes may carry keypoint_topology; kind="classification" carry a
classification_config.
Annotation ¶
Bases: BaseModel
One annotation row (ADR-0092: the client-minted UUID IS the identity).
Returned by client.annotations.list. asset and class_ are
populated only when the matching include= value is requested; otherwise
None. geometry is None for classification annotations.
AnnotationImportInit ¶
Bases: BaseModel
Result of import-init: a presigned PUT for a staged NDJSON file plus
the import_id to hand to bulk_create once the bytes are uploaded.
AnnotationBatchDeleteResultItem ¶
Bases: BaseModel
Per-id outcome of a batch_delete call.
AnnotationBatchDeleteResult ¶
Bases: BaseModel
Envelope for batch_delete (ADR-0041): total == deleted + skipped
and len(results) == total. skipped = requested ids that matched no
row in this project (already gone, wrong project, or never existed).
AnnotationBatchCreateResult ¶
Bases: BaseModel
Envelope for the sync project_batch_create (create-only): every row is
created or the whole call 422s, so there is no skipped bucket. replaced
counts existing annotations deleted by replace=True across the referenced
assets.
AnnotationBatchEditResult ¶
Bases: BaseModel
Envelope for the transactional batch_edit (ADR-0092): the ids in each
bucket, in request order. deleted excludes ids that were already gone.