Skip to content

Vb/fixes and improvements 3 #1784

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Aug 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
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
21 changes: 11 additions & 10 deletions libs/labelbox/src/labelbox/schema/labeling_service_dashboard.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,18 @@
boostUpdatedAt
boostRequestedBy
boostStatus
tasksCompletedCount
tasksPercentCompleted
tasksRemainingCount
tasksTotalCount
dataRowsCount
dataRowsDoneCount
dataRowsInReviewCount
dataRowsInReworkCount
mediaType
editorTaskType
tags
"""


class LabelingServiceDashboardTags(BaseModel):
id: str
text: str
color: str
type: str
Expand All @@ -43,9 +44,8 @@ class LabelingServiceDashboard(BaseModel):
id (str): project id
name (str): project name
status (LabelingServiceStatus): status of the labeling service
tasks_completed_count (int): number of data rows completed
tasks_remaining_count (int): number of data rows that have not started
tasks_total_count (int): total number of data rows in the project
data_rows_count (int): total number of data rows in the project
data_rows_done_count (int): number of data rows completed
tags (List[LabelingServiceDashboardTags]): tags associated with the project
media_type (MediaType): media type of the project
editor_task_type (EditorTaskType): editor task type of the project
Expand All @@ -57,9 +57,10 @@ class LabelingServiceDashboard(BaseModel):
updated_at: Optional[datetime] = Field(frozen=True, default=None)
created_by_id: Optional[str] = Field(frozen=True, default=None)
status: LabelingServiceStatus = Field(frozen=True, default=None)
tasks_completed_count: int = Field(frozen=True)
tasks_remaining_count: int = Field(frozen=True)
tasks_total_count: int = Field(frozen=True)
data_rows_count: int = Field(frozen=True)
data_rows_done_count: int = Field(frozen=True)
data_rows_in_review_count: int = Field(frozen=True)
data_rows_in_rework_count: int = Field(frozen=True)
media_type: Optional[MediaType] = Field(frozen=True, default=None)
editor_task_type: EditorTaskType = Field(frozen=True, default=None)
tags: List[LabelingServiceDashboardTags] = Field(frozen=True, default=None)
Expand Down
14 changes: 13 additions & 1 deletion libs/labelbox/src/labelbox/schema/search_filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from enum import Enum
from typing import List, Literal, Union

from labelbox.pydantic_compat import BaseModel
from labelbox.pydantic_compat import BaseModel, validator
from labelbox.schema.labeling_service_status import LabelingServiceStatus
from labelbox.utils import format_iso_datetime

Expand Down Expand Up @@ -106,6 +106,8 @@ class WorkspaceFilter(BaseSearchFilter):
class TagFilter(BaseSearchFilter):
"""
Filter for project tags
values are tag ids
"""
operation: Literal[OperationType.Tag] = OperationType.Tag
operator: IdOperator
Expand All @@ -121,6 +123,16 @@ class ProjectStageFilter(BaseSearchFilter):
operator: IdOperator
values: List[LabelingServiceStatus]

@validator('values', pre=True)
def validate_values(cls, values):
disallowed_values = [LabelingServiceStatus.Missing]
for value in values:
if value in disallowed_values:
raise ValueError(
f"{value} is not a valid value for ProjectStageFilter")

return values


class DateValue(BaseSearchFilter):
"""
Expand Down
63 changes: 30 additions & 33 deletions libs/labelbox/tests/integration/test_labeling_dashboard.py
Original file line number Diff line number Diff line change
@@ -1,28 +1,19 @@
from datetime import datetime, timedelta
from time import sleep
from labelbox.schema.labeling_service import LabelingServiceStatus
from labelbox.schema.ontology_kind import EditorTaskType
from labelbox.schema.media_type import MediaType
from labelbox.schema.search_filters import IntegerValue, RangeDateTimeOperatorWithSingleValue, RangeOperatorWithSingleValue, DateRange, RangeOperatorWithValue, DateRangeValue, DateValue, IdOperator, OperationType, OrganizationFilter, TaskCompletedCountFilter, WorkforceRequestedDateFilter, WorkforceRequestedDateRangeFilter, WorkspaceFilter, TaskRemainingCountFilter

ALLOW_TIME_TO_CREATE_DASHBOARD = 5 ## seconds


def test_request_labeling_service_dashboard(requested_labeling_service):
project, _ = requested_labeling_service

labeling_service_dashboard = project.get_labeling_service_dashboard()
assert labeling_service_dashboard.status == LabelingServiceStatus.Requested
assert labeling_service_dashboard.tasks_completed_count == 0
assert labeling_service_dashboard.tasks_remaining_count == 0
assert labeling_service_dashboard.media_type == MediaType.Conversational
assert labeling_service_dashboard.editor_task_type == EditorTaskType.ModelChatEvaluation
assert labeling_service_dashboard.service_type == "Live chat evaluation"
try:
project.get_labeling_service_dashboard()
except Exception as e:
assert False, f"An exception was raised: {e}"

sleep(ALLOW_TIME_TO_CREATE_DASHBOARD)
labeling_service_dashboard = project.client.get_labeling_service_dashboards(
).get_one()
assert labeling_service_dashboard
try:
project.client.get_labeling_service_dashboards().get_one()
except Exception as e:
assert False, f"An exception was raised: {e}"


def test_request_labeling_service_dashboard_filters(requested_labeling_service):
Expand All @@ -33,38 +24,42 @@ def test_request_labeling_service_dashboard_filters(requested_labeling_service):
operator=IdOperator.Is,
values=[organization.uid])

