From 85e04077c1d242fdc719c08b725146ad83601ec7 Mon Sep 17 00:00:00 2001 From: Shabin Dilanchian Date: Mon, 24 Jan 2022 17:53:44 +0400 Subject: [PATCH 1/3] Fix preannotation upload --- .../lib/app/interface/sdk_interface.py | 1 + .../lib/core/entities/annotation_classes.py | 20 ++++++ tests/integration/test_interface.py | 69 +++++++++++++++++++ 3 files changed, 90 insertions(+) create mode 100644 src/superannotate/lib/core/entities/annotation_classes.py diff --git a/src/superannotate/lib/app/interface/sdk_interface.py b/src/superannotate/lib/app/interface/sdk_interface.py index 867fe057f..0a1366bdf 100644 --- a/src/superannotate/lib/app/interface/sdk_interface.py +++ b/src/superannotate/lib/app/interface/sdk_interface.py @@ -2051,6 +2051,7 @@ def upload_preannotations_from_folder_to_project( folder_name=folder_name, annotation_paths=annotation_paths, # noqa: E203 client_s3_bucket=from_s3_bucket, + folder_path=folder_path, is_pre_annotations=True, ) if response.errors: diff --git a/src/superannotate/lib/core/entities/annotation_classes.py b/src/superannotate/lib/core/entities/annotation_classes.py new file mode 100644 index 000000000..8f97f3fa3 --- /dev/null +++ b/src/superannotate/lib/core/entities/annotation_classes.py @@ -0,0 +1,20 @@ +from pydantic import BaseModel +from pydantic import StrictStr +from pydantic import StrictBool +from typing import List + + +class Attribute(BaseModel): + name: StrictStr + + +class AttributeGroup(BaseModel): + name: StrictStr + is_multiselect: StrictBool + attributes: List[Attribute] + + +class AnnotationClass(BaseModel): + name : StrictStr + color: StrictStr + attribute_groups: List[AttributeGroup] diff --git a/tests/integration/test_interface.py b/tests/integration/test_interface.py index 5e73fb7b3..427b486e2 100644 --- a/tests/integration/test_interface.py +++ b/tests/integration/test_interface.py @@ -20,6 +20,11 @@ class TestInterface(BaseTestCase): NEW_IMAGE_NAME = "new_name_yup" IMAGE_PATH_IN_S3 = 'MP.MB/img1.bmp' TEST_S3_BUCKET_NAME = "test-openseadragon-1212" + TEST_INVALID_ANNOTATION_FOLDER_PATH = "sample_project_vector_invalid" + + @property + def invalid_json_path(self): + return os.path.join(self.data_set_path, self.TEST_INVALID_ANNOTATION_FOLDER_PATH) @property def data_set_path(self): @@ -172,6 +177,70 @@ def test_validate_log_for_single_uplaod(self): ) self.assertEqual(len(logs[1][0]), 150) + sa.upload_image_annotations( + self.PROJECT_NAME, self.EXAMPLE_IMAGE_1, { + "metadata": { + "name": "example_image_1.jpg", + "width": 1024, + "height": 683, + "status": "Completed", + }, + "instance": [] + } + ) + self.assertEqual(len(logs[1][1]), 86) + + sa.upload_images_from_folder_to_project( + self.PROJECT_NAME, self.folder_path, annotation_status="InProgress" + ) + uploaded_annotations, failed_annotations, missing_annotations = sa.upload_annotations_from_folder_to_project( + self.PROJECT_NAME, self.invalid_json_path + ) + self.assertEqual(len(uploaded_annotations), 3) + self.assertEqual(len(failed_annotations), 1) + self.assertEqual(len(missing_annotations), 0) + self.assertEqual(len(logs[1][2].split("from")[0]), 98) + self.assertEqual(len(logs[1][3]), 66) + self.assertEqual(len(logs[1][4]), 53) + self.assertEqual(len(logs[1][5]), 160) + self.assertEqual(len(logs[1][6].split("from")[0]), 32) + + uploaded_annotations, failed_annotations, missing_annotations = sa.upload_preannotations_from_folder_to_project( + self.PROJECT_NAME, self.invalid_json_path + ) + self.assertEqual(len(uploaded_annotations), 3) + self.assertEqual(len(failed_annotations), 1) + self.assertEqual(len(missing_annotations), 0) + + with tempfile.TemporaryDirectory() as tmpdir_name: + path = f"{tmpdir_name}/annotation___objects.json" + with open(path, "w") as annotation: + annotation.write( + ''' + { + "metadata": { + "name": "text_file_example_1", + "status": "NotStarted", + "url": "https://sa-public-files.s3.us-west-2.amazonaws.com/Text+project/text_file_example_1.txt", + "projectId": 167826, + "annotatorEmail": null, + "qaEmail": null, + "lastAction": { + "email": "some.email@gmail.com", + "timestamp": 1636620976450 + } + }, + "instances": [], + "tags": [] + } + ''' + ) + sa.upload_image_annotations(self.PROJECT_NAME, self.EXAMPLE_IMAGE_1, path) + self.assertEqual(len(logs[1][-1]),86) + self.assertEqual(len(logs[1][-2].split('from')[0]),30) + + + class TestPixelInterface(BaseTestCase): From 31a10e16ca98ad0990816b5dbf5e8a8ca656b119 Mon Sep 17 00:00:00 2001 From: Shabin Dilanchian Date: Mon, 24 Jan 2022 18:09:52 +0400 Subject: [PATCH 2/3] Delete unused --- .../lib/core/entities/annotation_classes.py | 20 ------------------- 1 file changed, 20 deletions(-) delete mode 100644 src/superannotate/lib/core/entities/annotation_classes.py diff --git a/src/superannotate/lib/core/entities/annotation_classes.py b/src/superannotate/lib/core/entities/annotation_classes.py deleted file mode 100644 index 8f97f3fa3..000000000 --- a/src/superannotate/lib/core/entities/annotation_classes.py +++ /dev/null @@ -1,20 +0,0 @@ -from pydantic import BaseModel -from pydantic import StrictStr -from pydantic import StrictBool -from typing import List - - -class Attribute(BaseModel): - name: StrictStr - - -class AttributeGroup(BaseModel): - name: StrictStr - is_multiselect: StrictBool - attributes: List[Attribute] - - -class AnnotationClass(BaseModel): - name : StrictStr - color: StrictStr - attribute_groups: List[AttributeGroup] From 8e5becd2e01e72d072687dd157146d5869fc59e1 Mon Sep 17 00:00:00 2001 From: Shabin Dilanchian Date: Mon, 24 Jan 2022 18:11:17 +0400 Subject: [PATCH 3/3] Remove dup log --- src/superannotate/lib/app/interface/sdk_interface.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/superannotate/lib/app/interface/sdk_interface.py b/src/superannotate/lib/app/interface/sdk_interface.py index 0a1366bdf..08f20ebff 100644 --- a/src/superannotate/lib/app/interface/sdk_interface.py +++ b/src/superannotate/lib/app/interface/sdk_interface.py @@ -2039,7 +2039,6 @@ def upload_preannotations_from_folder_to_project( "The JSON files should follow a specific naming convention, matching file names already present " "on the platform. Existing annotations will be overwritten" ) - logger.info("Existing annotations will be overwritten.",) annotation_paths = get_annotation_paths( folder_path, from_s3_bucket, recursive_subfolders )