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
20 changes: 16 additions & 4 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,20 @@ History

All release highlights of this project will be documented in this file.

4.4.17 - December 21, 2023
__________________________

**Added**

- ``SAClient.upload_annotations()`` added default values to the annotations during the upload.

**Updated**

- Fixed `SAClient.search_project() search with special characters.`
- ``pandas`` dependency ``pandas~=2.0``

4.4.16 - November 12, 2023
_______________________
__________________________

**Added**

Expand All @@ -16,9 +28,9 @@ _______________________
**Updated**

- Documentation updates
- pillow dependency ``pillow>=9.5,~=10.0``.
- opencv dependency replaced by ``opencv-python-headless~=4.7``.
- pydantic dependency ``pydantic>=1.10,!=2.0.*``.
- ``pillow`` dependency ``pillow>=9.5,~=10.0``.
- ``opencv`` dependency replaced by ``opencv-python-headless~=4.7``.
- ``pydantic`` dependency ``pydantic>=1.10,!=2.0.*``.

4.4.15 - August 20, 2023
________________________
Expand Down
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ opencv-python-headless~=4.7
packaging~=23.1
plotly~=5.14
email-validator~=2.0
pandas~=1.3
pandas~=2.0
ffmpeg-python~=0.2
pillow>=9.5,~=10.0
tqdm~=4.66.1
Expand Down
2 changes: 1 addition & 1 deletion src/superannotate/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import sys


__version__ = "4.4.16"
__version__ = "4.4.17"

sys.path.append(os.path.split(os.path.realpath(__file__))[0])

