44
55from labelbox .exceptions import ResourceNotFoundError
66from labelbox .pagination import PaginatedCollection
7- from pydantic import BaseModel , root_validator , Field
7+ from pydantic import BaseModel , model_validator , Field
88from labelbox .schema .search_filters import SearchFilter , build_search_filter
99from labelbox .utils import _CamelCaseMixin
1010from .ontology_kind import EditorTaskType
1111from labelbox .schema .media_type import MediaType
1212from labelbox .schema .labeling_service_status import LabelingServiceStatus
13- from labelbox .utils import _CamelCaseMixin , sentence_case
13+ from labelbox .utils import sentence_case
1414
1515GRAPHQL_QUERY_SELECTIONS = """
1616 id
@@ -58,7 +58,7 @@ class LabelingServiceDashboard(_CamelCaseMixin):
5858 status (LabelingServiceStatus): status of the labeling service
5959 data_rows_count (int): total number of data rows batched in the project
6060 tasks_completed_count (int): number of tasks completed (in the Done queue)
61- tasks_remaining_count (int): number of tasks remaining (in a queue other then Done)
61+ tasks_remaining_count (int): number of tasks remaining (i.e. tasks in progress), None if labeling has not started
6262 tags (List[LabelingServiceDashboardTags]): tags associated with the project
6363 media_type (MediaType): media type of the project
6464 editor_task_type (EditorTaskType): editor task type of the project
@@ -73,7 +73,7 @@ class LabelingServiceDashboard(_CamelCaseMixin):
7373 status : LabelingServiceStatus = Field (frozen = True , default = None )
7474 data_rows_count : int = Field (frozen = True )
7575 tasks_completed_count : int = Field (frozen = True )
76- tasks_remaining_count : int = Field (frozen = True )
76+ tasks_remaining_count : Optional [ int ] = Field (frozen = True , default = None )
7777 media_type : Optional [MediaType ] = Field (frozen = True , default = None )
7878 editor_task_type : EditorTaskType = Field (frozen = True , default = None )
7979 tags : List [LabelingServiceDashboardTags ] = Field (frozen = True , default = None )
@@ -84,8 +84,7 @@ def __init__(self, **kwargs):
8484 super ().__init__ (** kwargs )
8585 if not self .client .enable_experimental :
8686 raise RuntimeError (
87- "Please enable experimental in client to use LabelingService"
88- )
87+ "Please enable experimental in client to use LabelingService" )
8988
9089 @property
9190 def service_type (self ):
@@ -98,28 +97,20 @@ def service_type(self):
9897 if self .editor_task_type is None :
9998 return sentence_case (self .media_type .value )
10099
101- if (
102- self .editor_task_type == EditorTaskType .OfflineModelChatEvaluation
103- and self .media_type == MediaType .Conversational
104- ):
100+ if (self .editor_task_type == EditorTaskType .OfflineModelChatEvaluation
101+ and self .media_type == MediaType .Conversational ):
105102 return "Offline chat evaluation"
106103
107- if (
108- self .editor_task_type == EditorTaskType .ModelChatEvaluation
109- and self .media_type == MediaType .Conversational
110- ):
104+ if (self .editor_task_type == EditorTaskType .ModelChatEvaluation and
105+ self .media_type == MediaType .Conversational ):
111106 return "Live chat evaluation"
112107
113- if (
114- self .editor_task_type == EditorTaskType .ResponseCreation
115- and self .media_type == MediaType .Text
116- ):
108+ if (self .editor_task_type == EditorTaskType .ResponseCreation and
109+ self .media_type == MediaType .Text ):
117110 return "Response creation"
118111
119- if (
120- self .media_type == MediaType .LLMPromptCreation
121- or self .media_type == MediaType .LLMPromptResponseCreation
122- ):
112+ if (self .media_type == MediaType .LLMPromptCreation or
113+ self .media_type == MediaType .LLMPromptResponseCreation ):
123114 return "Prompt response creation"
124115
125116 return sentence_case (self .media_type .value )
@@ -163,8 +154,7 @@ def get_all(
163154 pageInfo { endCursor }
164155 }
165156 }
166- """
167- )
157+ """ )
168158 else :
169159 template = Template (
170160 """query SearchProjectsPyApi($$first: Int, $$from: String) {
@@ -174,13 +164,11 @@ def get_all(
174164 pageInfo { endCursor }
175165 }
176166 }
177- """
178- )
167+ """ )
179168 query_str = template .substitute (
180169 labeling_dashboard_selections = GRAPHQL_QUERY_SELECTIONS ,
181170 search_query = build_search_filter (search_query )
182- if search_query
183- else None ,
171+ if search_query else None ,
184172 )
185173 params : Dict [str , Union [str , int ]] = {}
186174
@@ -198,7 +186,7 @@ def convert_to_labeling_service_dashboard(client, data):
198186 experimental = True ,
199187 )
200188
201- @root_validator ( pre = True )
189+ @model_validator ( mode = 'before' )
202190 def convert_boost_data (cls , data ):
203191 if "boostStatus" in data :
204192 data ["status" ] = LabelingServiceStatus (data .pop ("boostStatus" ))
@@ -212,6 +200,12 @@ def convert_boost_data(cls, data):
212200 if "boostRequestedBy" in data :
213201 data ["created_by_id" ] = data .pop ("boostRequestedBy" )
214202
203+ tasks_remaining_count = data .get ("tasksRemainingCount" , 0 )
204+ tasks_total_count = data .get ("tasksTotalCount" , 0 )
205+ # to avoid confusion, setting tasks_completed_count to None if none of tasks has even completed an none are in flight
206+ if tasks_total_count == 0 and tasks_remaining_count == 0 :
207+ data .pop ("tasksRemainingCount" )
208+
215209 return data
216210
217211 def dict (self , * args , ** kwargs ):
0 commit comments