99from pydantic import EmailStr
1010from pydantic import Extra
1111from 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,15 @@ 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" , "updated_at" , pre = True )
114+ def validate_created_at (cls , value ):
115+ try :
116+ if value is not None :
117+ constr (regex = DATE_REGEX ).validate (value )
118+ except (TypeError , StrRegexError ):
119+ raise TypeError (DATE_TIME_FORMAT_ERROR_MESSAGE )
120+ return value
121+
109122
110123class UserAction (BaseModel ):
111124 email : EmailStr
@@ -126,15 +139,16 @@ def clean_creation_type(cls, _):
126139
127140class LastUserAction (BaseModel ):
128141 email : EmailStr
129- timestamp : float
142+ timestamp : int
130143
131144
132145class BaseInstance (TrackableModel , TimedBaseModel ):
133- class_id : Optional [str ] = Field (None , alias = "classId" )
134- class_name : Optional [str ] = Field (None , alias = "className" )
146+ class_id : Optional [int ] = Field (None , alias = "classId" )
147+ class_name : Optional [NotEmptyStr ] = Field (None , alias = "className" )
135148
136149
137150class MetadataBase (BaseModel ):
151+ url : Optional [str ]
138152 name : NotEmptyStr
139153 last_action : Optional [LastUserAction ] = Field (None , alias = "lastAction" )
140154 width : Optional [int ]
@@ -146,7 +160,7 @@ class MetadataBase(BaseModel):
146160
147161
148162class PointLabels (BaseModel ):
149- __root__ : Dict [constr (regex = r"^[0-9]*$" ), str ] # noqa: F722 E261
163+ __root__ : Dict [constr (regex = r"^[0-9]*$" ), NotEmptyStr ] # noqa: F722 E261
150164
151165
152166class Correspondence (BaseModel ):
@@ -163,7 +177,7 @@ class Comment(TimedBaseModel, TrackableModel):
163177
164178class BaseImageInstance (BaseInstance ):
165179 class_id : Optional [int ] = Field (None , alias = "classId" )
166- class_name : str = Field (alias = "className" )
180+ class_name : NotEmptyStr = Field (alias = "className" )
167181 visible : Optional [bool ]
168182 locked : Optional [bool ]
169183 probability : Optional [int ] = Field (100 )
0 commit comments