Skip to content

Commit b03a51f

Browse files
Narek MkhitaryanNarek Mkhitaryan
authored andcommitted
fix in multimodal creation
1 parent 8a53e72 commit b03a51f

File tree

6 files changed

+48
-5
lines changed

6 files changed

+48
-5
lines changed

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1211,7 +1211,11 @@ def create_project(
12111211
project = project_response.data
12121212
if form:
12131213
form_response = self.controller.projects.attach_form(project, form)
1214-
form_response.raise_for_status()
1214+
try:
1215+
form_response.raise_for_status()
1216+
except AppException:
1217+
self.controller.projects.delete(project)
1218+
raise
12151219
if classes:
12161220
classes_response = self.controller.annotation_classes.create_multiple(
12171221
project, classes

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,7 @@ def generate_class(self):
201201
"attribute_groups": [
202202
{
203203
"name": f"value_{self.id}",
204-
"group_type": "single_select",
204+
"group_type": "radio",
205205
"attributes": attributes,
206206
"default_value": default_value or "",
207207
}

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1005,13 +1005,15 @@ def __init__(
10051005
self._service_provider = service_provider
10061006
self._form = form
10071007
self._classes = None
1008+
self._entity = None
10081009

10091010
def validate_form(self):
10101011
if self._form is None:
10111012
raise AppException("Form was not provided.")
10121013
try:
10131014
self._entity = FormModel(**self._form)
10141015
except ValidationError:
1016+
self._service_provider.projects.delete(self._project)
10151017
raise AppException(
10161018
"The provided form object is invalid or does not match the required schema."
10171019
)

src/superannotate/lib/infrastructure/controller.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -596,12 +596,11 @@ def add_contributors(
596596
project: ProjectEntity,
597597
contributors: List[ContributorEntity],
598598
):
599-
project = self.get_metadata(project).data
599+
project = self.get_metadata(project, include_contributors=True).data
600600
for contributor in contributors:
601601
contributor.user_role = self.service_provider.get_role_name(
602602
project, contributor.user_role
603603
)
604-
project = self.get_metadata(project).data
605604
use_case = usecases.AddContributorsToProject(
606605
team=team,
607606
project=project,

tests/data_set/multimodal_form/form.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@
126126
"label": "Radio",
127127
"isRequired": false,
128128
"value": "",
129-
"exclude": true,
129+
"exclude": false,
130130
"disablePasting": false,
131131
"options": [
132132
{

tests/integration/projects/test_multimodal_creation.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import json
22
from unittest import TestCase
3+
from unittest.mock import MagicMock
4+
from unittest.mock import patch
35

46
from src.superannotate import AppException
57
from src.superannotate import SAClient
@@ -181,3 +183,39 @@ def test_create_project_invalid_form_structure(self):
181183
self.PROJECT_TYPE,
182184
form=invalid_form,
183185
)
186+
187+
def test_create_project_form_attach_failure_cleanup(self):
188+
"""Test that project is deleted when form attachment fails"""
189+
with open(self.FORM_PATH) as f:
190+
form_data = json.load(f)
191+
192+
# Mock the controller to simulate form attachment failure
193+
with patch.object(
194+
sa.controller.projects, "attach_form"
195+
) as mock_attach_form, patch.object(
196+
sa.controller.projects, "delete"
197+
) as mock_delete:
198+
# Create a mock response that raises AppException when raise_for_status is called
199+
mock_response = MagicMock()
200+
mock_response.raise_for_status.side_effect = AppException(
201+
"Form attachment failed"
202+
)
203+
mock_attach_form.return_value = mock_response
204+
205+
# Attempt to create project - should fail and trigger cleanup
206+
with self.assertRaises(AppException) as context:
207+
sa.create_project(
208+
self.PROJECT_NAME,
209+
"desc",
210+
self.PROJECT_TYPE,
211+
form=form_data,
212+
)
213+
214+
# Verify form attachment was attempted
215+
mock_attach_form.assert_called_once()
216+
217+
# Verify project deletion was called for cleanup
218+
mock_delete.assert_called_once()
219+
220+
# Verify the original exception is re-raised
221+
assert "Form attachment failed" in str(context.exception)

0 commit comments

Comments
 (0)