Skip to content

Commit b97358a

Browse files
authored
Merge pull request #586 from superannotateai/1821_implementation
added OCR groupe type validation in class creation
2 parents 581eaba + a255d59 commit b97358a

File tree

8 files changed

+102
-22
lines changed

8 files changed

+102
-22
lines changed

docs/source/api_reference/api_folder.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,4 @@ Folders
88
.. automethod:: superannotate.SAClient.get_folder_by_id
99
.. automethod:: superannotate.SAClient.get_folder_metadata
1010
.. automethod:: superannotate.SAClient.create_folder
11-
.. automethod:: superannotate.SAClient.delete_folders
11+
.. automethod:: superannotate.SAClient.delete_folders

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import nest_asyncio
12
from lib.core.usecases.annotations import * # noqa: F403 F401
23
from lib.core.usecases.classes import * # noqa: F403 F401
34
from lib.core.usecases.custom_fields import * # noqa: F403 F401
@@ -8,5 +9,4 @@
89
from lib.core.usecases.models import * # noqa: F403 F401
910
from lib.core.usecases.projects import * # noqa: F403 F401
1011

11-
import nest_asyncio
12-
nest_asyncio.apply()
12+
nest_asyncio.apply()

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

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from lib.core.conditions import CONDITION_EQ as EQ
77
from lib.core.entities import AnnotationClassEntity
88
from lib.core.entities import ProjectEntity
9+
from lib.core.entities.classes import GroupTypeEnum
910
from lib.core.enums import ProjectType
1011
from lib.core.exceptions import AppException
1112
from lib.core.serviceproviders import BaseServiceProvider
@@ -66,6 +67,13 @@ def validate_project_type(self):
6667
"Predefined tagging functionality is not supported for projects"
6768
f" of type {ProjectType.get_name(self._project.type)}."
6869
)
70+
if self._project.type != ProjectType.VECTOR:
71+
for g in self._annotation_class.attribute_groups:
72+
if g.group_type == GroupTypeEnum.OCR:
73+
raise AppException(
74+
f"OCR attribute group is not supported for project type "
75+
f"{ProjectType.get_name(self._project.type)}."
76+
)
6977

7078
def validate_default_value(self):
7179
if self._project.type == ProjectType.PIXEL.value and any(
@@ -109,13 +117,19 @@ def __init__(
109117
self._annotation_classes = annotation_classes
110118

111119
def validate_project_type(self):
112-
if self._project.type == ProjectType.PIXEL and any(
113-
[True for i in self._annotation_classes if i.type == "tag"]
114-
):
115-
raise AppException(
116-
f"Predefined tagging functionality is not supported"
117-
f" for projects of type {ProjectType.get_name(self._project.type)}."
118-
)
120+
if self._project.type != ProjectType.VECTOR:
121+
for c in self._annotation_classes:
122+
if self._project.type == ProjectType.PIXEL and c.type == "tag":
123+
raise AppException(
124+
f"Predefined tagging functionality is not supported"
125+
f" for projects of type {ProjectType.get_name(self._project.type)}."
126+
)
127+
for g in c.attribute_groups:
128+
if g.group_type == GroupTypeEnum.OCR:
129+
raise AppException(
130+
f"OCR attribute group is not supported for project type "
131+
f"{ProjectType.get_name(self._project.type)}."
132+
)
119133

120134
def validate_default_value(self):
121135
if self._project.type == ProjectType.PIXEL.value:

tests/integration/classes/test_classes_serialization.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,6 @@ def test_group_type_wrong_arg(self):
7878
"'radio',",
7979
"'checklist',",
8080
"'numeric',",
81-
"'text'",
81+
"'text',",
8282
"'ocr'",
8383
] == wrap_error(e).split()

tests/integration/classes/test_create_annotation_class.py

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,71 @@ def test_create_annotation_class(self):
245245
"Predefined tagging functionality is not supported for projects of type Video.",
246246
)
247247

