Skip to content

Commit 2750f6d

Browse files
committed
Minor changes
1 parent dfd634f commit 2750f6d

File tree

5 files changed

+115
-107
lines changed

5 files changed

+115
-107
lines changed

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

Lines changed: 109 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,11 @@
88
from typing import Tuple
99

1010
import boto3
11+
from superannotate_schemas.validators import AnnotationValidators
12+
1113
import lib.core as constances
12-
from lib.core.conditions import Condition
1314
from lib.core.conditions import CONDITION_EQ as EQ
15+
from lib.core.conditions import Condition
1416
from lib.core.data_handlers import ChainedAnnotationHandlers
1517
from lib.core.data_handlers import DocumentTagHandler
1618
from lib.core.data_handlers import LastActionHandler
@@ -32,8 +34,6 @@
3234
from lib.core.usecases.images import ValidateAnnotationUseCase
3335
from lib.core.video_convertor import VideoFrameGenerator
3436
from superannotate.logger import get_default_logger
35-
from superannotate_schemas.validators import AnnotationValidators
36-
3737

3838
logger = get_default_logger()
3939

@@ -45,20 +45,20 @@ class UploadAnnotationsUseCase(BaseReportableUseCae):
4545
ImageInfo = namedtuple("ImageInfo", ["path", "name", "id"])
4646

4747
def __init__(
48-
self,
49-
reporter: Reporter,
50-
project: ProjectEntity,
51-
folder: FolderEntity,
52-
team: TeamEntity,
53-
images: BaseManageableRepository,
54-
annotation_classes: List[AnnotationClassEntity],
55-
annotation_paths: List[str],
56-
backend_service_provider: SuerannotateServiceProvider,
57-
templates: List[dict],
58-
validators: AnnotationValidators,
59-
pre_annotation: bool = False,
60-
client_s3_bucket=None,
61-
folder_path: str = None,
48+
self,
49+
reporter: Reporter,
50+
project: ProjectEntity,
51+
folder: FolderEntity,
52+
team: TeamEntity,
53+
images: BaseManageableRepository,
54+
annotation_classes: List[AnnotationClassEntity],
55+
annotation_paths: List[str],
56+
backend_service_provider: SuerannotateServiceProvider,
57+
templates: List[dict],
58+
validators: AnnotationValidators,
59+
pre_annotation: bool = False,
60+
client_s3_bucket=None,
61+
folder_path: str = None,
6262
):
6363
super().__init__(reporter)
6464
self._project = project
@@ -82,8 +82,8 @@ def __init__(
8282
@property
8383
def annotation_postfix(self):
8484
if self._project.project_type in (
85-
constances.ProjectType.VIDEO.value,
86-
constances.ProjectType.DOCUMENT.value,
85+
constances.ProjectType.VIDEO.value,
86+
constances.ProjectType.DOCUMENT.value,
8787
):
8888
return constances.ATTACHED_VIDEO_ANNOTATION_POSTFIX
8989
elif self._project.project_type == constances.ProjectType.VECTOR.value:
@@ -95,8 +95,8 @@ def annotation_postfix(self):
9595
def extract_name(value: str):
9696
return os.path.basename(
9797
value.replace(constances.PIXEL_ANNOTATION_POSTFIX, "")
98-
.replace(constances.VECTOR_ANNOTATION_POSTFIX, "")
99-
.replace(constances.ATTACHED_VIDEO_ANNOTATION_POSTFIX, ""),
98+
.replace(constances.VECTOR_ANNOTATION_POSTFIX, "")
99+
.replace(constances.ATTACHED_VIDEO_ANNOTATION_POSTFIX, ""),
100100
)
101101

102102
@property
@@ -120,8 +120,8 @@ def annotations_to_upload(self):
120120
folder_id=self._folder.uuid,
121121
images=[image.name for image in images_detail],
122122
)
123-
.execute()
124-
.data
123+
.execute()
124+
.data
125125
)
126126
for image_data in images_data:
127127
for idx, detail in enumerate(images_detail):
@@ -151,7 +151,7 @@ def missing_annotations(self):
151151
return self._missing_annotations
152152

