Skip to content

Commit a756370

Browse files
authored
Merge pull request #227 from superannotateai/sdk_backend_error_fix
Fixed backend error
2 parents 5fa87ea + ac8930a commit a756370

File tree

10 files changed

+121
-151
lines changed

10 files changed

+121
-151
lines changed

pytest.ini

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@
22
minversion = 3.0
33
log_cli=true
44
python_files = test_*.py
5-
addopts = -n32 --dist=loadscope
5+
addopts = -n auto --dist=loadscope

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

Lines changed: 71 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -281,20 +281,22 @@ def execute(self):
281281
except AppValidationException as e:
282282
self._response.errors = e
283283
return self._response
284-
285-
backend_response = self._backend_service.attach_files(
286-
project_id=self._project.uuid,
287-
folder_id=self._folder.uuid,
288-
team_id=self._project.team_id,
289-
files=to_upload,
290-
annotation_status_code=self.annotation_status_code,
291-
upload_state_code=self.upload_state_code,
292-
meta=meta,
293-
)
294-
if isinstance(backend_response, dict) and "error" in backend_response:
295-
self._response.errors = AppException(backend_response["error"])
284+
if to_upload:
285+
backend_response = self._backend_service.attach_files(
286+
project_id=self._project.uuid,
287+
folder_id=self._folder.uuid,
288+
team_id=self._project.team_id,
289+
files=to_upload,
290+
annotation_status_code=self.annotation_status_code,
291+
upload_state_code=self.upload_state_code,
292+
meta=meta,
293+
)
294+
if isinstance(backend_response, dict) and "error" in backend_response:
295+
self._response.errors = AppException(backend_response["error"])
296+
else:
297+
self._response.data = backend_response, duplications
296298
else:
297-
self._response.data = backend_response, duplications
299+
self._response.data = [], duplications
298300
return self._response
299301

300302

