5050from lib .core .entities .classes import AnnotationClassEntity
5151from lib .core .entities .classes import AttributeGroup
5252from lib .core .entities .integrations import IntegrationEntity
53+ from lib .core .entities .integrations import IntegrationTypeEnum
5354from lib .core .enums import ImageQuality
5455from lib .core .enums import ProjectType
5556from lib .core .enums import ClassTypeEnum
6465from lib .infrastructure .utils import extract_project_folder
6566from lib .infrastructure .validators import wrap_error
6667
67-
6868logger = logging .getLogger ("sa" )
6969
7070NotEmptyStr = TypeVar ("NotEmptyStr" , bound = constr (strict = True , min_length = 1 ))
7777 "Video" ,
7878 "Document" ,
7979 "Tiled" ,
80- "Other" ,
8180 "PointCloud" ,
8281 "GenAI" ,
8382]
@@ -110,6 +109,7 @@ class PriorityScore(TypedDict):
110109class Attachment (TypedDict , total = False ):
111110 url : Required [str ] # noqa
112111 name : NotRequired [str ] # noqa
112+ integration : NotRequired [str ] # noqa
113113
114114
115115class SAClient (BaseInterfaceFacade , metaclass = TrackableMeta ):
@@ -311,7 +311,7 @@ def create_project(
311311 :param project_description: the new project's description
312312 :type project_description: str
313313
314- :param project_type: the new project type, Vector, Pixel, Video, Document, Tiled, PointCloud, Other .
314+ :param project_type: the new project type, Vector, Pixel, Video, Document, Tiled, PointCloud, GenAI .
315315 :type project_type: str
316316
317317 :param settings: list of settings objects
@@ -2559,6 +2559,20 @@ def attach_items(
25592559 attachments = [{"name": "item", "url": "https://..."}]
25602560 )
25612561
2562+ Example of attaching items from custom integration:
2563+ ::
2564+ client = SAClient()
2565+ client.attach_items(
2566+ project = "Medical Annotations",
2567+ attachments = [
2568+ {
2569+ "name": "item",
2570+ "url": "https://sa-public-files.s3.../text_file_example_1.jpeg"
2571+ "integration": "custom-integration"
2572+ }
2573+ ]
2574+ )
2575+
25622576 """
25632577
25642578 project_name , folder_name = extract_project_folder (project )
@@ -2579,25 +2593,51 @@ def attach_items(
25792593 logger .info ("Dropping duplicates." )
25802594 unique_attachments = parse_obj_as (List [AttachmentEntity ], unique_attachments )
25812595 uploaded , fails , duplicated = [], [], []
2582- if unique_attachments :
2596+ _unique_attachments = []
2597+ if any (i .integration for i in unique_attachments ):
2598+ integtation_item_map = {
2599+ i .name : i
2600+ for i in self .controller .integrations .list ().data
2601+ if i .type == IntegrationTypeEnum .CUSTOM
2602+ }
2603+ invalid_integrations = set ()
2604+ for attachment in unique_attachments :
2605+ if attachment .integration :
2606+ if attachment .integration in integtation_item_map :
2607+ attachment .integration_id = integtation_item_map [
2608+ attachment .integration
2609+ ].id
2610+ else :
2611+ invalid_integrations .add (attachment .integration )
2612+ continue
2613+ _unique_attachments .append (attachment )
2614+ if invalid_integrations :
2615+ logger .error (
2616+ f"The ['{ ',' .join (invalid_integrations )} '] integrations specified for the items doesn't exist in the "
2617+ "list of integrations on the platform. Any associated items will be skipped."
2618+ )
2619+ else :
2620+ _unique_attachments = unique_attachments
2621+
2622+ if _unique_attachments :
25832623 logger .info (
2584- f"Attaching { len (unique_attachments )} file(s) to project { project } ."
2624+ f"Attaching { len (_unique_attachments )} file(s) to project { project } ."
25852625 )
25862626 project , folder = self .controller .get_project_folder (
25872627 project_name , folder_name
25882628 )
25892629 response = self .controller .items .attach (
25902630 project = project ,
25912631 folder = folder ,
2592- attachments = unique_attachments ,
2632+ attachments = _unique_attachments ,
25932633 annotation_status = annotation_status ,
25942634 )
25952635 if response .errors :
25962636 raise AppException (response .errors )
25972637 uploaded , duplicated = response .data
25982638 fails = [
25992639 attachment .name
2600- for attachment in unique_attachments
2640+ for attachment in _unique_attachments
26012641 if attachment .name not in uploaded and attachment .name not in duplicated
26022642 ]
26032643 return uploaded , fails , duplicated
0 commit comments