153153
def get_annotation_upload_data(
154-
self, image_ids: List[int]
154+
self, image_ids: List[int]
155155
) -> UploadAnnotationAuthData:
156156
if self._pre_annotation:
157157
function = self._backend_service.get_pre_annotation_upload_data
@@ -167,12 +167,12 @@ def get_annotation_upload_data(
167167
return response.data
168168

169169
def _upload_annotation(
170-
self,
171-
image_id: int,
172-
image_name: str,
173-
upload_data: UploadAnnotationAuthData,
174-
path: str,
175-
bucket,
170+
self,
171+
image_id: int,
172+
image_name: str,
173+
upload_data: UploadAnnotationAuthData,
174+
path: str,
175+
bucket,
176176
):
177177
try:
178178
self.reporter.disable_warnings()
@@ -256,8 +256,8 @@ def execute(self):
256256
)
257257
for step in iterations_range:
258258
annotations_to_upload = self.annotations_to_upload[
259-
step : step + self.AUTH_DATA_CHUNK_SIZE # noqa: E203
260-
]
259+
step: step + self.AUTH_DATA_CHUNK_SIZE # noqa: E203
260+
]
261261
upload_data = self.get_annotation_upload_data(
262262
[int(image.id) for image in annotations_to_upload]
263263
)
@@ -270,11 +270,11 @@ def execute(self):
270270
}
271271
# dummy progress
272272
for _ in range(
273-
len(annotations_to_upload) - len(upload_data.images)
273+
len(annotations_to_upload) - len(upload_data.images)
274274
):
275275
self.reporter.update_progress()
276276
with concurrent.futures.ThreadPoolExecutor(
277-
max_workers=self.MAX_WORKERS
277+
max_workers=self.MAX_WORKERS
278278
) as executor:
279279
results = [
280280
executor.submit(
@@ -306,25 +306,25 @@ def execute(self):
306306

307307
class UploadAnnotationUseCase(BaseReportableUseCae):
308308
def __init__(
309-
self,
310-
project: ProjectEntity,
311-
folder: FolderEntity,
312-
image: ImageEntity,
313-
images: BaseManageableRepository,
314-
team: TeamEntity,
315-
annotation_classes: List[AnnotationClassEntity],
316-
backend_service_provider: SuerannotateServiceProvider,
317-
reporter: Reporter,
318-
templates: List[dict],
319-
validators: AnnotationValidators,
320-
annotation_upload_data: UploadAnnotationAuthData = None,
321-
annotations: dict = None,
322-
s3_bucket=None,
323-
client_s3_bucket=None,
324-
mask=None,
325-
verbose: bool = True,
326-
annotation_path: str = None,
327-
pass_validation: bool = False,
309+
self,
310+
project: ProjectEntity,
311+
folder: FolderEntity,
312+
image: ImageEntity,
313+
images: BaseManageableRepository,
314+
team: TeamEntity,
315+
annotation_classes: List[AnnotationClassEntity],
316+
backend_service_provider: SuerannotateServiceProvider,
317+
reporter: Reporter,
318+
templates: List[dict],
319+
validators: AnnotationValidators,
320+
annotation_upload_data: UploadAnnotationAuthData = None,
321+
annotations: dict = None,
322+
s3_bucket=None,
323+
client_s3_bucket=None,
324+
mask=None,
325+
verbose: bool = True,
326+
annotation_path: str = None,
327+
pass_validation: bool = False,
328328
):
329329
super().__init__(reporter)
330330
self._project = project
@@ -413,18 +413,18 @@ def set_annotation_json(self):
413413

414414
@staticmethod
415415
def prepare_annotations(
416-
project_type: int,
417-
annotations: dict,
418-
annotation_classes: List[AnnotationClassEntity],
419-
templates: List[dict],
420-
reporter: Reporter,
421-
team: TeamEntity,
416+
project_type: int,
417+
annotations: dict,
418+
annotation_classes: List[AnnotationClassEntity],
419+
templates: List[dict],
420+
reporter: Reporter,
421+
team: TeamEntity,
422422
) -> dict:
423423
handlers_chain = ChainedAnnotationHandlers()
424424
if project_type in (
425-
constances.ProjectType.VECTOR.value,
426-
constances.ProjectType.PIXEL.value,
427-
constances.ProjectType.DOCUMENT.value,
425+
constances.ProjectType.VECTOR.value,
426+
constances.ProjectType.PIXEL.value,
427+
constances.ProjectType.DOCUMENT.value,
428428
):
429429
handlers_chain.attach(
430430
MissingIDsHandler(annotation_classes, templates, reporter)
@@ -436,7 +436,7 @@ def prepare_annotations(
436436
handlers_chain.attach(LastActionHandler(team.creator_id))
437437
return handlers_chain.handle(annotations)
438438

439-
def clean_json(self, json_data: dict,) -> Tuple[bool, dict]:
439+
def clean_json(self, json_data: dict, ) -> Tuple[bool, dict]:
440440
use_case = ValidateAnnotationUseCase(
441441
constances.ProjectType.get_name(self._project.project_type),
442442
annotation=json_data,
@@ -466,8 +466,8 @@ def execute(self):
466466
Body=json.dumps(annotation_json),
467467
)
468468
if (
469-
self._project.project_type == constances.ProjectType.PIXEL.value
470-
and self._mask
469+
self._project.project_type == constances.ProjectType.PIXEL.value
470+
and self._mask
471471
):
472472
bucket.put_object(
473473
Key=self.annotation_upload_data.images[self._image.uuid][
@@ -540,7 +540,7 @@ def _prettify_annotations(self, annotations: List[dict]):
540540
try:
541541
data = []
542542
for annotation in annotations:
543-
data.append((self._item_names.index(annotation["metadata"]["name"]), annotation))
543+
data.append((self._item_names.index(annotation["metadata"]["name"]), annotation))
544544
return [i[1] for i in sorted(data, key=lambda x: x[0])]
545545
except KeyError:
546546
raise AppException("Broken data.")
@@ -598,48 +598,48 @@ def validate_project_type(self):
598598
)
599599

600600
def execute(self):
601-
self.reporter.disable_info()
602-
response = GetAnnotations(
603-
reporter=self.reporter,
604-
project=self._project,
605-
folder=self._folder,
606-
images=self._images,
607-
item_names=[self._video_name],
608-
backend_service_provider=self._client,
609-
show_process=False
610-
).execute()
611-
self.reporter.enable_info()
612-
if response.data:
613-
generator = VideoFrameGenerator(response.data[0], fps=self._fps)
614-
615-
self.reporter.log_info(f"Getting annotations for {generator.frames_count} frames from {self._video_name}.")
616-
if response.errors:
617-
self._response.errors = response.errors
618-
return self._response
619-
if not response.data:
620-
self._response.errors = AppException(f"Video {self._video_name} not found.")
621-
annotations = response.data
622-
if annotations:
623-
self._response.data = list(generator)
601+
if self.is_valid():
602+
self.reporter.disable_info()
603+
response = GetAnnotations(
604+
reporter=self.reporter,
605+
project=self._project,
606+
folder=self._folder,
607+
images=self._images,
608+
item_names=[self._video_name],
609+
backend_service_provider=self._client,
610+
show_process=False
611+
).execute()
612+
self.reporter.enable_info()
613+
if response.data:
614+
generator = VideoFrameGenerator(response.data[0], fps=self._fps)
615+
616+
self.reporter.log_info(f"Getting annotations for {generator.frames_count} frames from {self._video_name}.")
617+
if response.errors:
618+
self._response.errors = response.errors
619+
return self._response
620+
if not response.data:
621+
self._response.errors = AppException(f"Video {self._video_name} not found.")
622+
annotations = response.data
623+
if annotations:
624+
self._response.data = list(generator)
625+
else:
626+
self._response.data = []
624627
else:
625-
self._response.data = []
626-
else:
627-
self._response.errors = "Couldn't get annotations."
628+
self._response.errors = "Couldn't get annotations."
628629
return self._response
629630

630631

631632
class UploadPriorityScoresUseCase(BaseReportableUseCae):
632-
633633
CHUNK_SIZE = 100
634634

635635
def __init__(
636-
self,
637-
reporter,
638-
project: ProjectEntity,
639-
folder: FolderEntity,
640-
scores: List[PriorityScore],
641-
project_folder_name: str,
642-
backend_service_provider: SuerannotateServiceProvider
636+
self,
637+
reporter,
638+
project: ProjectEntity,
639+
folder: FolderEntity,
640+
scores: List[PriorityScore],
641+
project_folder_name: str,
642+
backend_service_provider: SuerannotateServiceProvider
643643
):
644644
super().__init__(reporter)
645645
self._project = project
@@ -663,7 +663,12 @@ def get_clean_priority(priority):
663663

664664
@property
665665
def folder_path(self):
666-
return f"{self._project.name}{f'/{self._folder.name}'if self._folder.name != 'root' else ''}"
666+
return f"{self._project.name}{f'/{self._folder.name}' if self._folder.name != 'root' else ''}"
667+
668+
@property
669+
def uploading_info(self):
670+
data_len: int = len(self._scores)
671+
return f"Uploading priority scores for {data_len} item{'(s)' if data_len < 1 else ''} to {self.folder_path}."
667672

668673
def execute(self):
669674
if self.is_valid():
@@ -676,12 +681,12 @@ def execute(self):
676681
})
677682
initial_scores.append(i.name)
678683
uploaded_score_names = []
679-
self.reporter.log_info(f"Uploading priority scores for {len(priorities)} item(s) from {self.folder_path}.")
684+
self.reporter.log_info(self.uploading_info)
680685
iterations = range(0, len(priorities), self.CHUNK_SIZE)
681686
self.reporter.start_progress(iterations, "Uploading priority scores")
682687
if iterations:
683688
for i in iterations:
684-
priorities_to_upload = priorities[i : i + self.CHUNK_SIZE] # noqa: E203
689+
priorities_to_upload = priorities[i: i + self.CHUNK_SIZE] # noqa: E203
685690
res = self._client.upload_priority_scores(
686691
team_id=self._project.team_id,
687692
project_id=self._project.uuid,
@@ -690,6 +695,7 @@ def execute(self):
690695
)
691696
self.reporter.update_progress(len(priorities_to_upload))
692697
uploaded_score_names.extend(list(map(lambda x: x["name"], res.get("data", []))))
698+
self.reporter.finish_progress()
693699
skipped_score_names = list(set(initial_scores) - set(uploaded_score_names))
694700
self._response.data = (uploaded_score_names, skipped_score_names)
695701
else:

src/superannotate/lib/core/video_convertor.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,8 @@ def get_median(self, annotations: List[dict]) -> dict:
116116
def merge_first_frame(frames_mapping):
117117
try:
118118
if 0 in frames_mapping:
119-
frames_mapping[1].extendleft(frames_mapping[0])
119+
frames_mapping[0].extend(frames_mapping[1])
120+
frames_mapping[1] = frames_mapping[0]
120121
del frames_mapping[0]
121122
finally:
122123
return frames_mapping

src/superannotate/lib/infrastructure/controller.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ def retrieve_configs(self, path: Path, raise_exception=True):
9898
)
9999
self._token = token
100100
self._backend_url = backend_url or self._backend_url
101-
self._ssl_verify = ssl_verify or self._ssl_verify
101+
self._ssl_verify = ssl_verify if ssl_verify is not None else True
102102

103103
@staticmethod
104104
def _validate_token(token: str):

src/superannotate/version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = "4.3.0.dev2"
1+
__version__ = "4.3.0.dev5"

tests/integration/test_upload_priority_scores.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,11 @@ def folder_path(self):
1616
return os.path.join(Path(__file__).parent.parent, self.TEST_FOLDER_PATH)
1717

1818
def test_upload_priority_scores(self):
19+
1920
sa.upload_images_from_folder_to_project(
2021
self.PROJECT_NAME, self.folder_path, annotation_status="InProgress"
2122
)
22-
uploaded, skipped = sa.upload_priority_2scores(self.PROJECT_NAME, scores=[{
23+
uploaded, skipped = sa.upload_priority_scores(self.PROJECT_NAME, scores=[{
2324
"name": "example_image_1.jpg",
2425
"priority": 1
2526
}])

0 commit comments

Comments
 (0)