Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 12 additions & 16 deletions src/superannotate/lib/app/interface/sdk_interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,7 @@ def search_images(
"""

project_name, folder_name = extract_project_folder(project)
project = controller._get_project(project_name)

response = controller.search_images(
project_name=project_name,
Expand All @@ -292,7 +293,7 @@ def search_images(
raise AppException(response.errors)

if return_metadata:
return [ImageSerializer(image).serialize() for image in response.data]
return [ImageSerializer(image).serialize_by_project(project) for image in response.data]
return [image.name for image in response.data]


Expand Down Expand Up @@ -889,21 +890,12 @@ def get_image_metadata(
:rtype: dict
"""
project_name, folder_name = extract_project_folder(project)
project = controller._get_project(project_name)
response = controller.get_image_metadata(project_name, folder_name, image_name)

if response.errors:
raise AppException(response.errors)

res_data = response.data
res_data["annotation_status"] = constances.AnnotationStatus.get_name(
res_data["annotation_status"]
)
res_data["prediction_status"] = constances.SegmentationStatus.get_name(
res_data["prediction_status"]
)
res_data["segmentation_status"] = constances.SegmentationStatus.get_name(
res_data["segmentation_status"]
)
return res_data
return ImageSerializer(response.data).serialize_by_project(project)


@Trackable
Expand Down Expand Up @@ -1849,13 +1841,14 @@ def set_image_annotation_status(
:rtype: dict
"""
project_name, folder_name = extract_project_folder(project)
project_entity = controller._get_project(project_name)
response = controller.set_images_annotation_statuses(
project_name, folder_name, [image_name], annotation_status
)
if response.errors:
raise AppException(response.errors)
image = controller.get_image_metadata(project_name, folder_name, image_name).data
return ImageSerializer(image).serialize()
return ImageSerializer(image).serialize_by_project(project=project_entity)


@Trackable
Expand Down Expand Up @@ -2581,14 +2574,17 @@ def search_images_all_folders(
:rtype: list of dicts or strs
"""

project_entity = controller._get_project(project)
res = controller.list_images(
project_name=project,
name_prefix=image_name_prefix,
annotation_status=annotation_status,
)
if return_metadata:
return res.data
return [image["name"] for image in res.data]
return [
ImageSerializer(image).serialize_by_project(project=project_entity) for image in res.data
]
return [image.name for image in res.data]


@Trackable
Expand Down
1 change: 1 addition & 0 deletions src/superannotate/lib/app/mixp/decorators.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

controller = Controller.get_instance()

# TODO:
try:
if "api.annotate.online" in controller._backend_client.api_url:
TOKEN = "ca95ed96f80e8ec3be791e2d3097cf51"
Expand Down
42 changes: 42 additions & 0 deletions src/superannotate/lib/app/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import superannotate.lib.core as constance
from superannotate.lib.core.entities import BaseEntity
from superannotate.lib.core.entities import ImageEntity
from superannotate.lib.core.entities import ProjectEntity


class BaseSerializers(ABC):
Expand Down Expand Up @@ -57,6 +58,47 @@ def serialize(self):
)
return data


def serialize_by_project(self, project: ProjectEntity):
data = super().serialize()
data = {
"name": data.get("name"),
"path": data.get("path"),
"annotation_status": data.get("annotation_status"),
"prediction_status": data.get("prediction_status"),
"segmentation_status": data.get("segmentation_status"),
"approval_status": data.get("approval_status"),
"is_pinned": data.get("is_pinned"),
"annotator_name": data.get("annotator_name"),
"qa_name": data.get("qa_name"),
"entropy_value": data.get("entropy_value"),
"createdAt": data.get("createdAt"),
"updatedAt": data.get("updatedAt"),
}

data["annotation_status"] = constance.AnnotationStatus.get_name(
data["annotation_status"]
)

if project.upload_state == constance.UploadState.EXTERNAL.value:
data["prediction_status"] = None
data["segmentation_status"] = None
else:
if project.project_type == constance.ProjectType.VECTOR.value:
data["prediction_status"] = constance.SegmentationStatus.get_name(
data["prediction_status"]
)
data["segmentation_status"] = None
if project.project_type == constance.ProjectType.PIXEL.value:
data["prediction_status"] = constance.SegmentationStatus.get_name(
data["prediction_status"]
)
data["segmentation_status"] = constance.SegmentationStatus.get_name(
data["segmentation_status"]
)
data["path"] = None
return data

@staticmethod
def deserialize(data):
if isinstance(data, list):
Expand Down
30 changes: 22 additions & 8 deletions src/superannotate/lib/core/entities/project_entities.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from typing import Iterable
from typing import List

import lib.core as constances
from lib.core.enums import SegmentationStatus


Expand Down Expand Up @@ -261,6 +262,8 @@ def __init__(
segmentation_status: int = SegmentationStatus.NOT_STARTED.value,
prediction_status: int = SegmentationStatus.NOT_STARTED.value,
meta: ImageInfoEntity = ImageInfoEntity(),
created_at: str = None,
updated_at: str = None,
**_
):
super().__init__(uuid)
Expand All @@ -281,6 +284,8 @@ def __init__(
self.segmentation_status = segmentation_status
self.prediction_status = prediction_status
self.meta = meta
self.created_at = created_at
self.updated_at = updated_at

@staticmethod
def from_dict(**kwargs):
Expand All @@ -290,26 +295,35 @@ def from_dict(**kwargs):
if "annotation_status" in kwargs:
kwargs["annotation_status_code"] = kwargs["annotation_status"]
del kwargs["annotation_status"]
if "createdAt" in kwargs:
kwargs["created_at"] = kwargs["createdAt"]
del kwargs["createdAt"]
if "updatedAt" in kwargs:
kwargs["updated_at"] = kwargs["updatedAt"]
del kwargs["updatedAt"]
return ImageEntity(**kwargs)


def to_dict(self):
data = {
"id": self.uuid,
"team_id": self.team_id,
"project_id": self.project_id,
"folder_id": self.folder_id,
"name": self.name,
"path": self.path,
"project_id": self.project_id,
"annotation_status": self.annotation_status_code,
"folder_id": self.folder_id,
"qa_id": self.qa_id,
"qa_name": self.qa_name,
"entropy_value": self.entropy_value,
"prediction_status": self.prediction_status,
"segmentation_status": self.segmentation_status,
"approval_status": self.approval_status,
"is_pinned": self.is_pinned,
"annotator_id": self.annotator_id,
"annotator_name": self.annotator_name,
"is_pinned": self.is_pinned,
"segmentation_status": self.segmentation_status,
"prediction_status": self.prediction_status,
"qa_id": self.qa_id,
"qa_name": self.qa_name,
"entropy_value": self.entropy_value,
"createdAt": self.created_at,
"updatedAt": self.updated_at,
"meta": self.meta.to_dict(),
}
return {k: v for k, v in data.items() if v is not None}
Expand Down
7 changes: 4 additions & 3 deletions src/superannotate/lib/core/usecases/images.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,6 @@ def execute(self):
constances.AnnotationStatus.get_value(self._annotation_status),
EQ,
)

self._response.data = self._images.get_all(condition)
return self._response

Expand Down Expand Up @@ -161,9 +160,10 @@ def execute(self):
condition &= Condition("annotation_status", self.annotation_status, EQ)
if self._name_prefix:
condition &= Condition("name", self._name_prefix, EQ)
self._response.data = self._service_provider.list_images(
images_list = self._service_provider.list_images(
query_string=condition.build_query()
)
self._response.data = [ImageEntity.from_dict(**image) for image in images_list]
return self._response


Expand Down Expand Up @@ -676,7 +676,8 @@ def execute(self):
folder_id=self._folder.uuid,
)
if data:
self._response.data = data[0]
image_entity = ImageEntity.from_dict(**data[0])
self._response.data = image_entity
else:
self._response.errors = AppException("Image not found.")
return self._response
Expand Down
2 changes: 2 additions & 0 deletions src/superannotate/lib/infrastructure/repositories.py
Original file line number Diff line number Diff line change
Expand Up @@ -396,6 +396,8 @@ def dict2entity(data: dict):
annotator_id=data["annotator_id"],
annotator_name=data["annotator_name"],
is_pinned=data.get("is_pinned"),
created_at=data["createdAt"],
updated_at=data["updatedAt"],
)