248+
def test_create_annotation_class_via_ocr_group_type(self):
249+
with self.assertRaisesRegexp(
250+
AppException,
251+
f"OCR attribute group is not supported for project type {self.PROJECT_TYPE}.",
252+
):
253+
attribute_groups = [
254+
{
255+
"id": 21448,
256+
"class_id": 56820,
257+
"name": "Large",
258+
"group_type": "ocr",
259+
"is_multiselect": 0,
260+
"createdAt": "2020-09-29T10:39:39.000Z",
261+
"updatedAt": "2020-09-29T10:39:39.000Z",
262+
"attributes": [],
263+
}
264+
]
265+
sa.create_annotation_class(
266+
self.PROJECT_NAME,
267+
"test_add",
268+
"#FF0000",
269+
attribute_groups,
270+
class_type="tag",
271+
)
272+
273+
def test_create_annotation_class_via_json_and_ocr_group_type(self):
274+
with tempfile.TemporaryDirectory() as tmpdir_name:
275+
temp_path = f"{tmpdir_name}/new_classes.json"
276+
with open(temp_path, "w") as new_classes:
277+
new_classes.write(
278+
"""
279+
[
280+
{
281+
"id":56820,
282+
"project_id":7617,
283+
"name":"Personal vehicle",
284+
"color":"#547497",
285+
"count":18,
286+
"createdAt":"2020-09-29T10:39:39.000Z",
287+
"updatedAt":"2020-09-29T10:48:18.000Z",
288+
"type": "tag",
289+
"attribute_groups":[
290+
{
291+
"id":21448,
292+
"class_id":56820,
293+
"name":"Large",
294+
"group_type": "ocr",
295+
"is_multiselect":0,
296+
"createdAt":"2020-09-29T10:39:39.000Z",
297+
"updatedAt":"2020-09-29T10:39:39.000Z",
298+
"attributes":[]
299+
}
300+
]
301+
}
302+
]
303+
"""
304+
)
305+
with self.assertRaisesRegexp(
306+
AppException,
307+
f"OCR attribute group is not supported for project type {self.PROJECT_TYPE}.",
308+
):
309+
sa.create_annotation_classes_from_classes_json(
310+
self.PROJECT_NAME, temp_path
311+
)
312+
248313

249314
class TestCreateAnnotationClassPixel(BaseTestCase):
250315
PROJECT_NAME = "TestCreateAnnotationClassPixel"

tests/integration/folders/test_set_folder_status.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,7 @@ def tearDownClass(cls) -> None:
3434

3535
def test_set_folder_status(self):
3636
with self.assertLogs("sa", level="INFO") as cm:
37-
for index, status in enumerate(
38-
self.FOLDER_STATUSES
39-
):
37+
for index, status in enumerate(self.FOLDER_STATUSES):
4038
sa.set_folder_status(
4139
project=self.PROJECT_NAME, folder=self.FOLDER_NAME, status=status
4240
)

tests/integration/projects/test_set_project_status.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,7 @@ def tearDownClass(cls) -> None:
3030

3131
def test_set_project_status(self):
3232
with self.assertLogs("sa", level="INFO") as cm:
33-
for index, status in enumerate(
34-
self.PROJECT_STATUSES
35-
):
33+
for index, status in enumerate(self.PROJECT_STATUSES):
3634
sa.set_project_status(project=self.PROJECT_NAME, status=status)
3735
project = sa.get_project_metadata(self.PROJECT_NAME)
3836
assert (

tests/unit/test_async_functions.py

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import asyncio
2+
from unittest import TestCase
23

34
from superannotate import SAClient
4-
from unittest import TestCase
55

66

77
sa = SAClient()
@@ -54,6 +54,7 @@ def test_get_annotations_in_running_event_loop(self):
5454
async def _test():
5555
annotations = sa.get_annotations(self.PROJECT_NAME)
5656
assert len(annotations) == 4
57+
5758
asyncio.run(_test())
5859

5960
def test_create_task_get_annotations_in_running_event_loop(self):
@@ -62,25 +63,29 @@ async def _test():
6263
task2 = asyncio.create_task(self.nested())
6364
await task1
6465
await task2
66+
6567
asyncio.run(_test())
6668

6769
def test_gather_get_annotations_in_running_event_loop(self):
6870
async def gather_test():
6971
await asyncio.gather(self.nested(), self.nested())
72+
7073
asyncio.run(gather_test())
7174

7275
def test_gather_async_for(self):
7376
async def gather_test():
7477
async for _ in DummyIterator(delay=0.01, to=2):
7578
annotations = sa.get_annotations(TestAsyncFunctions.PROJECT_NAME)
7679
assert len(annotations) == 4
80+
7781
asyncio.run(gather_test())
7882

7983
def test_upload_annotations_in_running_event_loop(self):
8084
async def _test():
8185
sa.attach_items(self.PROJECT_NAME, self.ATTACH_PAYLOAD)
82-
annotations = sa.upload_annotations(self.PROJECT_NAME, annotations=self.UPLOAD_PAYLOAD)
83-
assert len(annotations['succeeded']) == 4
84-
asyncio.run(_test())
85-
86+
annotations = sa.upload_annotations(
87+
self.PROJECT_NAME, annotations=self.UPLOAD_PAYLOAD
88+
)
89+
assert len(annotations["succeeded"]) == 4
8690

91+
asyncio.run(_test())

0 commit comments

Comments
 (0)