11from datetime import datetime , timezone
2+ from enum import Enum , auto
23import json
34import logging
45from multiprocessing .dummy import Pool as ThreadPool
@@ -33,6 +34,7 @@ class Project(DbObject, Updateable, Deletable):
3334 datasets = Relationship .ToMany ("Dataset" , True )
3435 created_by = Relationship .ToOne ("User" , False , "created_by" )
3536 organization = Relationship .ToOne ("Organization" , False )
37+ reviews = Relationship .ToMany ("Review" , True )
3638 labeling_frontend = Relationship .ToOne ("LabelingFrontend" )
3739 labeling_frontend_options = Relationship .ToMany (
3840 "LabelingFrontendOptions" , False , "labeling_frontend_options" )
@@ -104,6 +106,20 @@ def export_labels(self, timeout_seconds=60):
104106 # TODO Mutable (fetched) attributes
105107 # ...many, define which are required for v0.1
106108
109+ def review_metrics (self , net_score ):
110+ """ Returns this Project's review metrics.
111+ Args:
112+ net_score (None or Review.NetScore): Indicates desired metric.
113+ Return:
114+ int, aggregation count of reviews for given net_score.
115+ """
116+ if net_score not in (None ,) + tuple (Review .NetScore ):
117+ raise InvalidQueryError ("Review metrics net score must be either None "
118+ "or one of Review.NetScore values" )
119+ query_str , params = query .project_review_metrics (self , net_score )
120+ res = self .client .execute (query_str , params )
121+ return res ["data" ]["project" ]["reviewMetrics" ]["labelAggregate" ]["count" ]
122+
107123 def setup (self , labeling_frontend , labeling_frontend_options ):
108124 """ Finalizes the Project setup.
109125 Args:
@@ -344,6 +360,11 @@ def create_metadata(self, meta_type, meta_value):
344360
345361
346362class Label (DbObject , Updateable , BulkDeletable ):
363+
364+ def __init__ (self , * args , ** kwargs ):
365+ super ().__init__ (* args , ** kwargs )
366+ self .reviews .supports_filtering = False
367+
347368 label = Field .String ("label" )
348369 seconds_to_label = Field .Float ("seconds_to_label" )
349370 agreement = Field .Float ("agreement" )
@@ -352,11 +373,39 @@ class Label(DbObject, Updateable, BulkDeletable):
352373
353374 project = Relationship .ToOne ("Project" )
354375 data_row = Relationship .ToOne ("DataRow" )
376+ reviews = Relationship .ToMany ("Review" , False )
355377
356378 @staticmethod
357379 def bulk_delete (objects ):
358380 BulkDeletable .bulk_delete (objects , False )
359381
382+ def create_review (self , ** kwargs ):
383+ """ Creates a Review for this label.
384+ Kwargs:
385+ Review attributes. At a minimum a `Review.score` field
386+ value must be provided.
387+ """
388+ kwargs [Review .label .name ] = self
389+ kwargs [Review .project .name ] = self .project ()
390+ return self .client ._create (Review , kwargs )
391+
392+
393+ class Review (DbObject , Deletable , Updateable ):
394+
395+ class NetScore (Enum ):
396+ Negative = auto ()
397+ Zero = auto ()
398+ Positive = auto ()
399+
400+ updated_at = Field .DateTime ("updated_at" )
401+ created_at = Field .DateTime ("created_at" )
402+ score = Field .Float ("score" )
403+
404+ created_by = Relationship .ToOne ("User" , False , "created_by" )
405+ organization = Relationship .ToOne ("Organization" , False )
406+ project = Relationship .ToOne ("Project" , False )
407+ label = Relationship .ToOne ("Label" , False )
408+
360409
361410class AssetMetadata (DbObject ):
362411 VIDEO = "VIDEO"
0 commit comments