Expand Down
14 changes: 7 additions & 7 deletions tests/integration/test_assign_images.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ def test_assign_images(self):
image_metadata = sa.get_image_metadata(
self._project["name"], self.EXAMPLE_IMAGE_1
)
self.assertEqual(image_metadata["qa_id"], email)
self.assertIsNotNone(image_metadata["qa_name"])

def test_assign_images_folder(self):

Expand All @@ -52,8 +52,8 @@ def test_assign_images_folder(self):
im1_metadata = sa.get_image_metadata(project_folder, self.EXAMPLE_IMAGE_1)
im2_metadata = sa.get_image_metadata(project_folder, self.EXAMPLE_IMAGE_2)

self.assertEqual(im1_metadata["qa_id"], email)
self.assertEqual(im2_metadata["qa_id"], email)
self.assertIsNotNone(im1_metadata["qa_name"])
self.assertIsNotNone(im2_metadata["qa_name"])

def test_un_assign_images(self):

Expand All @@ -70,8 +70,8 @@ def test_un_assign_images(self):
im1_metadata = sa.get_image_metadata(self.PROJECT_NAME, self.EXAMPLE_IMAGE_1)
im2_metadata = sa.get_image_metadata(self.PROJECT_NAME, self.EXAMPLE_IMAGE_2)

