client.comments¶
Bases: SyncResource
Sync comments namespace (client.comments).
create ¶
create(project_id: UUID | str, asset_id: UUID | str, *, body: str, anchor_kind: AnchorKind | str = AnchorKind.ASSET, anchor_coords: AnchorCoordsParam | None = None, annotation_id: UUID | str | None = None, parent_id: UUID | str | None = None) -> Comment
Create a root comment or a reply (201).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
body
|
str
|
comment text (1..COMMENT_BODY_MAX chars; |
required |
anchor_kind
|
AnchorKind | str
|
|
ASSET
|
anchor_coords
|
AnchorCoordsParam | None
|
|
None
|
annotation_id
|
UUID | str | None
|
required when |
None
|
parent_id
|
UUID | str | None
|
set to reply under a thread root (inherits its anchor). |
None
|
Raises:
| Type | Description |
|---|---|
NotFoundError
|
unknown asset (ASSET_NOT_FOUND) or, for an |
BadRequestError
|
reply to a reply, or reply on a different asset than the root (BAD_REQUEST). |
ConflictError
|
per-asset comment cap reached (RESOURCE_LIMIT_EXCEEDED). |
UnprocessableError
|
anchor shape mismatch / reserved 3D kind (VALIDATION_ERROR). |
ForbiddenError
|
caller is not a project member (AUTH_FORBIDDEN). |
list_for_asset ¶
list_for_asset(project_id: UUID | str, asset_id: UUID | str, *, status: CommentStatus | str | None = None, parent_id: UUID | str | None = None, include_total: bool = False, limit: int | None = None, cursor: str | None = None) -> Page[Comment]
The per-asset thread list, newest first (cursor-paginated). Root
comments only by default; pass parent_id to load replies under one root.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
status
|
CommentStatus | str | None
|
filter root threads by |
None
|
parent_id
|
UUID | str | None
|
when set, returns only the replies under this root. |
None
|
include_total
|
bool
|
also populate |
False
|
Raises:
| Type | Description |
|---|---|
BadRequestError
|
malformed |
ForbiddenError
|
caller is not a project member (AUTH_FORBIDDEN). |
list ¶
list(project_id: UUID | str, *, status: CommentStatus | str | None = None, author: UUID | str | None = None, asset_id: UUID | str | None = None, created_at_from: datetime | str | None = None, created_at_to: datetime | str | None = None, include_total: bool = False, limit: int | None = None, cursor: str | None = None) -> Page[Comment]
The project-wide comment feed (the "issues" view), newest first — roots
only (threading is loaded per-asset via :meth:list_for_asset).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
author
|
UUID | str | None
|
filter to threads opened by this user (the |
None
|
asset_id
|
UUID | str | None
|
filter to threads anchored on this asset. |
None
|
include_total
|
bool
|
also populate |
False
|
Raises:
| Type | Description |
|---|---|
BadRequestError
|
malformed |
ForbiddenError
|
caller is not a project member (AUTH_FORBIDDEN). |
update ¶
update(project_id: UUID | str, comment_id: UUID | str, *, body: str | None = None, anchor_kind: AnchorKind | str | None = None, anchor_coords: AnchorCoordsParam | None = None, annotation_id: UUID | str | None = None, frame_number: int | None = None) -> Comment
Edit a comment's body and/or its anchor (drag-to-move). Pass at least
one of body / anchor fields. Editing any anchor field replaces the
whole anchor, so anchor_kind must be given then. Author or project
manager only; anchor edits apply to root comments only.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
frame_number
|
int | None
|
video-only anchor frame. It is rejected on image assets — the only asset kind today — so any value currently 422s (UnprocessableError: 'frame_number is not valid on image assets'). |
None
|
Raises:
| Type | Description |
|---|---|
NotFoundError
|
unknown comment, or (annotation anchor) unknown annotation (ANNOTATION_NOT_FOUND). |
ForbiddenError
|
caller is neither the author nor a project manager. |
UnprocessableError
|
nothing to update, anchor shape mismatch, missing
|
delete ¶
Soft-delete a comment (204). Replies are preserved. Author or project manager only.
Raises:
| Type | Description |
|---|---|
NotFoundError
|
unknown comment. |
ForbiddenError
|
caller is neither the author nor a project manager. |
resolve ¶
Mark a thread ROOT resolved (any project member). Idempotent.
Raises:
| Type | Description |
|---|---|
NotFoundError
|
unknown comment. |
BadRequestError
|
|
reopen ¶
Reopen a resolved thread ROOT (any project member). Idempotent.
Raises:
| Type | Description |
|---|---|
NotFoundError
|
unknown comment. |
BadRequestError
|
|
Response models¶
Models returned by client.comments methods (fields, types, and what each means).
Comment / issue domain models (ADR-0043).
A comment is project-scoped review feedback anchored to an asset. Its anchor is
one-of four kinds, discriminated by the SIBLING anchor_kind field (NOT a tag
inside the coords blob):
asset— whole-asset note, no coordspoint—anchor_coordsis a :class:PointAnchor(x, y)box—anchor_coordsis a :class:BoxAnchor(x, y, w, h)annotation— pinned toannotation_id, no coords
Because a point dict {x, y} is a field-subset of a box dict, a bare
PointAnchor | BoxAnchor union can't self-discriminate; anchor_coords is
coerced against anchor_kind in a before-validator, mirroring the server.
Depends only on common (enums) — a leaf module in the type dependency graph.
PointAnchor ¶
Bases: BaseModel
A point anchor: normalized coords (one image-dimension of margin, so the server accepts [-1, 2] for drag-to-edge / zoomed-out canvases).
BoxAnchor ¶
Bases: BaseModel
A box anchor: top-left (x, y) + width/height, in the same normalized space.
Comment ¶
Bases: BaseModel
One comment or reply. Roots carry an anchor + a stable per-asset seq
(the "#N" issue number, unique per asset, never reused — gaps after deletes
are expected); replies inherit the root's anchor, carry parent_id, and
have seq=None. reply_count is populated only on roots in list views.