Skip to content
Merged
15 changes: 14 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,19 @@
# Changelog
All release highlights of this project will be documented in this file.

## 4.4.7 - December 04, 2022
### Updated
- `SAClient.search_folders` _method_ to add a new `status` argument for searching folders via status.
- Schemas for `Annotation Classes` and `Video Annotation` to support **text** and **numeric input** attribute group types.
### Fixed
- `SAClient.query` _method_ to address invalid exceptions.
- `SAClient.download_export` _method_ to address the issue with downloading for Windows OS.
- `SAClient.attach_items_from_integrated_storage` _method_ to address "integration not found" error.
- `SAClient.aggregate_annotations_as_df` _method_ to support files without "___objects" in their naming.
### Removed
- `SAClient.add_annotation_bbox_to_image` _method_, use `SAClient.upload_annotations` instead.
- `SAClient.add_annotation_point_to_image` _method_, use `SAClient.upload_annotations` instead.
- `SAClient.add_annotation_comment_to_image` _method_, use `SAClient.upload_annotations` instead.
###
## 4.4.6 - November 23, 2022
### Updated
- `SAClient.aggregate_annotations_as_df` method to aggregate "comment" type instances.
Expand Down
4 changes: 3 additions & 1 deletion src/superannotate/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import os
import sys

__version__ = "4.4.7dev6"

__version__ = "4.4.7"


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

Expand Down
10 changes: 5 additions & 5 deletions src/superannotate/lib/core/usecases/items.py
Original file line number Diff line number Diff line change
Expand Up @@ -658,16 +658,16 @@ def validate_items(self):
existing_items = []
for i in range(0, len(self._item_names), self.CHUNK_SIZE):
search_names = self._item_names[i : i + self.CHUNK_SIZE] # noqa
cand_items = self._service_provider.items.list_by_names(
response = self._service_provider.items.list_by_names(
project=self._project,
folder=self._folder,
names=search_names,
).data
)
if not response.ok:
raise AppValidationException(response.error)

if isinstance(cand_items, dict):
continue
cand_items = response.data
existing_items += cand_items

if not existing_items:
raise AppValidationException(self.ERROR_MESSAGE)
if existing_items:
Expand Down
11 changes: 7 additions & 4 deletions src/superannotate/lib/core/usecases/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import os.path
import tempfile
import time
import platform
import zipfile
from pathlib import Path
from typing import List
Expand Down Expand Up @@ -140,7 +141,8 @@ def execute(self):


class DownloadExportUseCase(BaseReportableUseCase):
FORBIDDEN_CHARS = "*./\[]:;|,\"\'"
FORBIDDEN_CHARS = "*./\\[]:;|,\"'"

def __init__(
self,
service_provider: BaseServiceProvider,
Expand Down Expand Up @@ -206,9 +208,10 @@ def download_to_local_storage(self, destination: str, extract_zip=False):
time.sleep(1)
self.reporter.stop_spinner()
filename = Path(export["path"]).stem
for char in DownloadExportUseCase.FORBIDDEN_CHARS:
filename=filename.replace(char, "_")
filepath = Path(destination) / (filename+'.zip')
if platform.system().lower() == "windows":
for char in DownloadExportUseCase.FORBIDDEN_CHARS:
filename = filename.replace(char, "_")
filepath = Path(destination) / (filename + ".zip")
with requests.get(export["download"], stream=True) as response:
response.raise_for_status()
with open(filepath, "wb") as f:
Expand Down
31 changes: 20 additions & 11 deletions src/superannotate/lib/infrastructure/services/item.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,17 +46,26 @@ def list_by_names(
folder: entities.FolderEntity,
names: List[str],
):
return self.client.request(
self.URL_LIST_BY_NAMES,
"post",
data={
"project_id": project.id,
"team_id": project.team_id,
"folder_id": folder.id,
"names": names,
},
content_type=ItemListResponse,
)
chunk_size = 200
items = []
response = None
for i in range(0, len(names), chunk_size):
response = self.client.request(
self.URL_LIST_BY_NAMES,
"post",
data={
"project_id": project.id,
"team_id": project.team_id,
"folder_id": folder.id,
"names": names[i : i + chunk_size], # noqa
},
content_type=ItemListResponse,
)
if not response.ok:
return response
items.extend(response.data)
response.data = items
return response

def attach(
self,
Expand Down