@@ -1097,12 +1097,15 @@ def download_image_annotations(
10971097 :rtype: tuple
10981098 """
10991099
1100- project , folder = self .controller .get_project_folder_by_path (project )
1100+ project_name , folder_name = extract_project_folder (project )
1101+ project = self .controller .get_project (project_name )
1102+ folder = project .get_folder (folder_name )
1103+ download_path = self .controller .setup_destination_dir (local_dir_path )
11011104 res = self .controller .annotations .download_image_annotations (
11021105 project = project ,
11031106 folder = folder ,
11041107 image_name = image_name ,
1105- destination = local_dir_path ,
1108+ destination = download_path ,
11061109 )
11071110 if res .errors :
11081111 raise AppException (res .errors )
@@ -1709,17 +1712,67 @@ def upload_annotations(
17091712 }
17101713
17111714 """
1712- project , folder = self .controller .get_project_folder_by_path (project )
1713- response = self .controller .annotations .upload_multiple (
1714- project = project ,
1715- folder = folder ,
1716- annotations = annotations ,
1717- keep_status = keep_status ,
1718- user = self .controller .current_user ,
1715+ project_name , folder_name = extract_project_folder (project )
1716+ project = self .controller .get_project (project_name )
1717+ folder = project .get_folder (folder_name )
1718+
1719+ failed , skipped = [], []
1720+ name_annotation_map = {}
1721+ for annotation in annotations :
1722+ try :
1723+ name = annotation ["metadata" ]["name" ]
1724+ name_annotation_map [name ] = annotation
1725+ except KeyError :
1726+ failed .append (annotation )
1727+ logger .info (
1728+ f"Uploading { len (name_annotation_map )} /{ len (annotations )} "
1729+ f"annotations to the project { project .name } ."
17191730 )
1720- if response .errors :
1721- raise AppException (response .errors )
1722- return response .data
1731+
1732+ folder_items = folder .list_items (item_names = list (name_annotation_map .keys ()))
1733+ name_item_map = {i .name : i for i in folder_items }
1734+ len_existing , len_provided = len (folder_items ), len (name_annotation_map )
1735+ if len_existing < len_provided :
1736+ logger .warning (
1737+ f"Couldn't find { len_provided - len_existing } /{ len_provided } "
1738+ "items in the given directory that match the annotations."
1739+ )
1740+ item_id_annotation_pairs : List [Tuple [int , dict ]] = []
1741+ item_id_name_map = {}
1742+ for annotation_name , annotation in name_annotation_map .items ():
1743+ item = name_item_map .get (annotation_name )
1744+ if item :
1745+ # Verifies value is not NaN for data integrity
1746+ try :
1747+ json .dumps (annotation , allow_nan = False )
1748+ except ValueError :
1749+ failed .append (annotation_name )
1750+ continue
1751+
1752+ item_id_annotation_pairs .append ((item .id , annotation ))
1753+ item_id_name_map [item .id ] = annotation_name
1754+ else :
1755+ skipped .append (annotation_name )
1756+
1757+ failed_ids = folder .upload_annotations (item_id_annotation_pairs )
1758+ failed .extend (item_id_name_map [i ] for i in failed_ids )
1759+ uploaded_annotations = list (
1760+ set (item_id_name_map .values ()) - set (failed ).union (set (skipped ))
1761+ )
1762+ if uploaded_annotations and not keep_status :
1763+ try :
1764+ folder .set_items_annotation_statuses (
1765+ items = uploaded_annotations ,
1766+ annotation_status = constants .AnnotationStatus .IN_PROGRESS ,
1767+ )
1768+ except Exception :
1769+ raise AppException ("Failed to change status." )
1770+
1771+ return {
1772+ "succeeded" : uploaded_annotations ,
1773+ "failed" : failed ,
1774+ "skipped" : skipped ,
1775+ }
17231776
17241777 def upload_annotations_from_folder_to_project (
17251778 self ,
@@ -1761,6 +1814,8 @@ def upload_annotations_from_folder_to_project(
17611814 """
17621815
17631816 project_name , folder_name = extract_project_folder (project )
1817+ project = self .controller .get_project (project_name )
1818+ folder = project .get_folder (folder_name )
17641819 project_folder_name = project_name + (f"/{ folder_name } " if folder_name else "" )
17651820
17661821 if recursive_subfolders :
@@ -1780,11 +1835,9 @@ def upload_annotations_from_folder_to_project(
17801835 logger .info (
17811836 f"Uploading { len (annotation_paths )} annotations from { folder_path } to the project { project_folder_name } ."
17821837 )
1783- project , folder = self .controller .get_project_folder (project_name , folder_name )
17841838 response = self .controller .annotations .upload_from_folder (
17851839 project = project ,
17861840 folder = folder ,
1787- user = self .controller .current_user ,
17881841 annotation_paths = annotation_paths , # noqa: E203
17891842 client_s3_bucket = from_s3_bucket ,
17901843 folder_path = folder_path ,
@@ -1828,8 +1881,8 @@ def upload_image_annotations(
18281881 """
18291882
18301883 project_name , folder_name = extract_project_folder (project )
1831-
1832- project = self . controller . projects . get_by_name ( project_name ). data
1884+ project = self . controller . get_project ( project_name )
1885+ folder = project . get_folder ( folder_name )
18331886 if project .type not in constants .ProjectType .images :
18341887 raise AppException (LIMITED_FUNCTIONS [project .type ])
18351888
@@ -1848,7 +1901,6 @@ def upload_image_annotations(
18481901 if verbose :
18491902 logger .info ("Uploading annotations from %s." , annotation_json )
18501903 annotation_json = json .load (open (annotation_json ))
1851- folder = self .controller .get_folder (project , folder_name )
18521904 if not folder :
18531905 raise AppException ("Folder not found." )
18541906
0 commit comments