Skip to content

Commit 10719ef

Browse files
authored
Merge pull request #676 from superannotateai/FRIDAY-2706
fix upload_images_to_project in case of duplicate paths
2 parents 601b44a + ae5ac90 commit 10719ef

File tree

6 files changed

+131
-143
lines changed

6 files changed

+131
-143
lines changed

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

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2051,8 +2051,7 @@ def upload_images_to_project(
20512051
images_to_upload, duplicates = use_case.images_to_upload
20522052
if len(duplicates):
20532053
logger.warning(
2054-
"%s already existing images found that won't be uploaded.",
2055-
len(duplicates),
2054+
f"{len(duplicates)} duplicated images found that won't be uploaded."
20562055
)
20572056
logger.info(f"Uploading {len(images_to_upload)} images to project {project}.")
20582057
uploaded, failed_images, duplications = [], [], duplicates

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1020,11 +1020,12 @@ def filter_paths(self, paths: List[str]):
10201020
name_path_map[Path(path).name].append(path)
10211021

10221022
CHUNK_SIZE = UploadImagesToProject.LIST_NAME_CHUNK_SIZE
1023+
10231024
filtered_paths = []
10241025
duplicated_paths = []
10251026
for file_name in name_path_map:
10261027
if len(name_path_map[file_name]) > 1:
1027-
duplicated_paths.append(name_path_map[file_name][1:])
1028+
duplicated_paths.extend(name_path_map[file_name][1:])
10281029
filtered_paths.append(name_path_map[file_name][0])
10291030

10301031
image_list = []
@@ -1059,7 +1060,7 @@ def images_to_upload(self):
10591060

10601061
def execute(self):
10611062
if self.is_valid():
1062-
images_to_upload, duplications = self.images_to_upload
1063+
images_to_upload, _ = self.images_to_upload
10631064
images_to_upload = images_to_upload[: self.auth_data["availableImageCount"]]
10641065
if not images_to_upload:
10651066
return self._response
@@ -1082,6 +1083,7 @@ def execute(self):
10821083
yield
10831084

10841085
uploaded = []
1086+
duplications = [] # existing items
10851087
for i in range(0, len(uploaded_images), 100):
10861088
response = AttachFileUrlsUseCase(
10871089
project=self._project,

src/superannotate/logger.py

Lines changed: 0 additions & 35 deletions
This file was deleted.

tests/integration/test_duplicate_image_upload.py

Lines changed: 0 additions & 61 deletions
This file was deleted.
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
import io
2+
import os
3+
from os.path import dirname
4+
5+
from src.superannotate import SAClient
6+
from tests.integration.base import BaseTestCase
7+
8+
sa = SAClient()
9+
10+
11+
class TestSingleImageUpload(BaseTestCase):
12+
PROJECT_NAME = "single_image_upload"
13+
PROJECT_DESCRIPTION = "Desc"
14+
PROJECT_TYPE = "Vector"
15+
TEST_FOLDER_PTH = "data_set"
16+
TEST_FOLDER_PATH = "data_set/sample_project_vector"
17+
18+
@property
19+
def folder_path(self):
20+
return os.path.join(dirname(dirname(__file__)), self.TEST_FOLDER_PATH)
21+
22+
@property
23+
def classes_path(self):
24+
return os.path.join(
25+
dirname(dirname(__file__)), self.TEST_FOLDER_PATH, "classes/classes.json"
26+
)
27+
28+
def test_single_image_upload(self):
29+
sa.upload_image_to_project(
30+
self.PROJECT_NAME,
31+
self.folder_path + "/example_image_1.jpg",
32+
annotation_status="InProgress",
33+
)
34+
assert len(sa.search_items(self.PROJECT_NAME)) == 1
35+
36+
with open(self.folder_path + "/example_image_1.jpg", "rb") as f:
37+
img = io.BytesIO(f.read())
38+
39+
sa.upload_image_to_project(
40+
self.PROJECT_NAME, img, image_name="rr.jpg", annotation_status="InProgress"
41+
)
42+
43+
assert len(sa.search_items(self.PROJECT_NAME)) == 2
44+
45+
46+
class TestMultipleImageUpload(BaseTestCase):
47+
PROJECT_NAME = "test_multiple_image_upload"
48+
PROJECT_DESCRIPTION = "Desc"
49+
PROJECT_TYPE = "Vector"
50+
TEST_FOLDER_PTH = "data_set"
51+
TEST_FOLDER_PATH = "data_set/sample_project_vector"
52+
53+
@property
54+
def folder_path(self):
55+
return os.path.join(dirname(dirname(__file__)), self.TEST_FOLDER_PATH)
56+
57+
@property
58+
def classes_path(self):
59+
return os.path.join(
60+
dirname(dirname(__file__)), self.TEST_FOLDER_PATH, "classes/classes.json"
61+
)
62+
63+
def test_multiple_image_upload(self):
64+
(uploaded, could_not_upload, existing_images,) = sa.upload_images_to_project(
65+
self.PROJECT_NAME,
66+
[
67+
f"{self.folder_path}/example_image_1.jpg",
68+
f"{self.folder_path}/example_image_2.jpg",
69+
f"{self.folder_path}/example_image_3.jpg",
70+
f"{self.folder_path}/example_image_4.jpg",
71+
],
72+
annotation_status="InProgress",
73+
)
74+
self.assertEqual(len(uploaded), 4)
75+
self.assertEqual(len(could_not_upload), 0)
76+
self.assertEqual(len(existing_images), 0)
77+
78+
(uploaded, could_not_upload, existing_images,) = sa.upload_images_to_project(
79+
self.PROJECT_NAME,
80+
[
81+
f"{self.folder_path}/example_image_1.jpg",
82+
f"{self.folder_path}/example_image_2.jpg",
83+
f"{self.folder_path}/example_image_3.jpg",
84+
f"{self.folder_path}/example_image_4.jpg",
85+
],
86+
annotation_status="InProgress",
87+
)
88+
self.assertEqual(len(uploaded), 0)
89+
self.assertEqual(len(could_not_upload), 0)
90+
self.assertEqual(len(existing_images), 4)
91+
92+
uploaded, could_not_upload, existing_images = sa.upload_images_to_project(
93+
self.PROJECT_NAME, [f"{self.folder_path}/dd.jpg"]
94+
)
95+
self.assertEqual(len(uploaded), 0)
96+
self.assertEqual(len(could_not_upload), 1)
97+
self.assertEqual(len(existing_images), 0)
98+
99+
def test_multiple_image_upload_with_duplicates(self):
100+
with self.assertLogs("sa", level="INFO") as mock_log:
101+
(
102+
uploaded,
103+
could_not_upload,
104+
existing_images,
105+
) = sa.upload_images_to_project(
106+
self.PROJECT_NAME,
107+
[
108+
f"{self.folder_path}/example_image_1.jpg",
109+
f"{self.folder_path}/example_image_1.jpg",
110+
f"{self.folder_path}/example_image_1.jpg",
111+
f"{self.folder_path}/example_image_3.jpg",
112+
f"{self.folder_path}/example_image_4.jpg",
113+
],
114+
annotation_status="InProgress",
115+
)
116+
assert (
117+
mock_log.records[0].msg
118+
== "2 duplicated images found that won't be uploaded."
119+
)
120+
assert (
121+
mock_log.records[1].msg
122+
== "Uploading 3 images to project test_multiple_image_upload."
123+
)
124+
self.assertEqual(len(uploaded), 3)
125+
self.assertEqual(len(could_not_upload), 0)
126+
self.assertEqual(len(existing_images), 2)

tests/integration/test_single_image_upload.py

Lines changed: 0 additions & 43 deletions
This file was deleted.

0 commit comments

Comments
 (0)