Expand Down
1 change: 1 addition & 0 deletions src/superannotate/lib/app/interface/sdk_interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -1668,6 +1668,7 @@ def upload_annotations(
folder=folder,
annotations=annotations,
keep_status=keep_status,
user=self.controller.current_user,
)
if response.errors:
raise AppException(response.errors)
Expand Down
5 changes: 5 additions & 0 deletions src/superannotate/lib/core/usecases/annotations.py
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,7 @@ def __init__(
folder: FolderEntity,
annotations: List[dict],
service_provider: BaseServiceProvider,
user: UserEntity,
keep_status: bool = False,
):
super().__init__(reporter)
Expand All @@ -304,6 +305,7 @@ def __init__(
self._service_provider = service_provider
self._keep_status = keep_status
self._report = Report([], [], [], [])
self._user = user

def validate_project_type(self):
if self._project.type == constants.ProjectType.PIXEL.value:
Expand Down Expand Up @@ -439,6 +441,9 @@ def execute(self):
annotation_name = annotation["metadata"]["name"]
item = name_item_map.get(annotation_name)
if item:
annotation = UploadAnnotationUseCase.set_defaults(
self._user.email, annotation, self._project.type
)
items_to_upload.append(
ItemToUpload(item=item, annotation_json=annotation)
)
Expand Down
2 changes: 2 additions & 0 deletions src/superannotate/lib/infrastructure/controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -568,6 +568,7 @@ def upload_multiple(
folder: FolderEntity,
annotations: List[dict],
keep_status: bool,
user: UserEntity,
):
use_case = usecases.UploadAnnotationsUseCase(
reporter=Reporter(),
Expand All @@ -576,6 +577,7 @@ def upload_multiple(
annotations=annotations,
service_provider=self.service_provider,
keep_status=keep_status,
user=user,
)
return use_case.execute()

Expand Down
11 changes: 9 additions & 2 deletions src/superannotate/lib/infrastructure/services/http_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

import aiohttp
import requests
from aiohttp.client_exceptions import ClientError
from lib.core.exceptions import AppException
from lib.core.service_types import ServiceResponse
from lib.core.serviceproviders import BaseClient
Expand Down Expand Up @@ -197,7 +198,7 @@ def serialize_response(
if not response.ok:
if response.status_code in (502, 504):
data[
"_error"
"res_error"
] = "Our service is currently unavailable, please try again later."
return content_type(**data)
else:
Expand Down Expand Up @@ -234,7 +235,13 @@ async def request(self, *args, **kwargs) -> aiohttp.ClientResponse:
for _ in range(attempts):
delay += self.BACKOFF_FACTOR
attempts -= 1
response = await super()._request(*args, **kwargs)
try:
response = await super()._request(*args, **kwargs)
except ClientError:
if not attempts:
raise
await asyncio.sleep(delay)
continue
if response.status not in self.RETRY_STATUS_CODES or not attempts:
return response
await asyncio.sleep(delay)
5 changes: 2 additions & 3 deletions src/superannotate/lib/infrastructure/services/project.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,8 @@ def create(self, entity: entities.ProjectEntity) -> ServiceResponse:

def list(self, condition: Condition = None):
return self.client.paginate(
url=f"{self.URL_LIST}?{condition.build_query()}"
if condition
else self.URL_LIST,
url=self.URL_LIST,
query_params=condition.get_as_params_dict(),
item_type=entities.ProjectEntity,
)

Expand Down
2 changes: 2 additions & 0 deletions tests/integration/annotations/test_upload_annotations.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ def test_annotation_folder_upload_download(self):
assert i["annotation_status"] == "InProgress"
assert annotation["instances"][-1]["type"] == "tag"
assert annotation["instances"][-2]["type"] == "tag"
assert annotation["instances"][-2]["probability"] == 100
assert annotation["instances"][-2]["creationType"] == "Preannotation"

def test_upload_keep_true(self):
self._attach_items()
Expand Down
62 changes: 62 additions & 0 deletions tests/integration/projects/test_search_project.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
from src.superannotate import SAClient
from tests.integration.base import BaseTestCase

sa = SAClient()


class TestProjectSearch(BaseTestCase):
PROJECT_NAME = "TestProjectSearch"
PROJECT_DESCRIPTION = "Desc"
PROJECT_TYPE = "Vector"
PROJECT_NAME_2 = "TestProjectSearch2"
REPLACED_PROJECT_NAME = "TestProjectSearchReplaced"
PROJECT_NAME_CONTAIN_SPECIAL_CHARACTER = "TestProjectName!@#$%+"

def setUp(self, *args, **kwargs):
self.tearDown()
self._project = sa.create_project(
self.PROJECT_NAME, self.PROJECT_DESCRIPTION, self.PROJECT_TYPE
)
self._project_2 = sa.create_project(
self.PROJECT_NAME_2, self.PROJECT_DESCRIPTION, self.PROJECT_TYPE
)

def tearDown(self) -> None:
projects = []
projects.extend(sa.search_projects(self.PROJECT_NAME, return_metadata=True))
projects.extend(
sa.search_projects(self.REPLACED_PROJECT_NAME, return_metadata=True)
)
projects.extend(
sa.search_projects(
self.PROJECT_NAME_CONTAIN_SPECIAL_CHARACTER, return_metadata=True
)
)
for project in projects:
try:
sa.delete_project(project)
except Exception as _:
pass

def test_project_search(self):
# search before rename
result = sa.search_projects(self.PROJECT_NAME, return_metadata=True)
assert len(result) == 2

# search after rename
sa.rename_project(self.PROJECT_NAME, self.REPLACED_PROJECT_NAME)
meta = sa.get_project_metadata(self.REPLACED_PROJECT_NAME)
self.assertEqual(meta["name"], self.REPLACED_PROJECT_NAME)
result = sa.search_projects(self.REPLACED_PROJECT_NAME, return_metadata=True)
assert len(result) == 1
assert result[0]["name"] == self.REPLACED_PROJECT_NAME

def test_project_search_special_character(self):
sa.rename_project(
self.PROJECT_NAME, self.PROJECT_NAME_CONTAIN_SPECIAL_CHARACTER
)
meta = sa.get_project_metadata(self.PROJECT_NAME_CONTAIN_SPECIAL_CHARACTER)
self.assertEqual(meta["name"], self.PROJECT_NAME_CONTAIN_SPECIAL_CHARACTER)
result = sa.search_projects("!@#$%+", return_metadata=True)
assert len(result) == 1
assert result[0]["name"] == self.PROJECT_NAME_CONTAIN_SPECIAL_CHARACTER