self.assertIsNone(im1_metadata["qa_id"])
self.assertIsNone(im2_metadata["qa_id"])
self.assertIsNone(im1_metadata["qa_name"])
self.assertIsNone(im2_metadata["qa_name"])

sa.create_folder(self.PROJECT_NAME, self.TEST_FOLDER_NAME)
project = self.PROJECT_NAME + "/" + self.TEST_FOLDER_NAME
Expand All @@ -89,8 +89,8 @@ def test_un_assign_images(self):

im2_metadata = sa.get_image_metadata(project, self.EXAMPLE_IMAGE_2)

self.assertIsNone(im1_metadata["qa_id"])
self.assertIsNone(im2_metadata["qa_id"])
self.assertIsNone(im1_metadata["qa_name"])
self.assertIsNone(im2_metadata["qa_name"])

def test_assign_folder(self):
sa.create_folder(self.PROJECT_NAME, self.TEST_FOLDER_NAME)
Expand Down
10 changes: 10 additions & 0 deletions tests/integration/test_attach_image_urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,16 @@ def test_attach_image_urls(self):
self.assertEqual(len(existing_images), 1)
images = sa.search_images(project=self.PROJECT_NAME, return_metadata=True)
self.assertTrue(all([image["name"] for image in images]))
truth = {'name': '',
'path': 'https://drive.google.com/uc?export=download&id=1geS2YtQiTYuiduEirKVYxBujHJaIWA3V',
'annotation_status': 'NotStarted', 'prediction_status': None, 'segmentation_status': None,
'approval_status': None, 'is_pinned': 0, 'annotator_name': None, 'qa_name': None, 'entropy_value': None,
'createdAt': '', 'updatedAt': ''}
image = images[0]
image['createdAt'] = ''
image['updatedAt'] = ''
image['name'] = ''
self.assertEqual(image, truth)

def test_double_attach_image_urls(self):
uploaded, could_not_upload, existing_images = sa.attach_image_urls_to_project(
Expand Down
13 changes: 13 additions & 0 deletions tests/integration/test_basic_images.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,12 @@ def test_basic_images(self):
sa.create_annotation_classes_from_classes_json(
self.PROJECT_NAME, self.classes_json_path
)
image = sa.get_image_metadata(self.PROJECT_NAME,image_name="example_image_1.jpg" )
image['createdAt'] = ''
image['updatedAt'] = ''
truth ={'name': 'example_image_1.jpg', 'path': None, 'annotation_status': 'InProgress', 'prediction_status':'NotStarted', 'segmentation_status': 'NotStarted', 'approval_status': None, 'is_pinned': 0, 'annotator_name': None, 'qa_name': None, 'entropy_value': None, 'createdAt': '', 'updatedAt': ''}

self.assertEqual(image,truth)

sa.upload_image_annotations(
project=self.PROJECT_NAME,
Expand Down Expand Up @@ -82,6 +88,13 @@ def test_basic_images(self):
self.assertEqual(len(images), 1)

image_name = images[0]

image = sa.get_image_metadata(self.PROJECT_NAME,image_name="example_image_1.jpg" )
image['createdAt'] = ''
image['updatedAt'] = ''
truth = {'name': 'example_image_1.jpg', 'path': None, 'annotation_status': 'InProgress', 'prediction_status':'NotStarted', 'segmentation_status': None, 'approval_status': None, 'is_pinned': 0, 'annotator_name': None, 'qa_name': None, 'entropy_value': None, 'createdAt': '', 'updatedAt': ''}
self.assertEqual(image, truth)

sa.download_image(self.PROJECT_NAME, image_name, temp_dir, True)
self.assertEqual(
sa.get_image_annotations(self.PROJECT_NAME, image_name)[
Expand Down