Skip to content

Commit 5c8445d

Browse files
committed
Convertor fix
1 parent 24ddae3 commit 5c8445d

File tree

10 files changed

+97
-44
lines changed

10 files changed

+97
-44
lines changed

pytest.ini

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@
22
minversion = 3.7
33
log_cli=true
44
python_files = test_*.py
5-
;addopts = -n auto --dist=loadscope
5+
addopts = -n auto --dist=loadscope

requirements_dev.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
superannotate_schemas>=v1.0.43dev4
1+
superannotate_schemas>=v1.0.43dev5
22

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

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,22 @@ class DocumentRawData:
8585

8686

8787
class DataAggregator:
88+
MAPPERS = {
89+
"event": lambda annotation: None,
90+
"bbox": lambda annotation: annotation["points"],
91+
"polygon": lambda annotation: annotation["points"],
92+
"polyline": lambda annotation: annotation["points"],
93+
"cuboid": lambda annotation: annotation["points"],
94+
"point": lambda annotation: {"x": annotation["x"], "y": annotation["y"]},
95+
"annotation_type": lambda annotation: dict(
96+
cx=annotation["cx"],
97+
cy=annotation["cy"],
98+
rx=annotation["rx"],
99+
ry=annotation["ry"],
100+
angle=annotation["angle"],
101+
),
102+
}
103+
88104
def __init__(
89105
self,
90106
project_type: str,
@@ -186,11 +202,12 @@ def aggregate_video_annotations_as_df(self, annotation_paths: List[str]):
186202
# append instances
187203
instances = annotation_data.get("instances", [])
188204
for idx, instance in enumerate(instances):
205+
instance_type = instance["meta"].get("type", "event")
189206
instance_raw = copy.copy(raw_data)
190207
instance_raw.instanceId = int(idx)
191208
instance_raw.instanceStart = instance["meta"].get("start")
192209
instance_raw.instanceEnd = instance["meta"].get("end")
193-
instance_raw.type = instance["meta"].get("type")
210+
instance_raw.type = instance_type
194211
instance_raw.className = instance["meta"].get("className")
195212
instance_raw.createdAt = instance["meta"].get("createdAt")
196213
instance_raw.createdBy = (
@@ -217,7 +234,7 @@ def aggregate_video_annotations_as_df(self, annotation_paths: List[str]):
217234
for timestamp_id, timestamp in enumerate(timestamps):
218235
timestamp_raw = copy.copy(parameter_raw)
219236
timestamp_raw.timestampId = timestamp_id
220-
timestamp_raw.meta = timestamp.get("points")
237+
timestamp_raw.meta = self.MAPPERS[instance_type](timestamp)
221238
attributes = timestamp.get("attributes", [])
222239
for attribute_id, attribute in enumerate(attributes):
223240
attribute_raw = copy.copy(timestamp_raw)
@@ -467,8 +484,7 @@ def __append_annotation(annotation_dict):
467484
]
468485
):
469486
logger.warning(
470-
"Annotation class group value %s not in classes json. Skipping.",
471-
attribute_name,
487+
f"Annotation class group value {attribute_name} not in classes json. Skipping."
472488
)
473489
continue
474490
annotation_dict = {

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2144,6 +2144,8 @@ def upload_image_to_project(
21442144
raise AppException(response.errors)
21452145

21462146

2147+
@Trackable
2148+
@validate_arguments
21472149
def search_models(
21482150
name: Optional[NotEmptyStr] = None,
21492151
type_: Optional[NotEmptyStr] = None,

src/superannotate/lib/core/data_handlers.py

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ def get_annotation_class(self, name: str) -> AnnotationClass:
4747

4848
@lru_cache()
4949
def get_attribute_group(
50-
self, annotation_class: AnnotationClass, attr_group_name: str
50+
self, annotation_class: AnnotationClass, attr_group_name: str
5151
) -> AttributeGroup:
5252
for attr_group in annotation_class.attribute_groups:
5353
if attr_group.name == attr_group_name:
@@ -114,10 +114,10 @@ def handle(self, annotation: dict):
114114

115115
class MissingIDsHandler(BaseAnnotationDateHandler):
116116
def __init__(
117-
self,
118-
annotation_classes: List[AnnotationClass],
119-
templates: List[dict],
120-
reporter: Reporter,
117+
self,
118+
annotation_classes: List[AnnotationClass],
119+
templates: List[dict],
120+
reporter: Reporter,
121121
):
122122
super().__init__(annotation_classes)
123123
self.validate_existing_classes(annotation_classes)
@@ -187,7 +187,7 @@ def handle(self, annotation: dict):
187187
template["name"]: template["id"] for template in self._templates
188188
}
189189
for annotation_instance in (
190-
i for i in annotation["instances"] if i.get("type", None) == "template"
190+
i for i in annotation["instances"] if i.get("type", None) == "template"
191191
):
192192
annotation_instance["templateId"] = template_name_id_map.get(
193193
annotation_instance.get("templateName", ""), -1
@@ -244,10 +244,14 @@ def _point_handler(time_stamp):
244244
HANDLERS: Dict[str, Callable] = {
245245
AnnotationTypes.EVENT: lambda timestamp: {},
246246
AnnotationTypes.BBOX: lambda timestamp: {"points": timestamp["points"]},
247-
AnnotationTypes.POINT: lambda timestamp: {"x": timestamp["x"], "y": timestamp["y"]},
247+
AnnotationTypes.POINT: lambda timestamp: {
248+
"x": timestamp["x"],
249+
"y": timestamp["y"],
250+
},
248251
AnnotationTypes.POLYLINE: lambda timestamp: {"points": timestamp["points"]},
249252
AnnotationTypes.POLYGON: lambda timestamp: {
250-
"points": timestamp["points"], "exclude": timestamp.get("exclude", [])
253+
"points": timestamp["points"],
254+
"exclude": timestamp.get("exclude", []),
251255
},
252256
}
253257

@@ -315,7 +319,9 @@ def convert_timestamp(timestamp):
315319
editor_instance["timeline"][timestamp]["active"] = False
316320
handler: Callable = self.HANDLERS.get(meta["type"])
317321
if handler:
318-
editor_instance["timeline"][timestamp].update(handler(timestamp_data))
322+
editor_instance["timeline"][timestamp].update(
323+
handler(timestamp_data)
324+
)
319325
# if timestamp_data.get("points", None):
320326
# editor_instance["timeline"][timestamp][
321327
# "points"
@@ -357,10 +363,10 @@ def convert_timestamp(timestamp):
357363
(group_name, attr_name)
358364
)
359365
attributes_to_add = (
360-
existing_attributes_in_current_instance - active_attributes
366+
existing_attributes_in_current_instance - active_attributes
361367
)
362368
attributes_to_delete = (
363-
active_attributes - existing_attributes_in_current_instance
369+
active_attributes - existing_attributes_in_current_instance
364370
)
365371
if attributes_to_add or attributes_to_delete:
366372
editor_instance["timeline"][timestamp][

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,10 @@ def download_to_local_storage(self, destination: str, extract_zip=False):
238238
if "error" in export:
239239
raise AppException(export["error"])
240240
export_status = export["status"]
241-
if export_status in (ExportStatus.ERROR.value, ExportStatus.CANCELED.value):
241+
if export_status in (
242+
ExportStatus.ERROR.value,
243+
ExportStatus.CANCELED.value,
244+
):
242245
self.reporter.stop_spinner()
243246
raise AppException("Couldn't download export.")
244247
self.reporter.stop_spinner()

src/superannotate/lib/core/video_convertor.py

Lines changed: 47 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -56,14 +56,14 @@ def get_frame(self, frame_no: int):
5656
return self.annotations[frame_no]
5757

5858
def _interpolate(
59-
self,
60-
class_name: str,
61-
from_frame: int,
62-
to_frame: int,
63-
data: dict,
64-
instance_id: int,
65-
steps: dict = None,
66-
annotation_type: str = "bbox",
59+
self,
60+
class_name: str,
61+
from_frame: int,
62+
to_frame: int,
63+
data: dict,
64+
instance_id: int,
65+
steps: dict = None,
66+
annotation_type: str = "bbox",
6767
) -> dict:
6868
annotations = {}
6969
for idx, frame_idx in enumerate(range(from_frame + 1, to_frame), 1):
@@ -78,10 +78,12 @@ def _interpolate(
7878
elif annotation_type == AnnotationTypes.POINT:
7979
tmp_data = {
8080
"x": round(data["x"] + steps["x"] * idx, 2),
81-
"y": round(data["y"] + steps["y"] * idx, 2)
81+
"y": round(data["y"] + steps["y"] * idx, 2),
8282
}
8383
elif annotation_type in (AnnotationTypes.POLYGON, AnnotationTypes.POLYLINE):
84-
tmp_data["points"] = [point + steps[idx] * 2 for idx, point in enumerate(data["points"])]
84+
tmp_data["points"] = [
85+
point + steps[idx] * 2 for idx, point in enumerate(data["points"])
86+
]
8587
annotations[frame_idx] = Annotation(
8688
instanceId=instance_id,
8789
type=annotation_type,
@@ -107,7 +109,9 @@ def get_median(self, annotations: List[dict]) -> dict:
107109
if len(annotations) == 1:
108110
return annotations[0]
109111
first_annotations = annotations[:1][0]
110-
median = (first_annotations["timestamp"] // self.ratio) * self.ratio + self.ratio / 2
112+
median = (
113+
first_annotations["timestamp"] // self.ratio
114+
) * self.ratio + self.ratio / 2
111115
median_annotation = first_annotations
112116
distance = abs(median - first_annotations["timestamp"])
113117
for annotation in annotations[1:]:
@@ -131,29 +135,49 @@ def merge_first_frame(frames_mapping):
131135
return frames_mapping
132136

133137
def _interpolate_frames(
134-
self, from_frame, from_frame_no, to_frame, to_frame_no, annotation_type, class_name, instance_id
138+
self,
139+
from_frame,
140+
from_frame_no,
141+
to_frame,
142+
to_frame_no,
143+
annotation_type,
144+
class_name,
145+
instance_id,
135146
):
136147
steps = None
137148
frames_diff = to_frame_no - from_frame_no
138-
if annotation_type == AnnotationTypes.BBOX and from_frame.get("points") and to_frame.get("points"):
149+
if (
150+
annotation_type == AnnotationTypes.BBOX
151+
and from_frame.get("points")
152+
and to_frame.get("points")
153+
):
139154
steps = {}
140155
for point in "x1", "x2", "y1", "y2":
141156
steps[point] = round(
142-
(to_frame["points"][point] - from_frame["points"][point]) / frames_diff, 2
157+
(to_frame["points"][point] - from_frame["points"][point])
158+
/ frames_diff,
159+
2,
143160
)
144161
elif annotation_type == AnnotationTypes.POINT:
145162
steps = {
146163
"x": (to_frame["x"] - from_frame["x"]) / frames_diff,
147-
"y": (to_frame["y"] - from_frame["y"]) / frames_diff
164+
"y": (to_frame["y"] - from_frame["y"]) / frames_diff,
148165
}
149166
elif annotation_type in (AnnotationTypes.POLYGON, AnnotationTypes.POLYLINE):
150167
steps = [
151168
(to_point - from_point) / frames_diff
152-
for from_point, to_point in zip(from_frame["points"], to_frame["points"])
169+
for from_point, to_point in zip(
170+
from_frame["points"], to_frame["points"]
171+
)
153172
]
154173
return self._interpolate(
155-
class_name=class_name, from_frame=from_frame_no, to_frame=to_frame_no, data=from_frame,
156-
instance_id=instance_id, steps=steps, annotation_type=annotation_type
174+
class_name=class_name,
175+
from_frame=from_frame_no,
176+
to_frame=to_frame_no,
177+
data=from_frame,
178+
instance_id=instance_id,
179+
steps=steps,
180+
annotation_type=annotation_type,
157181
)
158182

159183
def _process(self):
@@ -185,13 +209,16 @@ def _process(self):
185209
to_frame_no=to_frame_no,
186210
class_name=class_name,
187211
annotation_type=annotation_type,
188-
instance_id=instance_id
212+
instance_id=instance_id,
189213
)
190214
)
191215

192216
start_median_frame = self.get_median(frames_mapping[from_frame_no])
193217
end_median_frame = self.get_median(frames_mapping[to_frame_no])
194-
for frame_no, frame in (from_frame_no, start_median_frame), (last_frame_no, end_median_frame):
218+
for frame_no, frame in (
219+
(from_frame_no, start_median_frame),
220+
(last_frame_no, end_median_frame),
221+
):
195222
interpolated_frames[frame_no] = Annotation(
196223
instanceId=instance_id,
197224
type=annotation_type,

src/superannotate/lib/infrastructure/controller.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1216,16 +1216,15 @@ def consensus(
12161216
if export_response.errors:
12171217
return export_response
12181218

1219-
download_export_usecase = self.download_export(
1219+
response = self.download_export(
12201220
project_name=project.name,
12211221
export_name=export_response.data["name"],
12221222
folder_path=export_path,
12231223
extract_zip_contents=True,
12241224
to_s3_bucket=False,
12251225
)
1226-
for _ in download_export_usecase.execute():
1227-
continue
1228-
1226+
if response.errors:
1227+
raise AppException(response.errors)
12291228
use_case = usecases.ConsensusUseCase(
12301229
project=project,
12311230
folder_names=folder_names,

src/superannotate/lib/infrastructure/services.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ def default_headers(self):
8686
"authtype": self.AUTH_TYPE,
8787
"Content-Type": "application/json",
8888
"User-Agent": f"Python-SDK-Version: {__version__}; Python: {platform.python_version()}; "
89-
f"OS: {platform.system()}; Team: {self.team_id}",
89+
f"OS: {platform.system()}; Team: {self.team_id}",
9090
}
9191

9292
@property

src/superannotate/version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = "4.3.4dev2"
1+
__version__ = "4.3.4dev3"

0 commit comments

Comments
 (0)