77from pydantic import conlist
88from pydantic import constr
99from pydantic import EmailStr
10- from pydantic import Field
1110from pydantic import Extra
11+ from pydantic import Field
12+ from pydantic import StrRegexError
1213from pydantic import validator
1314from pydantic .errors import EnumMemberError
1415
@@ -26,9 +27,12 @@ def enum_error_handling(self) -> str:
2627
2728DATE_REGEX = r"\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d(?:\.\d{3})Z"
2829
30+ DATE_TIME_FORMAT_ERROR_MESSAGE = (
31+ "does not match expected format YYYY-MM-DDTHH:MM:SS.fffZ"
32+ )
2933
30- class BaseModel (PyDanticBaseModel ):
3134
35+ class BaseModel (PyDanticBaseModel ):
3236 class Config :
3337 extra = Extra .allow
3438 use_enum_values = True
@@ -86,7 +90,7 @@ class Attribute(BaseModel):
8690
8791
8892class Tag (BaseModel ):
89- __root__ : str
93+ __root__ : NotEmptyStr
9094
9195
9296class AttributeGroup (BaseModel ):
@@ -106,6 +110,22 @@ class TimedBaseModel(BaseModel):
106110 created_at : constr (regex = DATE_REGEX ) = Field (None , alias = "createdAt" )
107111 updated_at : constr (regex = DATE_REGEX ) = Field (None , alias = "updatedAt" )
108112
113+ @validator ("created_at" , pre = True )
114+ def validate_created_at (cls , value ):
115+ try :
116+ constr (regex = DATE_REGEX ).validate (value )
117+ except (TypeError , StrRegexError ):
118+ raise TypeError (DATE_TIME_FORMAT_ERROR_MESSAGE )
119+ return value
120+
121+ @validator ("updated_at" , pre = True )
122+ def validate_updated_at (cls , value ):
123+ try :
124+ constr (regex = DATE_REGEX ).validate (value )
125+ except (TypeError , StrRegexError ):
126+ raise TypeError (DATE_TIME_FORMAT_ERROR_MESSAGE )
127+ return value
128+
109129
110130class UserAction (BaseModel ):
111131 email : EmailStr
@@ -130,8 +150,8 @@ class LastUserAction(BaseModel):
130150
131151
132152class BaseInstance (TrackableModel , TimedBaseModel ):
133- class_id : Optional [str ] = Field (None , alias = "classId" )
134- class_name : Optional [str ] = Field (None , alias = "className" )
153+ class_id : Optional [int ] = Field (None , alias = "classId" )
154+ class_name : Optional [NotEmptyStr ] = Field (None , alias = "className" )
135155
136156
137157class MetadataBase (BaseModel ):
@@ -147,7 +167,7 @@ class MetadataBase(BaseModel):
147167
148168
149169class PointLabels (BaseModel ):
150- __root__ : Dict [constr (regex = r"^[0-9]*$" ), str ] # noqa: F722 E261
170+ __root__ : Dict [constr (regex = r"^[0-9]*$" ), NotEmptyStr ] # noqa: F722 E261
151171
152172
153173class Correspondence (BaseModel ):
@@ -164,7 +184,7 @@ class Comment(TimedBaseModel, TrackableModel):
164184
165185class BaseImageInstance (BaseInstance ):
166186 class_id : Optional [int ] = Field (None , alias = "classId" )
167- class_name : str = Field (alias = "className" )
187+ class_name : NotEmptyStr = Field (alias = "className" )
168188 visible : Optional [bool ]
169189 locked : Optional [bool ]
170190 probability : Optional [int ] = Field (100 )
0 commit comments