2222from typing import Optional
2323from typing import Set
2424from typing import Tuple
25+ from typing import Union
2526
2627import aiofiles
2728import boto3
@@ -191,10 +192,13 @@ async def upload(_chunk: List[ItemToUpload]):
191192 [],
192193 )
193194 try :
195+ items_name_data_map = {i .item .name : i .annotation_json for i in chunk }
196+ if not items_name_data_map :
197+ return
194198 response = await service_provider .annotations .upload_small_annotations (
195199 project = project ,
196200 folder = folder ,
197- items_name_data_map = { i . item . name : i . annotation_json for i in chunk } ,
201+ items_name_data_map = items_name_data_map ,
198202 )
199203 if response .ok :
200204 if response .data .failed_items : # noqa
@@ -1450,44 +1454,56 @@ def __init__(
14501454 config : ConfigEntity ,
14511455 reporter : Reporter ,
14521456 project : ProjectEntity ,
1453- folder : FolderEntity ,
1454- item_names : Optional [List [str ]],
14551457 service_provider : BaseServiceProvider ,
1458+ folder : FolderEntity = None ,
1459+ items : Optional [Union [List [str ], List [int ]]] = None ,
14561460 ):
14571461 super ().__init__ (reporter )
14581462 self ._config = config
14591463 self ._project = project
14601464 self ._folder = folder
14611465 self ._service_provider = service_provider
1462- self ._item_names = item_names
1466+ self ._items = items
1467+ self ._item_name_id_map = {}
14631468 self ._item_names_provided = True
14641469 self ._big_annotations_queue = None
14651470
14661471 def validate_project_type (self ):
14671472 if self ._project .type == constants .ProjectType .PIXEL .value :
14681473 raise AppException ("The function is not supported for Pixel projects." )
14691474
1470- def validate_item_names (self ):
1471- if self ._item_names : # if names provided
1472- unique_item_names = list (set (self ._item_names ))
1473- len_unique_items , len_items = len (unique_item_names ), len (self ._item_names )
1474- if len_unique_items < len_items :
1475- self .reporter .log_info (
1476- f"Dropping duplicates. Found { len_unique_items } /{ len_items } unique items."
1477- )
1475+ @staticmethod
1476+ def items_duplication_validation (
1477+ reporter , items : Union [List [str ], List [int ]]
1478+ ) -> Union [List [str ], List [int ]]:
1479+ unique_items = list (set (items ))
1480+ len_unique_items , len_items = len (unique_items ), len (items )
1481+ if len_unique_items < len_items :
1482+ reporter .log_info (
1483+ f"Dropping duplicates. Found { len_unique_items } /{ len_items } unique items."
1484+ )
1485+ return unique_items
1486+
1487+ def validate_items (self ):
1488+ if self ._items : # if items provided:
1489+ self .items_duplication_validation (self .reporter , self ._items )
14781490 # Keep order required
14791491 seen = set ()
1480- self ._item_names = [
1481- i for i in self ._item_names if not (i in seen or seen .add (i ))
1482- ]
1492+ self ._items = [i for i in self ._items if not (i in seen or seen .add (i ))]
14831493
14841494 def _prettify_annotations (self , annotations : List [dict ]):
14851495 re_struct = {}
1486- if self ._item_names :
1496+ if self ._items :
1497+ names_provided = isinstance (self ._items [0 ], str )
14871498 for annotation in annotations :
1488- re_struct [annotation ["metadata" ]["name" ]] = annotation
1499+ if names_provided :
1500+ re_struct [annotation ["metadata" ]["name" ]] = annotation
1501+ else :
1502+ re_struct [
1503+ self ._item_name_id_map [annotation ["metadata" ]["name" ]]
1504+ ] = annotation
14891505 try :
1490- return [re_struct [x ] for x in self ._item_names if x in re_struct ]
1506+ return [re_struct [x ] for x in self ._items if x in re_struct ]
14911507 except KeyError :
14921508 raise AppException ("Broken data." )
14931509
@@ -1558,18 +1574,28 @@ async def run_workers(
15581574
15591575 def execute (self ):
15601576 if self .is_valid ():
1561- if self ._item_names :
1562- items = get_or_raise (
1563- self ._service_provider .items .list_by_names (
1564- self ._project , self ._folder , self ._item_names
1577+ if self ._items :
1578+ if isinstance (self ._items [0 ], str ):
1579+ items : List [BaseItemEntity ] = get_or_raise (
1580+ self ._service_provider .items .list_by_names (
1581+ self ._project , self ._folder , self ._items
1582+ )
15651583 )
1566- )
1567- len_items , len_provided_items = len (items ), len (self ._item_names )
1584+ else :
1585+ response = self ._service_provider .items .list_by_ids (
1586+ project = self ._project ,
1587+ ids = self ._items ,
1588+ )
1589+ if not response .ok :
1590+ raise AppException (response .error )
1591+ items : List [BaseItemEntity ] = response .data
1592+ self ._item_name_id_map = {i .name : i .id for i in items }
1593+ len_items , len_provided_items = len (items ), len (self ._items )
15681594 if len_items != len_provided_items :
15691595 self .reporter .log_warning (
15701596 f"Could not find annotations for { len_provided_items - len_items } /{ len_provided_items } items."
15711597 )
1572- elif self ._item_names is None :
1598+ elif self ._items is None :
15731599 condition = Condition ("project_id" , self ._project .id , EQ ) & Condition (
15741600 "folder_id" , self ._folder .id , EQ
15751601 )
@@ -1583,7 +1609,7 @@ def execute(self):
15831609 items_count = len (items )
15841610 self .reporter .log_info (
15851611 f"Getting { items_count } annotations from "
1586- f"{ self ._project .name } { f'/{ self ._folder .name } ' if self ._folder .name != 'root' else '' } ."
1612+ f"{ self ._project .name } { f'/{ self ._folder .name } ' if self ._folder and self . _folder .name != 'root' else '' } ."
15871613 )
15881614 id_item_map = {i .id : i for i in items }
15891615 self .reporter .start_progress (
@@ -1602,11 +1628,13 @@ def execute(self):
16021628 try :
16031629 annotations = run_async (self .run_workers (large_items , small_items ))
16041630 except Exception as e :
1631+ # todo remove
1632+ raise e
16051633 logger .error (e )
16061634 self ._response .errors = AppException ("Can't get annotations." )
16071635 return self ._response
16081636 self .reporter .finish_progress ()
1609- self ._response .data = self ._prettify_annotations (annotations )
1637+ self ._response .data = self ._prettify_annotations (annotations ) # noqa
16101638 return self ._response
16111639
16121640
@@ -1634,15 +1662,10 @@ def __init__(
16341662 self ._callback = callback
16351663 self ._big_file_queue = None
16361664
1637- def validate_item_names (self ):
1638- if self ._item_names :
1639- item_names = list (dict .fromkeys (self ._item_names ))
1640- len_unique_items , len_items = len (item_names ), len (self ._item_names )
1641- if len_unique_items < len_items :
1642- self .reporter .log_info (
1643- f"Dropping duplicates. Found { len_unique_items } /{ len_items } unique items."
1644- )
1645- self ._item_names = item_names
1665+ def validate_items (self ):
1666+ self ._item_names = GetAnnotations .items_duplication_validation (
1667+ self .reporter , self ._item_names
1668+ )
16461669
16471670 @property
16481671 def destination (self ) -> str :
0 commit comments