Skip to content

Commit 28b8680

Browse files
authored
Merge pull request #536 from superannotateai/friday
Friday
2 parents fb88bda + 071af7a commit 28b8680

File tree

8 files changed

+57
-44
lines changed

8 files changed

+57
-44
lines changed

src/superannotate/__init__.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,7 @@
11
import os
22
import sys
33

4-
5-
6-
__version__ = "4.4.7dev2"
7-
4+
__version__ = "4.4.7dev6"
85

96
sys.path.append(os.path.split(os.path.realpath(__file__))[0])
107

src/superannotate/lib/app/analytics/common.py

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
import pandas as pd
55
import plotly.express as px
66
from lib.app.exceptions import AppException
7-
from lib.core import DEPRICATED_DOCUMENT_VIDEO_MESSAGE
87
from superannotate.logger import get_default_logger
98

109

@@ -44,14 +43,6 @@ def aggregate_image_annotations_as_df(
4443
:rtype: pandas DataFrame
4544
"""
4645

47-
json_paths = list(Path(str(project_root)).glob("*.json"))
48-
if (
49-
json_paths
50-
and "___pixel.json" not in json_paths[0].name
51-
and "___objects.json" not in json_paths[0].name
52-
):
53-
raise AppException(DEPRICATED_DOCUMENT_VIDEO_MESSAGE)
54-
5546
logger.info("Aggregating annotations from %s as pandas DataFrame", project_root)
5647

5748
annotation_data = {
@@ -101,12 +92,16 @@ def aggregate_image_annotations_as_df(
10192
classes_json = json.load(open(classes_path))
10293
class_name_to_color = {}
10394
class_group_name_to_values = {}
95+
freestyle_attributes = set()
10496
for annotation_class in classes_json:
10597
name = annotation_class["name"]
10698
color = annotation_class["color"]
10799
class_name_to_color[name] = color
108100
class_group_name_to_values[name] = {}
109101
for attribute_group in annotation_class["attribute_groups"]:
102+
group_type = attribute_group.get("group_type")
103+
if group_type and group_type in ["text", "numeric"]:
104+
freestyle_attributes.add(attribute_group["name"])
110105
class_group_name_to_values[name][attribute_group["name"]] = []
111106
for attribute in attribute_group["attributes"]:
112107
class_group_name_to_values[name][attribute_group["name"]].append(
@@ -175,10 +170,14 @@ def __get_user_metadata(annotation):
175170

176171
if not annotations_paths:
177172
logger.warning(f"Could not find annotations in {project_root}.")
178-
if len(list(Path(project_root).rglob("*___objects.json"))) > 0:
173+
174+
if "___objects.json" in annotations_paths[0].name:
179175
type_postfix = "___objects.json"
180-
else:
176+
elif "___pixel.json" in annotations_paths[0].name:
181177
type_postfix = "___pixel.json"
178+
else:
179+
type_postfix = ".json"
180+
182181
for annotation_path in annotations_paths:
183182
annotation_json = json.load(open(annotation_path))
184183
parts = annotation_path.name.split(type_postfix)
@@ -294,6 +293,7 @@ def __get_user_metadata(annotation):
294293
not in class_group_name_to_values[annotation_class_name][
295294
attribute_group
296295
]
296+
and attribute_group not in freestyle_attributes
297297
):
298298
logger.warning(
299299
"Annotation class group value %s not in classes json. Skipping.",
@@ -383,9 +383,9 @@ def instance_consensus(inst_1, inst_2):
383383
384384
:param inst_1: First instance for consensus score.
385385
:type inst_1: shapely object
386+
386387
:param inst_2: Second instance for consensus score.
387388
:type inst_2: shapely object
388-
389389
"""
390390
if inst_1.type == inst_2.type == "Polygon":
391391
intersect = inst_1.intersection(inst_2)
@@ -404,19 +404,19 @@ def image_consensus(df, image_name, annot_type):
404404
405405
:param df: Annotation data of all images
406406
:type df: pandas.DataFrame
407+
407408
:param image_name: The image name for which the consensus score will be computed
408409
:type image_name: str
410+
409411
:param annot_type: Type of annotation instances to consider. Available candidates are: ["bbox", "polygon", "point"]
410412
:type dataset_format: str
411-
412413
"""
413414

414415
try:
415416
from shapely.geometry import Point, Polygon, box
416417
except ImportError:
417418
raise ImportError(
418-
"To use superannotate.benchmark or superannotate.consensus functions please install "
419-
"shapely package in Anaconda enviornment with # conda install shapely"
419+
"To use superannotate.benchmark or superannotate.consensus functions please install shapely package."
420420
)
421421

422422
image_df = df[df["imageName"] == image_name]

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2176,8 +2176,10 @@ def attach_items_from_integrated_storage(
21762176
"""
21772177
project, folder = self.controller.get_project_folder_by_path(project)
21782178
_integration = None
2179+
if isinstance(integration, str):
2180+
integration = IntegrationEntity(name=integration)
21792181
for i in self.controller.integrations.list().data:
2180-
if integration == i.name:
2182+
if integration.name == i.name:
21812183
_integration = i
21822184
break
21832185
else:

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

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import copy
2+
import traceback
23
from collections import defaultdict
34
from concurrent.futures import as_completed
45
from concurrent.futures import ThreadPoolExecutor
@@ -942,12 +943,10 @@ def execute(
942943
for future in as_completed(futures):
943944
try:
944945
ids = future.result()
945-
except Exception as e:
946-
continue
947-
948-
self.item_ids.extend(ids)
946+
self.item_ids.extend(ids)
947+
except Exception:
948+
logger.debug(traceback.format_exc())
949949

950-
futures = []
951950
subsets = self._service_provider.subsets.list(self.project).data
952951
subset = None
953952
for s in subsets:

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

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,7 @@ def execute(self):
140140

141141

142142
class DownloadExportUseCase(BaseReportableUseCase):
143+
FORBIDDEN_CHARS = "*./\[]:;|,\"\'"
143144
def __init__(
144145
self,
145146
service_provider: BaseServiceProvider,
@@ -204,8 +205,10 @@ def download_to_local_storage(self, destination: str, extract_zip=False):
204205
raise AppException("Couldn't download export.")
205206
time.sleep(1)
206207
self.reporter.stop_spinner()
207-
filename = Path(export["path"]).name
208-
filepath = Path(destination) / filename
208+
filename = Path(export["path"]).stem
209+
for char in DownloadExportUseCase.FORBIDDEN_CHARS:
210+
filename=filename.replace(char, "_")
211+
filepath = Path(destination) / (filename+'.zip')
209212
with requests.get(export["download"], stream=True) as response:
210213
response.raise_for_status()
211214
with open(filepath, "wb") as f:

tests/integration/annotations/video/test_get_annotations_per_frame.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
import math
33
import os
44
from os.path import dirname
5-
from pathlib import Path
65

76
from src.superannotate import SAClient
87
from tests.integration.base import BaseTestCase
@@ -24,7 +23,7 @@ class TestGetAnnotations(BaseTestCase):
2423

2524
@property
2625
def csv_path(self):
27-
return os.path.join(dirname(dirname(dirname(__file__))), self.PATH_TO_URLS)
26+
return os.path.join(DATA_SET_PATH, self.PATH_TO_URLS)
2827

2928
@property
3029
def classes_path(self):

tests/integration/classes/test_create_annotation_class.py

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -146,21 +146,6 @@ def test_create_annotation_class(self):
146146
msg = str(e)
147147
self.assertEqual(msg, "Predefined tagging functionality is not supported for projects of type Video.")
148148

149-
def test_create_supported_annotation_class(self):
150-
msg = ""
151-
try:
152-
sa.create_annotation_class(
153-
self.PROJECT_NAME, "test_add", "#FF0000",
154-
attribute_groups=[
155-
{
156-
"group_type": "text",
157-
"name": "name",
158-
}
159-
]
160-
)
161-
except Exception as e:
162-
msg = str(e)
163-
self.assertEqual(msg, "This project type doesn't support the attribute group types 'text' and 'numeric'.")
164149

165150
def test_create_radio_annotation_class_attr_required(self):
166151
msg = ""
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
from src.superannotate import SAClient
2+
3+
from tests.integration.base import BaseTestCase
4+
5+
sa = SAClient()
6+
7+
8+
class TestSubSets(BaseTestCase):
9+
PROJECT_NAME = "Test-TestSubSets"
10+
PROJECT_DESCRIPTION = "Desc"
11+
PROJECT_TYPE = "Vector"
12+
SUBSET_NAME = "SUBSET"
13+
14+
def test_add_items_to_subset(self):
15+
item_names = [{"name": f"earth_mov_00{i}.jpg", "url": f"url_{i}"} for i in range(1, 6)]
16+
sa.attach_items(
17+
self.PROJECT_NAME,
18+
item_names # noqa
19+
)
20+
subset_data = []
21+
for i in item_names:
22+
subset_data.append(
23+
{
24+
"name": i['name'],
25+
"path": self.PROJECT_NAME
26+
}
27+
)
28+
sa.add_items_to_subset(self.PROJECT_NAME, self.SUBSET_NAME, subset_data)

0 commit comments

Comments
 (0)