Skip to content

Commit 628b4a3

Browse files
committed
Added attach_items
1 parent 54edda5 commit 628b4a3

File tree

2 files changed

+81
-5
lines changed

2 files changed

+81
-5
lines changed

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

Lines changed: 78 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,12 @@
1111
from typing import Union
1212

1313
import boto3
14+
from pydantic import StrictBool
15+
from pydantic import conlist
16+
from pydantic import parse_obj_as
17+
from pydantic.error_wrappers import ValidationError
18+
from tqdm import tqdm
19+
1420
import lib.core as constances
1521
from lib.app.annotation_helpers import add_annotation_bbox_to_json
1622
from lib.app.annotation_helpers import add_annotation_comment_to_json
@@ -45,12 +51,7 @@
4551
from lib.core.types import PriorityScore
4652
from lib.core.types import Project
4753
from lib.infrastructure.controller import Controller
48-
from pydantic import conlist
49-
from pydantic import parse_obj_as
50-
from pydantic import StrictBool
51-
from pydantic.error_wrappers import ValidationError
5254
from superannotate.logger import get_default_logger
53-
from tqdm import tqdm
5455

5556
logger = get_default_logger()
5657

@@ -297,6 +298,7 @@ def search_images(
297298
"We're deprecating the search_images function. Please use search_items instead. Learn more."
298299
"https://superannotate.readthedocs.io/en/stable/superannotate.sdk.html#superannotate.search_items"
299300
)
301+
logger.warning(warning_msg)
300302
warnings.warn(warning_msg, DeprecationWarning)
301303
project_name, folder_name = extract_project_folder(project)
302304
project = Controller.get_default()._get_project(project_name)
@@ -2479,8 +2481,10 @@ def search_images_all_folders(
24792481
24802482
:param project: project name
24812483
:type project: str
2484+
24822485
:param image_name_prefix: image name prefix for search
24832486
:type image_name_prefix: str
2487+
24842488
:param annotation_status: if not None, annotation statuses of images to filter,
24852489
should be one of NotStarted InProgress QualityCheck Returned Completed Skipped
24862490
:type annotation_status: str
@@ -3087,3 +3091,72 @@ def search_items(
30873091
if response.errors:
30883092
raise AppException(response.errors)
30893093
return BaseSerializer.serialize_iterable(response.data)
3094+
3095+
3096+
@Trackable
3097+
@validate_arguments
3098+
def attach_items(
3099+
project: Union[NotEmptyStr, dict],
3100+
attachments,
3101+
annotation_status="NotStarted"
3102+
):
3103+
"""Link items from external storage to SuperAnnotate using URLs.
3104+
3105+
:param project: project name or folder path (e.g., “project1/folder1”)
3106+
:type project: str
3107+
3108+
:param attachments: path to CSV file or list of dicts containing attachments URLs.
3109+
:type attachments: path-like (str or Path) or list of dicts
3110+
3111+
:param annotation_status: value to set the annotation statuses of the
3112+
linked items:
3113+
“NotStarted”
3114+
“InProgress”
3115+
“QualityCheck”
3116+
“Returned”
3117+
“Completed”
3118+
“Skipped”
3119+
:type annotation_status: str
3120+
3121+
:return: list of attached item names, list of not attached item names, list of duplicate item names
3122+
that are already in SuperAnnotate.
3123+
:rtype: tuple
3124+
"""
3125+
project_name, folder_name = extract_project_folder(project)
3126+
3127+
images_to_upload, duplicate_images = get_paths_and_duplicated_from_csv(attachments)
3128+
3129+
attachments_data
3130+
3131+
use_case = Controller.get_default().attach_items(
3132+
project_name=project_name,
3133+
folder_name=folder_name,
3134+
files=ImageSerializer.deserialize(images_to_upload), # noqa: E203
3135+
annotation_status=annotation_status,
3136+
)
3137+
if len(duplicate_images):
3138+
logger.warning(
3139+
constances.ALREADY_EXISTING_FILES_WARNING.format(len(duplicate_images))
3140+
)
3141+
3142+
if use_case.is_valid():
3143+
logger.info(
3144+
constances.ATTACHING_FILES_MESSAGE.format(
3145+
len(images_to_upload), project
3146+
)
3147+
)
3148+
with tqdm(
3149+
total=use_case.attachments_count, desc="Attaching urls"
3150+
) as progress_bar:
3151+
for attached in use_case.execute():
3152+
progress_bar.update(attached)
3153+
uploaded, duplications = use_case.data
3154+
uploaded = [i["name"] for i in uploaded]
3155+
duplications.extend(duplicate_images)
3156+
failed_images = [
3157+
image["name"]
3158+
for image in images_to_upload
3159+
if image["name"] not in uploaded + duplications
3160+
]
3161+
return uploaded, failed_images, duplications
3162+
raise AppException(use_case.response.errors)

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,6 @@ class BaseEntity(TimedBaseModel):
2525

2626
class Config:
2727
extra = Extra.allow
28+
29+
30+
class AttachmentEntity(BaseModel):

0 commit comments

Comments
 (0)