diff --git a/README.md b/README.md index 348fa88..6261a9e 100644 --- a/README.md +++ b/README.md @@ -2967,6 +2967,82 @@ Example of a comment thread object } ``` +### Create Task Comment + +Create a comment on a task (creates a comment together with its first thread). The author is recorded as "via API". + +```python +comment = client.create_task_comment( + task_id="YOUR_TASK_ID", + points=[185.98, 86.55], + text="comment text", + frame=1, +) +``` + +#### Parameters + +| Name | Type | Required | Description | +|------|------|----------|-------------| +| task_id | str | Yes | Task ID the comment belongs to (the task is resolved by task_id alone) | +| points | list | Yes | Comment position as a numeric array | +| text | str | Yes | Comment body text | +| content_id | str | No | Content ID. If omitted and the task has a single content it is auto-selected; required for multi-content tasks | +| type | str | No | Comment type. Only `text` is supported (default: `text`) | +| scale | float | No | Canvas scale | +| frame | int | No | Frame index for sequential/video (1-indexed) | +| status | str | No | Comment status | +| priority | int | No | Comment priority | +| is_resolved | bool | No | Whether the comment is resolved | +| task_annotation_id | str | No | Annotation ID to anchor the comment to | +| color | str | No | Hex color like `#ffffff` | + +The response has the same shape as a comment object in [Get Task Comments](#get-task-comments). + +### Add a Comment Thread (Reply) + +Add a thread (reply) to an existing comment. The author is recorded as "via API". + +```python +comment = client.create_task_comment(comment_id="YOUR_COMMENT_ID", text="reply text") +``` + +#### Parameters + +| Name | Type | Required | Description | +|------|------|----------|-------------| +| comment_id | str | Yes | Parent comment ID | +| text | str | Yes | Thread body text | + +### Update a Comment Thread + +Update the body text of a single thread (message) by its thread ID. + +```python +comment = client.update_task_comment(thread_id="YOUR_THREAD_ID", text="updated text") +``` + +#### Parameters + +| Name | Type | Required | Description | +|------|------|----------|-------------| +| thread_id | str | Yes | Thread ID to update | +| text | str | Yes | New body text | + +### Delete a Comment Thread + +Delete a single thread (message) by its thread ID. When the deleted thread is the comment's last remaining thread, the comment itself is also removed. + +```python +client.delete_task_comment(thread_id="YOUR_THREAD_ID") +``` + +#### Parameters + +| Name | Type | Required | Description | +|------|------|----------|-------------| +| thread_id | str | Yes | Thread ID to delete | + ## Project ### Create Project diff --git a/fastlabel/__init__.py b/fastlabel/__init__.py index 3242504..fa28612 100644 --- a/fastlabel/__init__.py +++ b/fastlabel/__init__.py @@ -5483,6 +5483,65 @@ def get_task_comments( params["limit"] = limit return self.api.get_request(endpoint, params=params) + def create_task_comment( + self, + task_id: str = None, + points: list = None, + text: str = None, + content_id: str = None, + type: str = "text", + scale: float = 0, + frame: int = 0, + status: str = None, + priority: int = None, + is_resolved: bool = False, + task_annotation_id: str = None, + color: str = None, + comment_id: str = None, + ) -> dict: + """ + Create a comment, or add a thread (message/reply) to an existing comment. + The author is recorded as "via API". + """ + if comment_id is not None: + return self.api.post_request( + "comments/" + comment_id + "/threads", payload={"text": text} + ) + endpoint = "comments" + payload = { + "taskId": task_id, + "points": points, + "text": text, + "type": type, + "isResolved": is_resolved, + "scale": scale, + "frame": frame, + } + if content_id is not None: + payload["contentId"] = content_id + if status is not None: + payload["status"] = status + if priority is not None: + payload["priority"] = priority + if task_annotation_id is not None: + payload["taskAnnotationId"] = task_annotation_id + if color is not None: + payload["color"] = color + return self.api.post_request(endpoint, payload=payload) + + def update_task_comment(self, thread_id: str, text: str) -> dict: + """ + Update the body text of a comment thread (message) by its id. + """ + endpoint = "comments/threads/" + thread_id + return self.api.put_request(endpoint, payload={"text": text}) + + def delete_task_comment(self, thread_id: str) -> None: + """ + Delete a comment thread (message) by its id. + """ + self.api.delete_request("comments/threads/" + thread_id) + def get_project_comments( self, project: str,