sleep(ALLOW_TIME_TO_CREATE_DASHBOARD)
labeling_service_dashboard = project.client.get_labeling_service_dashboards(
search_query=[org_filter]).get_one()
assert labeling_service_dashboard is not None
try:
project.client.get_labeling_service_dashboards(
search_query=[org_filter]).get_one()
except Exception as e:
assert False, f"An exception was raised: {e}"

workforce_requested_filter_before = WorkforceRequestedDateFilter(
workforce_requested_filter_after = WorkforceRequestedDateFilter(
operation=OperationType.WorforceRequestedDate,
value=DateValue(
operator=RangeDateTimeOperatorWithSingleValue.GreaterThanOrEqual,
value=datetime.strptime("2024-01-01", "%Y-%m-%d")))
year_from_now = (datetime.now() + timedelta(days=365))
workforce_requested_filter_after = WorkforceRequestedDateFilter(
workforce_requested_filter_before = WorkforceRequestedDateFilter(
operation=OperationType.WorforceRequestedDate,
value=DateValue(
operator=RangeDateTimeOperatorWithSingleValue.LessThanOrEqual,
value=year_from_now))

labeling_service_dashboard = project.client.get_labeling_service_dashboards(
search_query=[
try:
project.client.get_labeling_service_dashboards(search_query=[
workforce_requested_filter_after, workforce_requested_filter_before
]).get_one()
assert labeling_service_dashboard is not None
except Exception as e:
assert False, f"An exception was raised: {e}"

workforce_date_range_filter = WorkforceRequestedDateRangeFilter(
operation=OperationType.WorforceRequestedDate,
value=DateRangeValue(operator=RangeOperatorWithValue.Between,
value=DateRange(min="2024-01-01T00:00:00-0800",
max=year_from_now)))

labeling_service_dashboard = project.client.get_labeling_service_dashboards(
search_query=[workforce_date_range_filter]).get_one()
assert labeling_service_dashboard is not None
try:
project.client.get_labeling_service_dashboards(
search_query=[workforce_date_range_filter]).get_one()
except Exception as e:
assert False, f"An exception was raised: {e}"

# with non existing data
workspace_id = "clzzu4rme000008l42vnl4kre"
Expand All @@ -87,7 +82,9 @@ def test_request_labeling_service_dashboard_filters(requested_labeling_service):
value=IntegerValue(
operator=RangeOperatorWithSingleValue.GreaterThanOrEqual, value=0))

labeling_service_dashboard = project.client.get_labeling_service_dashboards(
search_query=[task_done_count_filter, task_remaining_count_filter
]).get_one()
assert labeling_service_dashboard is not None
try:
project.client.get_labeling_service_dashboards(
search_query=[task_done_count_filter, task_remaining_count_filter
]).get_one()
except Exception as e:
assert False, f"An exception was raised: {e}"
16 changes: 14 additions & 2 deletions libs/labelbox/tests/unit/test_unit_search_filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from labelbox.schema.labeling_service import LabelingServiceStatus
from labelbox.schema.search_filters import IntegerValue, RangeDateTimeOperatorWithSingleValue, RangeOperatorWithSingleValue, DateRange, RangeOperatorWithValue, DateRangeValue, DateValue, IdOperator, OperationType, OrganizationFilter, ProjectStageFilter, SharedWithOrganizationFilter, TagFilter, TaskCompletedCountFilter, TaskRemainingCountFilter, WorkforceRequestedDateFilter, WorkforceRequestedDateRangeFilter, WorkforceStageUpdatedFilter, WorkforceStageUpdatedRangeFilter, WorkspaceFilter, build_search_filter
from labelbox.utils import format_iso_datetime
import pytest


def test_id_filters():
Expand All @@ -12,14 +13,25 @@ def test_id_filters():
values=["clphb4vd7000cd2wv1ktu5cwa"]),
WorkspaceFilter(operator=IdOperator.Is,
values=["clphb4vd7000cd2wv1ktu5cwa"]),
TagFilter(operator=IdOperator.Is, values=["tag"]),
TagFilter(operator=IdOperator.Is, values=["cls1vkrw401ab072vg2pq3t5d"]),
ProjectStageFilter(operator=IdOperator.Is,
values=[LabelingServiceStatus.Requested]),
]

assert build_search_filter(
filters
) == '[{operator: "is", values: ["clphb4vd7000cd2wv1ktu5cwa"], type: "organization_id"}, {operator: "is", values: ["clphb4vd7000cd2wv1ktu5cwa"], type: "shared_with_organizations"}, {operator: "is", values: ["clphb4vd7000cd2wv1ktu5cwa"], type: "workspace"}, {operator: "is", values: ["tag"], type: "tag"}, {operator: "is", values: ["REQUESTED"], type: "stage"}]'
) == '[{operator: "is", values: ["clphb4vd7000cd2wv1ktu5cwa"], type: "organization_id"}, {operator: "is", values: ["clphb4vd7000cd2wv1ktu5cwa"], type: "shared_with_organizations"}, {operator: "is", values: ["clphb4vd7000cd2wv1ktu5cwa"], type: "workspace"}, {operator: "is", values: ["cls1vkrw401ab072vg2pq3t5d"], type: "tag"}, {operator: "is", values: ["REQUESTED"], type: "stage"}]'


def test_stage_filter_with_invalid_values():
with pytest.raises(
ValueError,
match="is not a valid value for ProjectStageFilter") as e:
_ = ProjectStageFilter(operator=IdOperator.Is,
values=[
LabelingServiceStatus.Requested,
LabelingServiceStatus.Missing
]),


def test_date_filters():
Expand Down
Loading