Skip to content

Commit 10440b0

Browse files
committed
merge
2 parents fd12975 + 8a913c1 commit 10440b0

File tree

6 files changed

+97
-60
lines changed

6 files changed

+97
-60
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
from lib.infrastructure.repositories import ConfigRepository
2525
from tqdm import tqdm
2626

27-
logger = logging.getLogger()
27+
logger = logging.getLogger("superannotate-python-sdk")
2828

2929

3030
class CLIFacade(BaseInterfaceFacade):

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

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -47,11 +47,20 @@
4747

4848

4949
logging.basicConfig(level=logging.INFO)
50-
logger = logging.getLogger()
50+
formatter = logging.Formatter(fmt='SA-PYTHON-SDK - %(levelname)s - %(message)s')
51+
52+
handler = logging.StreamHandler()
53+
handler.setFormatter(formatter)
54+
55+
logger = logging.getLogger("superannotate-python-sdk")
56+
logger.setLevel(logging.INFO)
57+
logger.addHandler(handler)
5158

5259
controller = Controller(logger)
5360

5461

62+
63+
5564
@validate_input
5665
def init(path_to_config_json: str):
5766
"""
@@ -540,10 +549,12 @@ def copy_image(
540549

541550
img_bytes = get_image_bytes(project=source_project, image_name=image_name)
542551

543-
image_entity = controller.upload_image_to_s3(
552+
s3_response = controller.upload_image_to_s3(
544553
project_name=destination_project, image_path=image_name, image_bytes=img_bytes
545-
).data
546-
554+
)
555+
if s3_response.errors:
556+
raise AppException(s3_response.errors)
557+
image_entity = s3_response.data
547558
del img_bytes
548559

549560
if copy_annotation_status:
@@ -756,7 +767,7 @@ def copy_images(
756767
message_postfix = "{from_path} to {to_path}."
757768
message_prefix = "Copied images from "
758769
if done_count > 1 or done_count == 0:
759-
message_prefix = f"Copied {done_count}/{len(image_names)} images from"
770+
message_prefix = f"Copied {done_count}/{len(image_names)} images from "
760771
elif done_count == 1:
761772
message_prefix = "Copied an image from "
762773
logger.info(

src/superannotate/lib/core/plugin.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
import cv2
77
import ffmpeg
8+
from lib.core.exceptions import ImageProcessingException
89
from PIL import Image
910
from PIL import ImageDraw
1011
from PIL import ImageOps
@@ -13,6 +14,7 @@
1314
class ImagePlugin:
1415
def __init__(self, image_bytes: io.BytesIO, max_resolution: int = 4096):
1516
self._image_bytes = image_bytes
17+
self._image_bytes.seek(0)
1618
self._max_resolution = max_resolution
1719
self._image = Image.open(self._image_bytes).convert("RGBA")
1820
self._draw = None
@@ -61,7 +63,7 @@ def _get_image(self):
6163
resolution = width * height
6264

6365
if resolution > self._max_resolution:
64-
raise Exception(
66+
raise ImageProcessingException(
6567
f"Image resolution {resolution} too large. Max supported for resolution is {self._max_resolution}"
6668
)
6769
return im

src/superannotate/lib/core/response.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
from typing import Union
22

3+
from lib.core.exceptions import AppException
4+
35

46
class Response:
57
def __init__(self, status: str = None, data: Union[dict, list] = None):
@@ -25,7 +27,13 @@ def status(self, value):
2527

2628
@property
2729
def errors(self):
28-
return "\n".join([error.message for error in self._errors])
30+
message = ""
31+
for error in self._errors:
32+
if isinstance(error, AppException):
33+
message += error.message + "\n"
34+
else:
35+
message += str(error)
36+
return message
2937

3038
@errors.setter
3139
def errors(self, error: list):

src/superannotate/lib/core/usecases.py

Lines changed: 67 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -48,12 +48,14 @@
4848
from lib.core.enums import ProjectType
4949
from lib.core.exceptions import AppException
5050
from lib.core.exceptions import AppValidationException
51+
from lib.core.exceptions import ImageProcessingException
5152
from lib.core.plugin import ImagePlugin
5253
from lib.core.plugin import VideoPlugin
5354
from lib.core.repositories import BaseManageableRepository
5455
from lib.core.repositories import BaseReadOnlyRepository
5556
from lib.core.response import Response
5657
from lib.core.serviceproviders import SuerannotateServiceProvider
58+
from PIL import UnidentifiedImageError
5759

5860
logger = logging.getLogger()
5961

@@ -498,64 +500,77 @@ def max_resolution(self) -> int:
498500

499501
def execute(self):
500502
image_name = Path(self._image_path).name
501-
image_processor = ImagePlugin(self._image, self.max_resolution)
502-
origin_width, origin_height = image_processor.get_size()
503-
thumb_image, _, _ = image_processor.generate_thumb()
504-
huge_image, huge_width, huge_height = image_processor.generate_huge()
505-
quality = 60
506-
if not self._image_quality_in_editor:
507-
for setting in self._project_settings.get_all():
508-
if setting.attribute == "ImageQuality":
509-
quality = setting.value
510-
else:
511-
quality = ImageQuality.get_value(self._image_quality_in_editor)
512-
if Path(image_name).suffix[1:].upper() in ("JPEG", "JPG"):
513-
if quality == 100:
514-
self._image.seek(0)
515-
low_resolution_image = self._image
503+
try:
504+
image_processor = ImagePlugin(self._image, self.max_resolution)
505+
origin_width, origin_height = image_processor.get_size()
506+
thumb_image, _, _ = image_processor.generate_thumb()
507+
huge_image, huge_width, huge_height = image_processor.generate_huge()
508+
quality = 60
509+
if not self._image_quality_in_editor:
510+
for setting in self._project_settings.get_all():
511+
if setting.attribute == "ImageQuality":
512+
quality = setting.value
516513
else:
517-
low_resolution_image, _, _ = image_processor.generate_low_resolution(
518-
quality=quality
519-
)
520-
else:
521-
if quality == 100:
522-
low_resolution_image, _, _ = image_processor.generate_low_resolution(
523-
quality=quality, subsampling=0
524-
)
514+
quality = ImageQuality.get_value(self._image_quality_in_editor)
515+
if Path(image_name).suffix[1:].upper() in ("JPEG", "JPG"):
516+
if quality == 100:
517+
self._image.seek(0)
518+
low_resolution_image = self._image
519+
else:
520+
(
521+
low_resolution_image,
522+
_,
523+
_,
524+
) = image_processor.generate_low_resolution(quality=quality)
525525
else:
526-
low_resolution_image, _, _ = image_processor.generate_low_resolution(
527-
quality=quality, subsampling=-1
528-
)
529-
image_key = (
530-
self._upload_path + str(uuid.uuid4()) + Path(self._image_path).suffix
531-
)
526+
if quality == 100:
527+
(
528+
low_resolution_image,
529+
_,
530+
_,
531+
) = image_processor.generate_low_resolution(
532+
quality=quality, subsampling=0
533+
)
534+
else:
535+
(
536+
low_resolution_image,
537+
_,
538+
_,
539+
) = image_processor.generate_low_resolution(
540+
quality=quality, subsampling=-1
541+
)
542+
image_key = (
543+
self._upload_path + str(uuid.uuid4()) + Path(self._image_path).suffix
544+
)
532545

533-
file_entity = S3FileEntity(uuid=image_key, data=self._image)
546+
file_entity = S3FileEntity(uuid=image_key, data=self._image)
534547

535-
thumb_image_name = image_key + "___thumb.jpg"
536-
thumb_image_entity = S3FileEntity(uuid=thumb_image_name, data=thumb_image)
537-
self._s3_repo.insert(thumb_image_entity)
548+
thumb_image_name = image_key + "___thumb.jpg"
549+
thumb_image_entity = S3FileEntity(uuid=thumb_image_name, data=thumb_image)
550+
self._s3_repo.insert(thumb_image_entity)
538551

539-
low_resolution_image_name = image_key + "___lores.jpg"
540-
low_resolution_file_entity = S3FileEntity(
541-
uuid=low_resolution_image_name, data=low_resolution_image
542-
)
543-
self._s3_repo.insert(low_resolution_file_entity)
552+
low_resolution_image_name = image_key + "___lores.jpg"
553+
low_resolution_file_entity = S3FileEntity(
554+
uuid=low_resolution_image_name, data=low_resolution_image
555+
)
556+
self._s3_repo.insert(low_resolution_file_entity)
544557

545-
huge_image_name = image_key + "___huge.jpg"
546-
huge_file_entity = S3FileEntity(
547-
uuid=huge_image_name,
548-
data=huge_image,
549-
metadata={"height": huge_width, "weight": huge_height},
550-
)
551-
self._s3_repo.insert(huge_file_entity)
552-
file_entity.data.seek(0)
553-
self._s3_repo.insert(file_entity)
554-
self._response.data = ImageEntity(
555-
name=image_name,
556-
path=image_key,
557-
meta=ImageInfoEntity(width=origin_width, height=origin_height),
558-
)
558+
huge_image_name = image_key + "___huge.jpg"
559+
huge_file_entity = S3FileEntity(
560+
uuid=huge_image_name,
561+
data=huge_image,
562+
metadata={"height": huge_width, "weight": huge_height},
563+
)
564+
self._s3_repo.insert(huge_file_entity)
565+
file_entity.data.seek(0)
566+
self._s3_repo.insert(file_entity)
567+
self._response.data = ImageEntity(
568+
name=image_name,
569+
path=image_key,
570+
meta=ImageInfoEntity(width=origin_width, height=origin_height),
571+
)
572+
except (ImageProcessingException, UnidentifiedImageError) as e:
573+
self._response.errors = e
559574
return self._response
560575

561576

src/superannotate/lib/infrastructure/repositories.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -372,6 +372,7 @@ def dict2entity(data: dict):
372372
folder_id=data["folder_id"],
373373
annotator_id=data["annotator_id"],
374374
annotator_name=data["annotator_name"],
375+
is_pinned=data.get("is_pinned"),
375376
)
376377

377378

0 commit comments

Comments
 (0)