@@ -1088,7 +1090,7 @@ def __init__(
10881090
self,
10891091
project: ProjectEntity,
10901092
folder: FolderEntity,
1091-
s3_repo: BaseManageableRepository,
1093+
s3_repo,
10921094
settings: BaseManageableRepository,
10931095
backend_client: SuerannotateServiceProvider,
10941096
annotation_status: str,
@@ -1112,15 +1114,19 @@ def __init__(
11121114
self._annotation_status = annotation_status
11131115
self._auth_data = None
11141116

1115-
def validate_auth_data(self):
1116-
response = self._backend_client.get_s3_upload_auth_token(
1117-
team_id=self._project.team_id,
1118-
folder_id=self._folder.uuid,
1119-
project_id=self._project.uuid,
1117+
@property
1118+
def s3_repo(self):
1119+
self._auth_data = self._backend_client.get_s3_upload_auth_token(
1120+
self._project.team_id, self._folder.uuid, self._project.uuid
1121+
)
1122+
if "error" in self._auth_data:
1123+
raise AppException(self._auth_data.get("error"))
1124+
return self._s3_repo(
1125+
self._auth_data["accessKeyId"],
1126+
self._auth_data["secretAccessKey"],
1127+
self._auth_data["sessionToken"],
1128+
self._auth_data["bucket"],
11201129
)
1121-
if "error" in response:
1122-
raise AppException(response.get("error"))
1123-
self._auth_data = response
11241130

11251131
def validate_project_type(self):
11261132
if self._project.project_type in [
@@ -1194,7 +1200,7 @@ def execute(self) -> Response:
11941200
else Path(self._image_path).name,
11951201
project_settings=self._settings.get_all(),
11961202
image=image_bytes,
1197-
s3_repo=self._s3_repo,
1203+
s3_repo=self.s3_repo,
11981204
upload_path=self.auth_data["filePath"],
11991205
image_quality_in_editor=self._image_quality_in_editor,
12001206
).execute()
@@ -1458,7 +1464,7 @@ def execute(self):
14581464
folder=self._folder,
14591465
backend_service_provider=self._backend_client,
14601466
attachments=[
1461-
image.entity for image in uploaded_images[i : i + 100]
1467+
image.entity for image in uploaded_images[i : i + 100] # noqa: E203
14621468
],
14631469
annotation_status=self._annotation_status,
14641470
upload_state_code=constances.UploadState.BASIC.value,
@@ -1580,6 +1586,27 @@ def __init__(
15801586
self._annotation_status = annotation_status
15811587
self._image_quality_in_editor = image_quality_in_editor
15821588
self._settings = settings
1589+
self._auth_data = None
1590+
1591+
@property
1592+
def auth_data(self):
1593+
if not self._auth_data:
1594+
self._auth_data = self._backend_service.get_s3_upload_auth_token(
1595+
self._project.team_id, self._folder.uuid, self._project.uuid
1596+
)
1597+
return self._auth_data
1598+
1599+
@property
1600+
def s3_repo(self):
1601+
1602+
if "error" in self.auth_data:
1603+
raise AppException(self._auth_data.get("error"))
1604+
return self._s3_repo(
1605+
self.auth_data["accessKeyId"],
1606+
self.auth_data["secretAccessKey"],
1607+
self.auth_data["sessionToken"],
1608+
self.auth_data["bucket"],
1609+
)
15831610

15841611
def validate_limitations(self):
15851612
response = self._backend_service.get_limitations(
@@ -1624,18 +1651,6 @@ def validate_annotation_status(self):
16241651
else:
16251652
self._annotation_status = constances.AnnotationStatus.NOT_STARTED
16261653

1627-
def get_auth_data(self, project_id: int, team_id: int, folder_id: int):
1628-
response = self._backend_service.get_s3_upload_auth_token(
1629-
team_id, folder_id, project_id
1630-
)
1631-
if "error" in response:
1632-
raise AppException(response.get("error"))
1633-
return response
1634-
1635-
@property
1636-
def s3_repo(self):
1637-
return self._s3_repo
1638-
16391654
def upload_image(self, image_url, image_name=None):
16401655
download_response = DownloadImageFromPublicUrlUseCase(
16411656
project=self._project, image_url=image_url, image_name=image_name
@@ -1661,10 +1676,8 @@ def upload_image(self, image_url, image_name=None):
16611676
project_settings=self._settings,
16621677
image_path=image_name,
16631678
image=content,
1664-
s3_repo=self._s3_repo,
1665-
upload_path=self.get_auth_data(
1666-
self._project.uuid, self._project.team_id, self._folder.uuid
1667-
)["filePath"],
1679+
s3_repo=self.s3_repo,
1680+
upload_path=self.auth_data["filePath"],
16681681
image_quality_in_editor=self._image_quality_in_editor,
16691682
).execute()
16701683

@@ -1911,7 +1924,7 @@ def execute(self):
19111924
response = AttachFileUrlsUseCase(
19121925
project=self._project,
19131926
folder=self._folder,
1914-
attachments=self._attachments[i : i + 500], # noqa: E203
1927+
attachments=self._attachments[i : i + self.CHUNK_SIZE], # noqa: E203
19151928
backend_service_provider=self._backend_service,
19161929
annotation_status=self._annotation_status,
19171930
upload_state_code=self._upload_state_code,
@@ -1937,7 +1950,7 @@ def __init__(
19371950
to_folder: FolderEntity,
19381951
backend_service: SuerannotateServiceProvider,
19391952
images: BaseManageableRepository,
1940-
to_upload_s3_repo: BaseManageableRepository,
1953+
s3_repo,
19411954
project_settings: List[ProjectSettingEntity],
19421955
include_annotations: Optional[bool] = True,
19431956
copy_annotation_status: Optional[bool] = True,
@@ -1950,7 +1963,7 @@ def __init__(
19501963
self._image_name = image_name
19511964
self._to_project = to_project
19521965
self._to_folder = to_folder
1953-
self._to_upload_s3_repo = to_upload_s3_repo
1966+
self._s3_repo = s3_repo
19541967
self._project_settings = project_settings
19551968
self._include_annotations = include_annotations
19561969
self._copy_annotation_status = copy_annotation_status
@@ -2002,6 +2015,20 @@ def validate_limitations(self):
20022015
if response.data.super_user_limit and response.data.super_user_limit.remaining_image_count < 1:
20032016
raise AppValidationException(constances.COPY_SUPER_LIMIT_ERROR_MESSAGE)
20042017

2018+
@property
2019+
def s3_repo(self):
2020+
self._auth_data = self._backend_service.get_s3_upload_auth_token(
2021+
self._to_project.team_id, self._to_folder.uuid, self._to_project.uuid
2022+
)
2023+
if "error" in self._auth_data:
2024+
raise AppException(self._auth_data.get("error"))
2025+
return self._s3_repo(
2026+
self._auth_data["accessKeyId"],
2027+
self._auth_data["secretAccessKey"],
2028+
self._auth_data["sessionToken"],
2029+
self._auth_data["bucket"],
2030+
)
2031+
20052032
def execute(self) -> Response:
20062033
if self.is_valid():
20072034
image = (
@@ -2038,7 +2065,7 @@ def execute(self) -> Response:
20382065
image=image_bytes,
20392066
project_settings=self._project_settings,
20402067
upload_path=auth_data["filePath"],
2041-
s3_repo=self._to_upload_s3_repo,
2068+
s3_repo=self.s3_repo,
20422069
).execute()
20432070
if s3_response.errors:
20442071
raise AppException(s3_response.errors)

src/superannotate/lib/infrastructure/controller.py

Lines changed: 3 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -298,50 +298,6 @@ def update_project(self, name: str, project_data: dict) -> Response:
298298
use_case = usecases.UpdateProjectUseCase(project, project_data, self.projects)
299299
return use_case.execute()
300300

301-
def upload_images(
302-
self,
303-
project_name: str,
304-
folder_name: str,
305-
images: List[ImageEntity],
306-
annotation_status: str = None,
307-
):
308-
project = self._get_project(project_name)
309-
folder = self._get_folder(project, folder_name)
310-
use_case = usecases.AttachFileUrlsUseCase(
311-
project=project,
312-
folder=folder,
313-
backend_service_provider=self._backend_client,
314-
attachments=images,
315-
annotation_status=annotation_status,
316-
upload_state_code=constances.UploadState.BASIC.value,
317-
)
318-
return use_case.execute()
319-
320-
def upload_image_to_s3(
321-
self,
322-
project_name: str,
323-
image_path: str, # image path to upload
324-
image_bytes: io.BytesIO,
325-
folder_name: str = None, # project folder path
326-
image_quality_in_editor: str = None,
327-
):
328-
project = self._get_project(project_name)
329-
folder = self._get_folder(project, folder_name)
330-
s3_repo = self.get_s3_repository(self.team_id, project.uuid, folder.uuid)
331-
auth_data = self.get_auth_data(project.uuid, self.team_id, folder.uuid)
332-
use_case = usecases.UploadImageS3UseCase(
333-
project=project,
334-
project_settings=ProjectSettingsRepository(
335-
self._backend_client, project
336-
).get_all(),
337-
image_path=image_path,
338-
image=image_bytes,
339-
s3_repo=s3_repo,
340-
upload_path=auth_data["filePath"],
341-
image_quality_in_editor=image_quality_in_editor,
342-
)
343-
return use_case.execute()
344-
345301
def upload_image_to_project(
346302
self,
347303
project_name: str,
@@ -367,7 +323,7 @@ def upload_image_to_project(
367323
settings=ProjectSettingsRepository(
368324
service=self._backend_client, project=project
369325
),
370-
s3_repo=self.get_s3_repository(self.team_id, project.uuid, folder.uuid),
326+
s3_repo=self.s3_repo,
371327
backend_client=self._backend_client,
372328
image_path=image_path,
373329
image_bytes=image_bytes,
@@ -455,7 +411,7 @@ def upload_images_from_public_urls_to_project(
455411
settings=ProjectSettingsRepository(
456412
service=self._backend_client, project=project
457413
),
458-
s3_repo=self.get_s3_repository(self.team_id, project.uuid, folder.uuid),
414+
s3_repo=self.s3_repo,
459415
image_quality_in_editor=image_quality_in_editor,
460416
annotation_status=annotation_status,
461417
)
@@ -492,27 +448,6 @@ def clone_project(
492448
)
493449
return use_case.execute()
494450

495-
def attach_urls(
496-
self,
497-
project_name: str,
498-
files: List[ImageEntity],
499-
folder_name: str = None,
500-
annotation_status: str = None,
501-
upload_state_code: int = None,
502-
):
503-
project = self._get_project(project_name)
504-
folder = self._get_folder(project, folder_name)
505-
506-
use_case = usecases.AttachFileUrlsUseCase(
507-
project=project,
508-
folder=folder,
509-
attachments=files,
510-
backend_service_provider=self._backend_client,
511-
annotation_status=annotation_status,
512-
upload_state_code=upload_state_code,
513-
)
514-
return use_case.execute()
515-
516451
def interactive_attach_urls(
517452
self,
518453
project_name: str,
@@ -723,9 +658,7 @@ def copy_image(
723658
project_settings=ProjectSettingsRepository(
724659
self._backend_client, to_project
725660
).get_all(),
726-
to_upload_s3_repo=self.get_s3_repository(
727-
self.team_id, to_project.uuid, to_folder.uuid
728-
),
661+
s3_repo=self.s3_repo,
729662
copy_annotation_status=copy_annotation_status,
730663
move=move,
731664
)
@@ -1593,13 +1526,6 @@ def list_images(
15931526
)
15941527
return use_case.execute()
15951528

1596-
@staticmethod
1597-
def upload_file_to_s3(to_s3_bucket, path, s3_key: str):
1598-
use_case = usecases.UploadFileToS3UseCase(
1599-
to_s3_bucket=to_s3_bucket, path=path, s3_key=s3_key
1600-
)
1601-
return use_case.execute()
1602-
16031529
def search_models(
16041530
self,
16051531
name: str,
@@ -1643,28 +1569,3 @@ def delete_annotations(
16431569
image_names=image_names,
16441570
)
16451571
return use_case.execute()
1646-
1647-
def get_duplicated_images(
1648-
self, project_name: str, folder_name: str, images: List[str]
1649-
):
1650-
project = self._get_project(project_name)
1651-
folder = self._get_folder(project, folder_name)
1652-
use_case = usecases.GetBulkImages(
1653-
service=self._backend_client,
1654-
project_id=project.uuid,
1655-
team_id=project.team_id,
1656-
folder_id=folder.uuid,
1657-
images=images,
1658-
)
1659-
return use_case.execute().data
1660-
1661-
def get_project_limitations(self, project_name: str, folder_name: str):
1662-
project = self._get_project(project_name)
1663-
folder = self._get_folder(project, folder_name)
1664-
1665-
return usecases.GetUserLimitsUseCase(
1666-
service=self._backend_client,
1667-
project_id=project.uuid,
1668-
team_id=project.team_id,
1669-
folder_id=folder.uuid,
1670-
).execute()

tests/integration/test_annotation_delete.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import os
22
from os.path import dirname
3+
import pytest
34

45
import src.superannotate as sa
56
from tests.integration.base import BaseTestCase
@@ -70,6 +71,7 @@ def test_delete_annotations_by_not_existing_name(self):
7071
)
7172
self.assertRaises(Exception, sa.delete_annotations, self.PROJECT_NAME, [self.EXAMPLE_IMAGE_2])
7273

74+
@pytest.mark.flaky(reruns=2)
7375
def test_delete_annotations_wrong_path(self):
7476
sa.create_folder(self.PROJECT_NAME, self.TEST_FOLDER_NAME)
7577
sa.upload_images_from_folder_to_project(

0 commit comments

Comments
 (0)