Skip to content

Commit faec5bd

Browse files
committed
validate - fix datetime- add error wrapper
1 parent f1962a8 commit faec5bd

File tree

6 files changed

+41
-14
lines changed

6 files changed

+41
-14
lines changed

src/superannotate/lib/app/interface/sdk_interface.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3657,7 +3657,9 @@ def validate_annotations(
36573657
"""
36583658
with open(annotations_json) as file:
36593659
annotation_data = json.loads(file.read())
3660-
response = controller.validate_annotations(project_type, annotation_data, allow_extra=False)
3660+
response = controller.validate_annotations(
3661+
project_type, annotation_data, allow_extra=False
3662+
)
36613663
if response.errors:
36623664
raise AppException(response.errors)
36633665
is_valid, _ = response.data

src/superannotate/lib/core/entities/utils.py

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77
from pydantic import conlist
88
from pydantic import constr
99
from pydantic import EmailStr
10-
from pydantic import Field
1110
from pydantic import Extra
11+
from pydantic import Field
1212
from pydantic import validator
1313
from pydantic.errors import EnumMemberError
1414

@@ -26,9 +26,10 @@ def enum_error_handling(self) -> str:
2626

2727
DATE_REGEX = r"\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d(?:\.\d{3})Z"
2828

29+
DATE_TIME_FORMAT_ERROR_MESSAGE = "Expected format: YYYY-mm-ddTHH:MM:SS.055Z"
2930

30-
class BaseModel(PyDanticBaseModel):
3131

32+
class BaseModel(PyDanticBaseModel):
3233
class Config:
3334
extra = Extra.allow
3435
use_enum_values = True
@@ -106,6 +107,26 @@ class TimedBaseModel(BaseModel):
106107
created_at: constr(regex=DATE_REGEX) = Field(None, alias="createdAt")
107108
updated_at: constr(regex=DATE_REGEX) = Field(None, alias="updatedAt")
108109

110+
@validator("created_at", pre=True)
111+
def validate_created_at(cls, value):
112+
from pydantic import StrRegexError
113+
114+
try:
115+
constr(regex=DATE_REGEX).validate(value)
116+
except StrRegexError:
117+
raise TypeError(DATE_TIME_FORMAT_ERROR_MESSAGE)
118+
return value
119+
120+
@validator("updated_at", pre=True)
121+
def validate_updated_at(cls, value):
122+
from pydantic import StrRegexError
123+
124+
try:
125+
constr(regex=DATE_REGEX).validate(value)
126+
except StrRegexError:
127+
raise TypeError(DATE_TIME_FORMAT_ERROR_MESSAGE)
128+
return value
129+
109130

110131
class UserAction(BaseModel):
111132
email: EmailStr

src/superannotate/lib/core/usecases/images.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3154,11 +3154,11 @@ def execute(self):
31543154

31553155
class ValidateAnnotationUseCase(BaseUseCase):
31563156
def __init__(
3157-
self,
3158-
project_type: str,
3159-
annotation: dict,
3160-
validators: BaseAnnotationValidator,
3161-
allow_extra: bool = True
3157+
self,
3158+
project_type: str,
3159+
annotation: dict,
3160+
validators: BaseAnnotationValidator,
3161+
allow_extra: bool = True,
31623162
):
31633163
super().__init__()
31643164
self._project_type = project_type

src/superannotate/lib/infrastructure/controller.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1642,10 +1642,13 @@ def delete_annotations(
16421642
)
16431643
return use_case.execute()
16441644

1645-
def validate_annotations(self, project_type: str, annotation: dict, allow_extra: bool = False):
1645+
def validate_annotations(
1646+
self, project_type: str, annotation: dict, allow_extra: bool = False
1647+
):
16461648
use_case = usecases.ValidateAnnotationUseCase(
1647-
project_type, annotation,
1649+
project_type,
1650+
annotation,
16481651
validators=self.annotation_validators,
1649-
allow_extra=allow_extra
1652+
allow_extra=allow_extra,
16501653
)
16511654
return use_case.execute()

src/superannotate/lib/infrastructure/validators.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,9 @@ def wrap_error(e: ValidationError) -> str:
2222
error_messages = defaultdict(list)
2323
for error in e.errors():
2424
errors_list = list(error["loc"])
25-
errors_list[1::2] = [f"[{i}]" for i in errors_list[1::2]]
26-
errors_list[2::2] = [f".{i}" for i in errors_list[2::2]]
25+
errors_list[1::] = [
26+
f"[{i}]" if isinstance(i, int) else f".{i}" for i in errors_list[1::]
27+
]
2728
error_messages["".join(errors_list)].append(error["msg"])
2829
texts = ["\n"]
2930
for field, text in error_messages.items():

tests/unit/test_validators.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ def test_validate_annotation_without_metadata(self):
8989
self.assertIn("metadatafieldrequired", out.getvalue().strip().replace(" ", ""))
9090

9191
def test_validate_annotation_invalid_date_time_format(self):
92-
with self.assertRaises(ValidationError):
92+
with self.assertRaisesRegexp(ValidationError,"Expected format: YYYY-mm-ddTHH:MM:SS.055Z"):
9393
TimedBaseModel(createdAt="2021-11-02T15:11:50.065000Z")
9494

9595
def test_validate_annotation_valid_date_time_format(self):

0 commit comments

Comments
 (0)