11from typing import Any , Dict , List , Union , Optional
22
33from pydantic import BaseModel , Field , root_validator
4+ from labelbox .data .mixins import ConfidenceMixin
45
56from labelbox .utils import camel_case
67from ...annotation_types .annotation import ClassificationAnnotation , VideoClassificationAnnotation
1011from .base import NDAnnotation
1112
1213
13- class NDFeature (BaseModel ):
14+ class NDFeature (ConfidenceMixin ):
1415 name : Optional [str ] = None
1516 schema_id : Optional [Cuid ] = None
1617
@@ -41,7 +42,7 @@ class FrameLocation(BaseModel):
4142
4243
4344class VideoSupported (BaseModel ):
44- #Note that frames are only allowed as top level inferences for video
45+ # Note that frames are only allowed as top level inferences for video
4546 frames : Optional [List [FrameLocation ]] = None
4647
4748 def dict (self , * args , ** kwargs ):
@@ -70,15 +71,18 @@ class NDChecklistSubclass(NDFeature):
7071 def to_common (self ) -> Checklist :
7172 return Checklist (answer = [
7273 ClassificationAnswer (name = answer .name ,
73- feature_schema_id = answer .schema_id )
74+ feature_schema_id = answer .schema_id ,
75+ confidence = answer .confidence )
7476 for answer in self .answer
7577 ])
7678
7779 @classmethod
7880 def from_common (cls , checklist : Checklist , name : str ,
7981 feature_schema_id : Cuid ) -> "NDChecklistSubclass" :
8082 return cls (answer = [
81- NDFeature (name = answer .name , schema_id = answer .feature_schema_id )
83+ NDFeature (name = answer .name ,
84+ schema_id = answer .feature_schema_id ,
85+ confidence = answer .confidence )
8286 for answer in checklist .answer
8387 ],
8488 name = name ,
@@ -95,19 +99,22 @@ class NDRadioSubclass(NDFeature):
9599 answer : NDFeature
96100
97101 def to_common (self ) -> Radio :
98- return Radio (answer = ClassificationAnswer (
99- name = self .answer .name , feature_schema_id = self .answer .schema_id ))
102+ return Radio (
103+ answer = ClassificationAnswer (name = self .answer .name ,
104+ feature_schema_id = self .answer .schema_id ,
105+ confidence = self .answer .confidence ))
100106
101107 @classmethod
102108 def from_common (cls , radio : Radio , name : str ,
103109 feature_schema_id : Cuid ) -> "NDRadioSubclass" :
104110 return cls (answer = NDFeature (name = radio .answer .name ,
105- schema_id = radio .answer .feature_schema_id ),
111+ schema_id = radio .answer .feature_schema_id ,
112+ confidence = radio .answer .confidence ),
106113 name = name ,
107114 schema_id = feature_schema_id )
108115
109116
110- ### ====== End of subclasses
117+ # ====== End of subclasses
111118
112119
113120class NDText (NDAnnotation , NDTextSubclass ):
@@ -133,7 +140,9 @@ def from_common(
133140 extra : Dict [str , Any ], data : Union [VideoData , TextData ,
134141 ImageData ]) -> "NDChecklist" :
135142 return cls (answer = [
136- NDFeature (name = answer .name , schema_id = answer .feature_schema_id )
143+ NDFeature (name = answer .name ,
144+ schema_id = answer .feature_schema_id ,
145+ confidence = answer .confidence )
137146 for answer in checklist .answer
138147 ],
139148 data_row = {'id' : data .uid },
@@ -150,7 +159,8 @@ def from_common(cls, radio: Radio, name: str, feature_schema_id: Cuid,
150159 extra : Dict [str , Any ], data : Union [VideoData , TextData ,
151160 ImageData ]) -> "NDRadio" :
152161 return cls (answer = NDFeature (name = radio .answer .name ,
153- schema_id = radio .answer .feature_schema_id ),
162+ schema_id = radio .answer .feature_schema_id ,
163+ confidence = radio .answer .confidence ),
154164 data_row = {'id' : data .uid },
155165 name = name ,
156166 schema_id = feature_schema_id ,
@@ -241,6 +251,11 @@ def lookup_classification(
241251 }.get (type (annotation .value ))
242252
243253
244- NDSubclassificationType = Union [NDRadioSubclass , NDChecklistSubclass ,
254+ # Make sure to keep NDChecklistSubclass prior to NDRadioSubclass in the list,
255+ # otherwise list of answers gets parsed by NDRadio whereas NDChecklist must be used
256+ NDSubclassificationType = Union [NDChecklistSubclass , NDRadioSubclass ,
245257 NDTextSubclass ]
246- NDClassificationType = Union [NDRadio , NDChecklist , NDText ]
258+
259+ # Make sure to keep NDChecklist prior to NDRadio in the list,
260+ # otherwise list of answers gets parsed by NDRadio whereas NDChecklist must be used
261+ NDClassificationType = Union [NDChecklist , NDRadio , NDText ]
0 commit comments