From 1dd61d41c0aae33b341b79be0b0061e94f42da27 Mon Sep 17 00:00:00 2001 From: Vaghinak Basentsyan Date: Mon, 24 Jan 2022 15:13:08 +0400 Subject: [PATCH 1/3] Add InstanceTag model. --- pytest.ini | 2 +- src/superannotate_schemas/schemas/base.py | 20 +++++++------------ src/superannotate_schemas/schemas/enums.py | 6 ++++++ .../schemas/external/vector.py | 4 +++- .../schemas/internal/vector.py | 1 + tests/test_cli.py | 3 ++- 6 files changed, 20 insertions(+), 16 deletions(-) diff --git a/pytest.ini b/pytest.ini index d9ab3b4..de4eaf7 100644 --- a/pytest.ini +++ b/pytest.ini @@ -2,4 +2,4 @@ minversion = 3.0 log_cli=true python_files = test_*.py -;addopts = -n auto --dist=loadscope \ No newline at end of file +addopts = -n auto --dist=loadscope diff --git a/src/superannotate_schemas/schemas/base.py b/src/superannotate_schemas/schemas/base.py index 8794bfe..360911c 100644 --- a/src/superannotate_schemas/schemas/base.py +++ b/src/superannotate_schemas/schemas/base.py @@ -26,6 +26,7 @@ from superannotate_schemas.schemas.enums import BaseImageRoleEnum from superannotate_schemas.schemas.enums import VectorAnnotationTypeEnum from superannotate_schemas.schemas.enums import AnnotationStatusEnum +from superannotate_schemas.schemas.enums import TagTypeEnum from superannotate_schemas.schemas.constances import DATE_REGEX from superannotate_schemas.schemas.constances import DATE_TIME_FORMAT_ERROR_MESSAGE from superannotate_schemas.schemas.constances import POINT_LABEL_VALUE_FORMAT_ERROR_MESSAGE @@ -72,12 +73,6 @@ class Tag(BaseModel): __root__: NotEmptyStr -class AttributeGroup(BaseModel): - name: NotEmptyStr - is_multiselect: Optional[bool] = Field(False) - attributes: List[BaseAttribute] - - class BboxPoints(BaseModel): x1: StrictNumber x2: StrictNumber @@ -126,6 +121,12 @@ class BaseInstance(TrackableModel, TimedBaseModel): class_name: Optional[NotEmptyStr] = Field(None, alias="className") +class InstanceTag(BaseInstance): + type: TagTypeEnum + probability: Optional[StrictInt] = Field(100) + attributes: Optional[List[BaseAttribute]] = Field(list()) + + class BaseMetadata(BaseModel): name: NotEmptyStr url: Optional[StrictStr] @@ -220,13 +221,6 @@ class BaseVectorInstance(BaseImageAnnotationInstance): tracking_id: Optional[str] = Field(alias="trackingId") group_id: Optional[int] = Field(alias="groupId") -# -# class Metadata(BaseMetadata): -# name: NotEmptyStr -# status: Optional[AnnotationStatusEnum] -# pinned: Optional[StrictBool] -# is_predicted: Optional[StrictBool] = Field(None, alias="isPredicted") - class PixelColor(BaseModel): __root__: ColorType diff --git a/src/superannotate_schemas/schemas/enums.py b/src/superannotate_schemas/schemas/enums.py index 0b8557b..e8ccdbb 100644 --- a/src/superannotate_schemas/schemas/enums.py +++ b/src/superannotate_schemas/schemas/enums.py @@ -10,6 +10,7 @@ class VectorAnnotationTypeEnum(str, Enum): POLYGON = "polygon" POINT = "point" RBBOX = "rbbox" + TAG = "tag" class CreationTypeEnum(str, Enum): @@ -38,3 +39,8 @@ class BaseImageRoleEnum(str, Enum): ADMIN = "Admin" ANNOTATOR = "Annotator" QA = "QA" + + +class TagTypeEnum(str, Enum): + TAG = "tag" + OBJECT = "object" diff --git a/src/superannotate_schemas/schemas/external/vector.py b/src/superannotate_schemas/schemas/external/vector.py index 637faca..220b7f3 100644 --- a/src/superannotate_schemas/schemas/external/vector.py +++ b/src/superannotate_schemas/schemas/external/vector.py @@ -21,6 +21,7 @@ from superannotate_schemas.schemas.base import NotEmptyStr from superannotate_schemas.schemas.base import StrictNumber from superannotate_schemas.schemas.base import Tag +from superannotate_schemas.schemas.base import InstanceTag from superannotate_schemas.schemas.enums import VectorAnnotationTypeEnum @@ -115,12 +116,13 @@ class Cuboid(VectorInstance): VectorAnnotationTypeEnum.POLYLINE: PolyLine, VectorAnnotationTypeEnum.ELLIPSE: Ellipse, VectorAnnotationTypeEnum.RBBOX: RotatedBox, + VectorAnnotationTypeEnum.TAG: InstanceTag, } class AnnotationInstance(BaseModel): __root__: Union[ - Template, Cuboid, Point, PolyLine, Polygon, Bbox, Ellipse, RotatedBox + Template, Cuboid, Point, PolyLine, Polygon, Bbox, Ellipse, RotatedBox, InstanceTag ] @classmethod diff --git a/src/superannotate_schemas/schemas/internal/vector.py b/src/superannotate_schemas/schemas/internal/vector.py index 4ec86bb..392ba23 100644 --- a/src/superannotate_schemas/schemas/internal/vector.py +++ b/src/superannotate_schemas/schemas/internal/vector.py @@ -112,6 +112,7 @@ class Cuboid(VectorInstance): VectorAnnotationTypeEnum.RBBOX: RotatedBox, } + class AnnotationInstance(BaseModel): __root__: Union[ Template, Cuboid, Point, PolyLine, Polygon, Bbox, Ellipse, RotatedBox diff --git a/tests/test_cli.py b/tests/test_cli.py index c968554..5b995e8 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -82,4 +82,5 @@ def test_(self): # pass # print(time.time() - s) import datetime - print((datetime.datetime.now(datetime.timezone.utc)).strftime("%Y-%m-%dT%H:%M:%S.%f")[:-3] + 'Z') \ No newline at end of file + print((datetime.datetime.now(datetime.timezone.utc)).strftime("%Y-%m-%dT%H:%M:%S.%f")[:-3] + 'Z') + From bb4506f799115976f924873092ba8860e8029b97 Mon Sep 17 00:00:00 2001 From: Shabin Dilanchian Date: Thu, 20 Jan 2022 10:51:40 +0400 Subject: [PATCH 2/3] Schema update --- src/superannotate_schemas/schemas/base.py | 2 +- tests/test_validators.py | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/superannotate_schemas/schemas/base.py b/src/superannotate_schemas/schemas/base.py index 360911c..1dd6878 100644 --- a/src/superannotate_schemas/schemas/base.py +++ b/src/superannotate_schemas/schemas/base.py @@ -140,7 +140,7 @@ class BaseMetadata(BaseModel): class BaseImageMetadata(BaseMetadata): width: Optional[StrictInt] height: Optional[StrictInt] - pinned: Optional[bool] + pinned: Optional[StrictBool] class Correspondence(BaseModel): diff --git a/tests/test_validators.py b/tests/test_validators.py index 939a233..1962ba7 100644 --- a/tests/test_validators.py +++ b/tests/test_validators.py @@ -2147,11 +2147,11 @@ def test_validate_vector_empty_annotation_bad_role(self): }, "width":480, "height":270, + "pinned": [ "fasdf" ], "name":"1 copy_001.jpg", "projectId":181302, "isPredicted":false, "status":"Completed", - "pinned":false, "annotatorEmail":null, "qaEmail":null }, @@ -2209,4 +2209,5 @@ def test_validate_vector_empty_annotation_bad_role(self): data = json.loads(f.read()) validator = AnnotationValidators.get_validator("vector")(data) self.assertFalse(validator.is_valid()) - self.assertEqual(len(validator.generate_report()), 113) \ No newline at end of file + print(validator.generate_report()) + self.assertEqual(len(validator.generate_report()), 191) \ No newline at end of file From 2f23534eaf5952df891e56632dab8421c8c49d3f Mon Sep 17 00:00:00 2001 From: Shabin Dilanchian Date: Thu, 20 Jan 2022 12:40:33 +0400 Subject: [PATCH 3/3] Update base schema --- src/superannotate_schemas/schemas/base.py | 6 +++--- src/superannotate_schemas/schemas/external/vector.py | 6 +++++- src/superannotate_schemas/schemas/internal/vector.py | 9 ++++++++- tests/test_validators.py | 10 +++++++--- 4 files changed, 23 insertions(+), 8 deletions(-) diff --git a/src/superannotate_schemas/schemas/base.py b/src/superannotate_schemas/schemas/base.py index 1dd6878..baed528 100644 --- a/src/superannotate_schemas/schemas/base.py +++ b/src/superannotate_schemas/schemas/base.py @@ -65,8 +65,8 @@ class AxisPoint(BaseModel): class BaseAttribute(BaseModel): id: Optional[StrictInt] group_id: Optional[StrictInt] = Field(alias="groupId") - name: Optional[NotEmptyStr] - group_name: Optional[NotEmptyStr] = Field(alias="groupName") + name: NotEmptyStr + group_name: NotEmptyStr = Field(alias="groupName") class Tag(BaseModel): @@ -121,7 +121,7 @@ class BaseInstance(TrackableModel, TimedBaseModel): class_name: Optional[NotEmptyStr] = Field(None, alias="className") -class InstanceTag(BaseInstance): +class BaseInstanceTag(BaseInstance): type: TagTypeEnum probability: Optional[StrictInt] = Field(100) attributes: Optional[List[BaseAttribute]] = Field(list()) diff --git a/src/superannotate_schemas/schemas/external/vector.py b/src/superannotate_schemas/schemas/external/vector.py index 220b7f3..d04be70 100644 --- a/src/superannotate_schemas/schemas/external/vector.py +++ b/src/superannotate_schemas/schemas/external/vector.py @@ -21,10 +21,14 @@ from superannotate_schemas.schemas.base import NotEmptyStr from superannotate_schemas.schemas.base import StrictNumber from superannotate_schemas.schemas.base import Tag -from superannotate_schemas.schemas.base import InstanceTag +from superannotate_schemas.schemas.base import BaseInstanceTag from superannotate_schemas.schemas.enums import VectorAnnotationTypeEnum +class InstanceTag(BaseInstanceTag): + class_name: NotEmptyStr + + class Attribute(BaseAttribute): name: NotEmptyStr group_name: NotEmptyStr = Field(alias="groupName") diff --git a/src/superannotate_schemas/schemas/internal/vector.py b/src/superannotate_schemas/schemas/internal/vector.py index 392ba23..16cc89b 100644 --- a/src/superannotate_schemas/schemas/internal/vector.py +++ b/src/superannotate_schemas/schemas/internal/vector.py @@ -10,6 +10,7 @@ from superannotate_schemas.schemas.base import Tag from superannotate_schemas.schemas.base import AxisPoint from superannotate_schemas.schemas.base import VectorAnnotationTypeEnum +from superannotate_schemas.schemas.base import BaseInstanceTag from superannotate_schemas.schemas.base import StrictNumber from superannotate_schemas.schemas.base import INVALID_DICT_MESSAGE from superannotate_schemas.schemas.base import BaseModel @@ -24,6 +25,11 @@ from pydantic.error_wrappers import ErrorWrapper + +class InstanceTag(BaseInstanceTag): + class_id: StrictInt + + class Attribute(BaseAttribute): id: StrictInt group_id: StrictInt = Field(alias="groupId") @@ -110,12 +116,13 @@ class Cuboid(VectorInstance): VectorAnnotationTypeEnum.POLYLINE: PolyLine, VectorAnnotationTypeEnum.ELLIPSE: Ellipse, VectorAnnotationTypeEnum.RBBOX: RotatedBox, + VectorAnnotationTypeEnum.TAG: InstanceTag, } class AnnotationInstance(BaseModel): __root__: Union[ - Template, Cuboid, Point, PolyLine, Polygon, Bbox, Ellipse, RotatedBox + Template, Cuboid, Point, PolyLine, Polygon, Bbox, Ellipse, RotatedBox, InstanceTag ] @classmethod diff --git a/tests/test_validators.py b/tests/test_validators.py index 1962ba7..facd2cd 100644 --- a/tests/test_validators.py +++ b/tests/test_validators.py @@ -310,7 +310,12 @@ def test_validate_document_annotation_wrong_class_id(self, mock_print): "email": "some.email@gmail.com", "role": "Admin" }, - "attributes": [], + "attributes": [ + { + "id": 1175876, + "groupId": 338357 + } + ], "creationType": "Manual", "className": "vid" }], @@ -324,8 +329,7 @@ def test_validate_document_annotation_wrong_class_id(self, mock_print): data = json.loads(f.read()) validator = AnnotationValidators.get_validator("document")(data) self.assertFalse(validator.is_valid()) - self.assertEqual(validator.generate_report(), - "instances[0].classId integer type expected") + self.assertEqual(len(validator.generate_report()), 198) def test_validate_document_annotation_with_null_created_at(self): with tempfile.TemporaryDirectory() as tmpdir_name: