Skip to content

Commit 53c0a5d

Browse files
authored
Merge pull request #390 from superannotateai/569-get-project-metadata
569 get project metadata
2 parents 6366372 + e8d3d4b commit 53c0a5d

File tree

6 files changed

+125
-19
lines changed

6 files changed

+125
-19
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,7 @@ def create_project_from_metadata(project_metadata: Project):
193193
contributors=project_metadata.get("contributors", []),
194194
settings=project_metadata.get("settings", []),
195195
annotation_classes=project_metadata.get("classes", []),
196-
workflows=project_metadata.get("workflow", []),
196+
workflows=project_metadata.get("workflows", []),
197197
)
198198
if response.errors:
199199
raise AppException(response.errors)

src/superannotate/lib/core/entities/project_entities.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
from typing import List
66

77
from lib.core.enums import ClassTypeEnum
8+
from lib.core.enums import ImageQuality
89
from lib.core.enums import SegmentationStatus
910
from superannotate_schemas.schemas.classes import AnnotationClass
1011

@@ -176,6 +177,11 @@ def to_dict(self):
176177
"value": self.value,
177178
}
178179

180+
def serialize(self):
181+
if self.attribute == "ImageQuality":
182+
self.value = ImageQuality.get_value(self.value)
183+
return self.to_dict()
184+
179185

180186
class WorkflowEntity(BaseEntity):
181187
def __init__(

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

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -240,26 +240,37 @@ def execute(self):
240240
)
241241
for annotation_class in self._annotation_classes:
242242
annotation_classes_mapping[
243-
annotation_class.uuid
243+
annotation_class.id
244244
] = annotation_repo.insert(annotation_class)
245245
self._response.data.annotation_classes = self._annotation_classes
246246
if self._workflows:
247-
workflow_repo = self._workflows_repo(self._backend_service, entity)
248-
for workflow in self._workflows:
249-
workflow.project_id = entity.uuid
250-
workflow.class_id = annotation_classes_mapping.get(
251-
workflow.class_id
252-
)
253-
workflow_repo.insert(workflow)
247+
set_workflow_use_case = SetWorkflowUseCase(
248+
service=self._backend_service,
249+
annotation_classes_repo=self._annotation_classes_repo(
250+
self._backend_service, entity
251+
),
252+
workflow_repo=self._workflows_repo(self._backend_service, entity),
253+
steps=self._workflows,
254+
project=entity,
255+
)
256+
set_workflow_response = set_workflow_use_case.execute()
257+
if set_workflow_response.errors:
258+
self._response.errors = set_workflow_response.errors
254259
data["workflows"] = self._workflows
255260

256261
if self._contributors:
257262
for contributor in self._contributors:
258-
self._backend_service.share_project(
259-
entity.uuid,
260-
entity.team_id,
261-
contributor["user_id"],
262-
constances.UserRole.get_value(contributor["user_role"]),
263+
self._backend_service.share_project_bulk(
264+
team_id=entity.team_id,
265+
project_id=entity.uuid,
266+
users=[
267+
{
268+
"user_id": contributor["user_id"],
269+
"user_role": constances.UserRole.get_value(
270+
contributor["user_role"]
271+
),
272+
}
273+
],
263274
)
264275
data["contributors"] = self._contributors
265276

src/superannotate/lib/infrastructure/controller.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -319,11 +319,9 @@ def create_project(
319319
settings=[
320320
ProjectSettingsRepository.dict2entity(setting) for setting in settings
321321
],
322-
workflows=[
323-
WorkflowRepository.dict2entity(workflow) for workflow in workflows
324-
],
322+
workflows=workflows,
325323
annotation_classes=[
326-
AnnotationClassRepository.dict2entity(annotation_class)
324+
AnnotationClassEntity(**annotation_class)
327325
for annotation_class in annotation_classes
328326
],
329327
contributors=contributors,

src/superannotate/lib/infrastructure/repositories.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,7 @@ def delete(self, uuid: int):
198198

199199
def update(self, entity: ProjectSettingEntity):
200200
res = self._service.set_project_settings(
201-
self._project.uuid, self._project.team_id, [entity.to_dict()]
201+
self._project.uuid, self._project.team_id, [entity.serialize()]
202202
)
203203
return entity
204204

tests/integration/projects/test_basic_project.py

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,96 @@
99
from tests.integration.base import BaseTestCase
1010

1111

12+
13+
class TestProjectCreateMetadata(BaseTestCase):
14+
PROJECT_NAME = "sample_basic_project"
15+
PROJECT_TYPE = "Vector"
16+
OTHER_PROJECT_NAME = "other_project"
17+
PROJECT_DESCRIPTION = "DESCRIPTION"
18+
IMAGE_QUALITY_ORIGINAL = "original"
19+
20+
def setUp(self, *args, **kwargs):
21+
super(TestProjectCreateMetadata, self).setUp()
22+
try:
23+
sa.delete_project(self.OTHER_PROJECT_NAME)
24+
except:
25+
pass
26+
27+
def tearDown(self) -> None:
28+
super(TestProjectCreateMetadata, self).tearDown()
29+
try:
30+
sa.delete_project(self.OTHER_PROJECT_NAME)
31+
except:
32+
pass
33+
34+
def test_create_project_from_metadata(self):
35+
sa.create_annotation_class(
36+
self.PROJECT_NAME,
37+
"rrr",
38+
"#FFAAFF",
39+
[
40+
{
41+
"name": "tall",
42+
"is_multiselect": 0,
43+
"attributes": [{"name": "yes"}, {"name": "no"}],
44+
},
45+
{
46+
"name": "age",
47+
"is_multiselect": 0,
48+
"attributes": [{"name": "young"}, {"name": "old"}],
49+
},
50+
],
51+
)
52+
sa.set_project_workflow(
53+
self.PROJECT_NAME,
54+
[
55+
{
56+
"step": 1,
57+
"className": "rrr",
58+
"tool": 3,
59+
"attribute": [
60+
{
61+
"attribute": {
62+
"name": "young",
63+
"attribute_group": {"name": "age"},
64+
}
65+
},
66+
{
67+
"attribute": {
68+
"name": "yes",
69+
"attribute_group": {"name": "tall"},
70+
}
71+
},
72+
],
73+
}
74+
],
75+
)
76+
77+
team_users = sa.search_team_contributors()
78+
sa.share_project(self.PROJECT_NAME, team_users[0], "QA")
79+
80+
sa.set_project_default_image_quality_in_editor(self.PROJECT_NAME, self.IMAGE_QUALITY_ORIGINAL)
81+
meta = sa.get_project_metadata(self.PROJECT_NAME,
82+
include_workflow=True,
83+
include_settings=True,
84+
include_contributors=True,
85+
include_annotation_classes=True
86+
)
87+
meta["name"] = self.OTHER_PROJECT_NAME
88+
sa.create_project_from_metadata(meta)
89+
created = sa.get_project_metadata(self.OTHER_PROJECT_NAME,
90+
include_workflow=True,
91+
include_settings=True,
92+
include_contributors=True,
93+
include_annotation_classes=True
94+
)
95+
self.assertEqual(len(created["classes"]), 1)
96+
self.assertEqual(len(created["contributors"]), 1)
97+
self.assertEqual([f"{i['attribute']}_{i['value']}" for i in meta["settings"]],
98+
[f"{i['attribute']}_{i['value']}" for i in created["settings"]])
99+
self.assertEqual(len(created['workflows']), 1)
100+
101+
12102
class TestProject(BaseTestCase):
13103
PROJECT_NAME = "sample_basic_project"
14104
PROJECT_TYPE = "Pixel"
@@ -19,6 +109,7 @@ class TestProject(BaseTestCase):
19109
PNG_POSTFIX = "*___save.png"
20110
FUSE_PNG_POSTFIX = "*___fuse.png"
21111

112+
22113
@property
23114
def folder_path(self):
24115
return Path(

0 commit comments

Comments
 (0)