Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 56 additions & 0 deletions encord/orm/project.py
Original file line number Diff line number Diff line change
Expand Up @@ -600,3 +600,59 @@ class ProjectUserResponse(BaseDTO):

user_email: str
user_role: ProjectUserRole


# --- Bulk classifications endpoint DTOs ---


class BulkClassificationsPayload(BaseDTO):
"""Request payload for ``POST /projects/{uuid}/label-rows/classifications``."""

label_uuids: List[str]
branch_name: str = "main"


class ClassificationAnswerObject(BaseDTO):
"""Nested answer within a :class:`ClassificationAnswerEntry`."""

name: str
value: str
answers: Any # list[AnswersAnswer] | str | float
feature_hash: str
manual_annotation: bool


class ClassificationAnswerEntry(BaseDTO):
"""Single classification answer returned by the bulk classifications endpoint.

Matches the ``ClassificationAnswer`` shape produced by the legacy
``initialise_labels`` SDK path.
"""

classification_hash: str
feature_hash: Optional[str] = None
classifications: List[ClassificationAnswerObject]
range: Optional[List[Tuple[int, int]]] = None
created_at: Optional[str] = None
created_by: Optional[str] = None
last_edited_at: Optional[str] = None
last_edited_by: Optional[str] = None
manual_annotation: Optional[bool] = None


class LabelClassificationsEntry(BaseDTO):
"""One label row's classification data in the bulk response."""

label_uuid: UUID
data_uuid: UUID
data_title: Optional[str] = None
branch_name: str = "main"
classification_answers: Dict[str, ClassificationAnswerEntry] = {}
export_uuid: Optional[UUID] = None
exported_at: Optional[datetime.datetime] = None


class BulkClassificationsResponse(BaseDTO):
"""Response from ``POST /projects/{uuid}/label-rows/classifications``."""

labels: List[LabelClassificationsEntry]
40 changes: 40 additions & 0 deletions encord/project.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,11 @@
)
from encord.orm.project import (
AddProjectIssueTagsPayload,
BulkClassificationsPayload,
BulkClassificationsResponse,
CopyDatasetOptions,
CopyLabelsOptions,
LabelClassificationsEntry,
ProjectDataset,
ProjectDTO,
ProjectStatus,
Expand Down Expand Up @@ -287,6 +290,43 @@ def list_label_rows_v2(
]
return label_rows

def get_label_classifications(
self,
label_uuids: List[Union[str, UUID]],
branch_name: str = "main",
batch_size: int = 500,
Comment thread
deoracord marked this conversation as resolved.
) -> List[LabelClassificationsEntry]:
"""Fast bulk fetch of classification answers only.

Calls the ``POST /projects/{uuid}/label-rows/classifications`` endpoint
Comment thread
deoracord marked this conversation as resolved.
Outdated
which skips the full enrichment pipeline (no objects, no data-units, no
signed URLs). Returns classification answers in the same shape as the
legacy ``initialise_labels`` path so existing SDK types can consume them.

Args:
label_uuids: Label row UUIDs to fetch classifications for.
Obtain these from :meth:`list_label_rows_v2` (``row.label_hash``).
branch_name: Label branch to read from (default ``"main"``).
batch_size: Number of labels per server request (max 1000).

Returns:
A flat list of :class:`~encord.orm.project.LabelClassificationsEntry`,
one per label row. Each entry contains ``classification_answers``
keyed by classification hash.
"""
uuid_strs = [str(u) for u in label_uuids]
results: List[LabelClassificationsEntry] = []
for i in range(0, len(uuid_strs), batch_size):
batch = uuid_strs[i : i + batch_size]
response = self._api_client.post(
f"projects/{self.project_hash}/label-rows/classifications",
params=None,
payload=BulkClassificationsPayload(label_uuids=batch, branch_name=branch_name),
result_type=BulkClassificationsResponse,
)
results.extend(response.labels)
return results
Comment thread
deoracord marked this conversation as resolved.
Outdated

def add_users(self, user_emails: List[str], user_role: ProjectUserRole) -> List[ProjectUser]:
"""Add users to the project.

Expand Down
Loading