11from typing import Any , Dict , List , Union , Optional
22
3- from pydantic import BaseModel , Field , validator
3+ from pydantic import BaseModel , Field , root_validator
44
55from labelbox .utils import camel_case
66from ...annotation_types .annotation import ClassificationAnnotation , VideoClassificationAnnotation
1111
1212
1313class NDFeature (BaseModel ):
14- schema_id : Cuid
14+ name : Optional [str ] = None
15+ schema_id : Optional [Cuid ] = None
1516
16- @validator ('schema_id' , pre = True , always = True )
17- def validate_id (cls , v ):
18- if v is None :
19- raise ValueError (
20- "Schema ids are not set. Use `LabelGenerator.assign_feature_schema_ids`, `LabelList.assign_feature_schema_ids`, or `Label.assign_feature_schema_ids`."
21- )
22- return v
17+ @root_validator ()
18+ def must_set_one (cls , values ):
19+ if ('schema_id' not in values or
20+ values ['schema_id' ] is None ) and ('name' not in values or
21+ values ['name' ] is None ):
22+ raise ValueError ("Schema id or name are not set. Set either one." )
23+ return values
24+
25+ def dict (self , * args , ** kwargs ):
26+ res = super ().dict (* args , ** kwargs )
27+ if 'name' in res and res ['name' ] is None :
28+ res .pop ('name' )
29+ if 'schemaId' in res and res ['schemaId' ] is None :
30+ res .pop ('schemaId' )
31+ return res
2332
2433 class Config :
2534 allow_population_by_field_name = True
@@ -50,27 +59,29 @@ def to_common(self) -> Text:
5059 return Text (answer = self .answer )
5160
5261 @classmethod
53- def from_common (cls , text : Text ,
62+ def from_common (cls , text : Text , name : str ,
5463 feature_schema_id : Cuid ) -> "NDTextSubclass" :
55- return cls (answer = text .answer , schema_id = feature_schema_id )
64+ return cls (answer = text .answer , name = name , schema_id = feature_schema_id )
5665
5766
5867class NDChecklistSubclass (NDFeature ):
5968 answer : List [NDFeature ] = Field (..., alias = 'answers' )
6069
6170 def to_common (self ) -> Checklist :
6271 return Checklist (answer = [
63- ClassificationAnswer (feature_schema_id = answer .schema_id )
72+ ClassificationAnswer (name = answer .name ,
73+ feature_schema_id = answer .schema_id )
6474 for answer in self .answer
6575 ])
6676
6777 @classmethod
68- def from_common (cls , checklist : Checklist ,
78+ def from_common (cls , checklist : Checklist , name : str ,
6979 feature_schema_id : Cuid ) -> "NDChecklistSubclass" :
7080 return cls (answer = [
71- NDFeature (schema_id = answer .feature_schema_id )
81+ NDFeature (name = answer . name , schema_id = answer .feature_schema_id )
7282 for answer in checklist .answer
7383 ],
84+ name = name ,
7485 schema_id = feature_schema_id )
7586
7687 def dict (self , * args , ** kwargs ):
@@ -85,12 +96,14 @@ class NDRadioSubclass(NDFeature):
8596
8697 def to_common (self ) -> Radio :
8798 return Radio (answer = ClassificationAnswer (
88- feature_schema_id = self .answer .schema_id ))
99+ name = self . answer . name , feature_schema_id = self .answer .schema_id ))
89100
90101 @classmethod
91- def from_common (cls , radio : Radio ,
102+ def from_common (cls , radio : Radio , name : str ,
92103 feature_schema_id : Cuid ) -> "NDRadioSubclass" :
93- return cls (answer = NDFeature (schema_id = radio .answer .feature_schema_id ),
104+ return cls (answer = NDFeature (name = radio .answer .name ,
105+ schema_id = radio .answer .feature_schema_id ),
106+ name = name ,
94107 schema_id = feature_schema_id )
95108
96109
@@ -100,12 +113,13 @@ def from_common(cls, radio: Radio,
100113class NDText (NDAnnotation , NDTextSubclass ):
101114
102115 @classmethod
103- def from_common (cls , text : Text , feature_schema_id : Cuid ,
116+ def from_common (cls , text : Text , name : str , feature_schema_id : Cuid ,
104117 extra : Dict [str , Any ], data : Union [TextData ,
105118 ImageData ]) -> "NDText" :
106119 return cls (
107120 answer = text .answer ,
108121 data_row = {'id' : data .uid },
122+ name = name ,
109123 schema_id = feature_schema_id ,
110124 uuid = extra .get ('uuid' ),
111125 )
@@ -115,14 +129,15 @@ class NDChecklist(NDAnnotation, NDChecklistSubclass, VideoSupported):
115129
116130 @classmethod
117131 def from_common (
118- cls , checklist : Checklist , feature_schema_id : Cuid ,
132+ cls , checklist : Checklist , name : str , feature_schema_id : Cuid ,
119133 extra : Dict [str , Any ], data : Union [VideoData , TextData ,
120134 ImageData ]) -> "NDChecklist" :
121135 return cls (answer = [
122- NDFeature (schema_id = answer .feature_schema_id )
136+ NDFeature (name = answer . name , schema_id = answer .feature_schema_id )
123137 for answer in checklist .answer
124138 ],
125139 data_row = {'id' : data .uid },
140+ name = name ,
126141 schema_id = feature_schema_id ,
127142 uuid = extra .get ('uuid' ),
128143 frames = extra .get ('frames' ))
@@ -131,11 +146,13 @@ def from_common(
131146class NDRadio (NDAnnotation , NDRadioSubclass , VideoSupported ):
132147
133148 @classmethod
134- def from_common (cls , radio : Radio , feature_schema_id : Cuid ,
149+ def from_common (cls , radio : Radio , name : str , feature_schema_id : Cuid ,
135150 extra : Dict [str , Any ], data : Union [VideoData , TextData ,
136151 ImageData ]) -> "NDRadio" :
137- return cls (answer = NDFeature (schema_id = radio .answer .feature_schema_id ),
152+ return cls (answer = NDFeature (name = radio .answer .name ,
153+ schema_id = radio .answer .feature_schema_id ),
138154 data_row = {'id' : data .uid },
155+ name = name ,
139156 schema_id = feature_schema_id ,
140157 uuid = extra .get ('uuid' ),
141158 frames = extra .get ('frames' ))
@@ -152,13 +169,14 @@ def from_common(
152169 raise TypeError (
153170 f"Unable to convert object to MAL format. `{ type (annotation .value )} `"
154171 )
155- return classify_obj .from_common (annotation .value ,
172+ return classify_obj .from_common (annotation .value , annotation . name ,
156173 annotation .feature_schema_id )
157174
158175 @staticmethod
159176 def to_common (
160177 annotation : "NDClassificationType" ) -> ClassificationAnnotation :
161178 return ClassificationAnnotation (value = annotation .to_common (),
179+ name = annotation .name ,
162180 feature_schema_id = annotation .schema_id )
163181
164182 @staticmethod
@@ -182,6 +200,7 @@ def to_common(
182200 ) -> Union [ClassificationAnnotation , VideoClassificationAnnotation ]:
183201 common = ClassificationAnnotation (
184202 value = annotation .to_common (),
203+ name = annotation .name ,
185204 feature_schema_id = annotation .schema_id ,
186205 extra = {'uuid' : annotation .uuid })
187206 if getattr (annotation , 'frames' , None ) is None :
@@ -204,7 +223,7 @@ def from_common(
204223 raise TypeError (
205224 f"Unable to convert object to MAL format. `{ type (annotation .value )} `"
206225 )
207- return classify_obj .from_common (annotation .value ,
226+ return classify_obj .from_common (annotation .value , annotation . name ,
208227 annotation .feature_schema_id ,
209228 annotation .extra , data )
210229
0 commit comments