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
2 changes: 1 addition & 1 deletion src/superannotate/lib/app/interface/sdk_interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ def create_project_from_metadata(project_metadata: Project):
contributors=project_metadata.get("contributors", []),
settings=project_metadata.get("settings", []),
annotation_classes=project_metadata.get("classes", []),
workflows=project_metadata.get("workflow", []),
workflows=project_metadata.get("workflows", []),
)
if response.errors:
raise AppException(response.errors)
Expand Down
6 changes: 6 additions & 0 deletions src/superannotate/lib/core/entities/project_entities.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from typing import List

from lib.core.enums import ClassTypeEnum
from lib.core.enums import ImageQuality
from lib.core.enums import SegmentationStatus
from superannotate_schemas.schemas.classes import AnnotationClass

Expand Down Expand Up @@ -176,6 +177,11 @@ def to_dict(self):
"value": self.value,
}

def serialize(self):
if self.attribute == "ImageQuality":
self.value = ImageQuality.get_value(self.value)
return self.to_dict()


class WorkflowEntity(BaseEntity):
def __init__(
Expand Down
37 changes: 24 additions & 13 deletions src/superannotate/lib/core/usecases/projects.py
Original file line number Diff line number Diff line change
Expand Up @@ -240,26 +240,37 @@ def execute(self):
)
for annotation_class in self._annotation_classes:
annotation_classes_mapping[
annotation_class.uuid
annotation_class.id
] = annotation_repo.insert(annotation_class)
self._response.data.annotation_classes = self._annotation_classes
if self._workflows:
workflow_repo = self._workflows_repo(self._backend_service, entity)
for workflow in self._workflows:
workflow.project_id = entity.uuid
workflow.class_id = annotation_classes_mapping.get(
workflow.class_id
)
workflow_repo.insert(workflow)
set_workflow_use_case = SetWorkflowUseCase(
service=self._backend_service,
annotation_classes_repo=self._annotation_classes_repo(
self._backend_service, entity
),
workflow_repo=self._workflows_repo(self._backend_service, entity),
steps=self._workflows,
project=entity,
)
set_workflow_response = set_workflow_use_case.execute()
if set_workflow_response.errors:
self._response.errors = set_workflow_response.errors
data["workflows"] = self._workflows

if self._contributors:
for contributor in self._contributors:
self._backend_service.share_project(
entity.uuid,
entity.team_id,
contributor["user_id"],
constances.UserRole.get_value(contributor["user_role"]),
self._backend_service.share_project_bulk(
team_id=entity.team_id,
project_id=entity.uuid,
users=[
{
"user_id": contributor["user_id"],
"user_role": constances.UserRole.get_value(
contributor["user_role"]
),
}
],
)
data["contributors"] = self._contributors

Expand Down
6 changes: 2 additions & 4 deletions src/superannotate/lib/infrastructure/controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -343,11 +343,9 @@ def create_project(
settings=[
ProjectSettingsRepository.dict2entity(setting) for setting in settings
],
workflows=[
WorkflowRepository.dict2entity(workflow) for workflow in workflows
],
workflows=workflows,
annotation_classes=[
AnnotationClassRepository.dict2entity(annotation_class)
AnnotationClassEntity(**annotation_class)
for annotation_class in annotation_classes
],
contributors=contributors,
Expand Down
2 changes: 1 addition & 1 deletion src/superannotate/lib/infrastructure/repositories.py
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ def delete(self, uuid: int):

def update(self, entity: ProjectSettingEntity):
res = self._service.set_project_settings(
self._project.uuid, self._project.team_id, [entity.to_dict()]
self._project.uuid, self._project.team_id, [entity.serialize()]
)
return entity

Expand Down
91 changes: 91 additions & 0 deletions tests/integration/projects/test_basic_project.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,96 @@
from tests.integration.base import BaseTestCase



class TestProjectCreateMetadata(BaseTestCase):
PROJECT_NAME = "sample_basic_project"
PROJECT_TYPE = "Vector"
OTHER_PROJECT_NAME = "other_project"
PROJECT_DESCRIPTION = "DESCRIPTION"
IMAGE_QUALITY_ORIGINAL = "original"

def setUp(self, *args, **kwargs):
super(TestProjectCreateMetadata, self).setUp()
try:
sa.delete_project(self.OTHER_PROJECT_NAME)
except:
pass

def tearDown(self) -> None:
super(TestProjectCreateMetadata, self).tearDown()
try:
sa.delete_project(self.OTHER_PROJECT_NAME)
except:
pass

def test_create_project_from_metadata(self):
sa.create_annotation_class(
self.PROJECT_NAME,
"rrr",
"#FFAAFF",
[
{
"name": "tall",
"is_multiselect": 0,
"attributes": [{"name": "yes"}, {"name": "no"}],
},
{
"name": "age",
"is_multiselect": 0,
"attributes": [{"name": "young"}, {"name": "old"}],
},
],
)
sa.set_project_workflow(
self.PROJECT_NAME,
[
{
"step": 1,
"className": "rrr",
"tool": 3,
"attribute": [
{
"attribute": {
"name": "young",
"attribute_group": {"name": "age"},
}
},
{
"attribute": {
"name": "yes",
"attribute_group": {"name": "tall"},
}
},
],
}
],
)

team_users = sa.search_team_contributors()
sa.share_project(self.PROJECT_NAME, team_users[0], "QA")

sa.set_project_default_image_quality_in_editor(self.PROJECT_NAME, self.IMAGE_QUALITY_ORIGINAL)
meta = sa.get_project_metadata(self.PROJECT_NAME,
include_workflow=True,
include_settings=True,
include_contributors=True,
include_annotation_classes=True
)
meta["name"] = self.OTHER_PROJECT_NAME
sa.create_project_from_metadata(meta)
created = sa.get_project_metadata(self.OTHER_PROJECT_NAME,
include_workflow=True,
include_settings=True,
include_contributors=True,
include_annotation_classes=True
)
self.assertEqual(len(created["classes"]), 1)
self.assertEqual(len(created["contributors"]), 1)
self.assertEqual([f"{i['attribute']}_{i['value']}" for i in meta["settings"]],
[f"{i['attribute']}_{i['value']}" for i in created["settings"]])
self.assertEqual(len(created['workflows']), 1)


class TestProject(BaseTestCase):
PROJECT_NAME = "sample_basic_project"
PROJECT_TYPE = "Pixel"
Expand All @@ -19,6 +109,7 @@ class TestProject(BaseTestCase):
PNG_POSTFIX = "*___save.png"
FUSE_PNG_POSTFIX = "*___fuse.png"


@property
def folder_path(self):
return Path(
Expand Down