@@ -179,17 +179,13 @@ def create_project(project_name: str, project_description: str, project_type: st
179179 :return: dict object metadata the new project
180180 :rtype: dict
181181 """
182- projects = controller .search_project (name = project_name ).data
183- if projects :
184- raise AppException (
185- f"Project with name { project_name } already exists."
186- f" Please use unique names for projects to use with SDK."
187- )
188-
189- result = controller .create_project (
182+ response = controller .create_project (
190183 name = project_name , description = project_description , project_type = project_type
191- ).data
192- return ProjectSerializer (result ).serialize ()
184+ )
185+ if response .errors :
186+ raise Exception (response .errors )
187+
188+ return ProjectSerializer (response .data ).serialize ()
193189
194190
195191@Trackable
@@ -672,6 +668,8 @@ def _upload_image(image_url, image_path) -> ProcessedImage:
672668 else :
673669 failed_images .append (processed_image )
674670
671+ logger .info ("Downloading %s images" , len (images_to_upload ))
672+
675673 for i in range (0 , len (images_to_upload ), 500 ):
676674 controller .upload_images (
677675 project_name = project_name ,
@@ -886,7 +884,9 @@ def get_project_settings(project: Union[str, dict]):
886884 """
887885 project_name , folder_name = extract_project_folder (project )
888886 settings = controller .get_project_settings (project_name = project_name )
889- settings = [BaseSerializers (attribute ).serialize () for attribute in settings .data ]
887+ settings = [
888+ SettingsSerializer (attribute ).serialize () for attribute in settings .data
889+ ]
890890 return settings
891891
892892
@@ -1099,6 +1099,9 @@ def delete_images(project: Union[str, dict], image_names: Optional[List[str]] =
10991099 """
11001100 project_name , folder_name = extract_project_folder (project )
11011101
1102+ if not isinstance (image_names , list ) and image_names is not None :
1103+ raise AppValidationException ("Image_names should be a list of strs or None." )
1104+
11021105 response = controller .delete_images (
11031106 project_name = project_name , folder_name = folder_name , image_names = image_names
11041107 )
@@ -1143,9 +1146,6 @@ def assign_images(project: Union[str, dict], image_names: List[str], user: str):
11431146 logger .warning (
11441147 f"Skipping { user } . { user } is not a verified contributor for the { project_name } "
11451148 )
1146-
1147-
1148-
11491149 return
11501150
11511151 controller .assign_images (project_name , folder_name , image_names , user )
@@ -1204,9 +1204,27 @@ def assign_folder(project_name: str, folder_name: str, users: List[str]):
12041204 :param users: list of user emails
12051205 :type users: list of str
12061206 """
1207+
1208+ contributors = (
1209+ controller .get_project_metadata (
1210+ project_name = project_name , include_contributors = True
1211+ )
1212+ .data ["project" ]
1213+ .users
1214+ )
1215+ verified_users = [i ["user_id" ] for i in contributors ]
1216+ verified_users = set (users ).intersection (set (verified_users ))
1217+ unverified_contributor = set (users ) - verified_users
1218+
1219+ for user in unverified_contributor :
1220+ logger .warning (
1221+ f"Skipping { user } from assignees. { user } is not a verified contributor for the { project_name } "
1222+ )
1223+
12071224 response = controller .assign_folder (
1208- project_name = project_name , folder_name = folder_name , users = users
1225+ project_name = project_name , folder_name = folder_name , users = list ( verified_users )
12091226 )
1227+
12101228 if response .errors :
12111229 raise AppException (response .errors )
12121230
@@ -1226,10 +1244,15 @@ def share_project(project_name: str, user: Union[str, dict], user_role: str):
12261244 if isinstance (user , dict ):
12271245 user_id = user ["id" ]
12281246 else :
1229- user_id = controller .search_team_contributors (email = user ).data [0 ]["id" ]
1230- controller .share_project (
1247+ response = controller .search_team_contributors (email = user )
1248+ if not response .data :
1249+ raise AppException (f"User { user } not found." )
1250+ user_id = response .data [0 ]["id" ]
1251+ response = controller .share_project (
12311252 project_name = project_name , user_id = user_id , user_role = user_role
12321253 )
1254+ if response .errors :
1255+ raise AppException (response .errors )
12331256
12341257
12351258@Trackable
@@ -1814,6 +1837,9 @@ def upload_videos_from_folder_to_project(
18141837 if os .name != "nt" :
18151838 video_paths += list (Path (folder_path ).glob (f"*.{ extension .upper ()} " ))
18161839 else :
1840+ logger .warning (
1841+ "When using recursive subfolder parsing same name videos in different subfolders will overwrite each other."
1842+ )
18171843 video_paths += list (Path (folder_path ).rglob (f"*.{ extension .lower ()} " ))
18181844 if os .name != "nt" :
18191845 video_paths += list (Path (folder_path ).rglob (f"*.{ extension .upper ()} " ))
@@ -1824,6 +1850,14 @@ def upload_videos_from_folder_to_project(
18241850 if all (not_in_exclude_list ):
18251851 filtered_paths .append (path )
18261852
1853+ logger .info (
1854+ "Uploading all videos with extensions %s from %s to project %s. Excluded file patterns are: %s." ,
1855+ extensions ,
1856+ str (folder_path ),
1857+ project_name ,
1858+ exclude_file_patterns ,
1859+ )
1860+
18271861 uploaded_images , failed_images = [], []
18281862 for path in tqdm (video_paths ):
18291863 with tempfile .TemporaryDirectory () as temp_path :
@@ -2173,6 +2207,7 @@ def _upload_file_to_s3(to_s3_bucket, path, s3_key) -> None:
21732207
21742208 for future in concurrent .futures .as_completed (results ):
21752209 future .result ()
2210+ logger .info ("Exported to AWS %s/%s" , to_s3_bucket , str (path ))
21762211
21772212
21782213@Trackable
@@ -2569,6 +2604,7 @@ def upload_image_annotations(
25692604 image_name = image_name ,
25702605 annotations = annotation_json ,
25712606 mask = mask ,
2607+ verbose = verbose ,
25722608 )
25732609 if response .errors :
25742610 raise AppValidationException (response .errors )
@@ -3485,6 +3521,9 @@ def _upload_s3_image(image_path: str):
34853521 progress_bar .update (1 )
34863522 uploaded = []
34873523 duplicates = []
3524+
3525+ logger .info ("Uploading %s images to project." , len (images_to_upload ))
3526+
34883527 for i in range (0 , len (uploaded_image_entities ), 500 ):
34893528 response = controller .upload_images (
34903529 project_name = project_name ,
@@ -3496,6 +3535,11 @@ def _upload_s3_image(image_path: str):
34963535 uploaded .extend (attachments )
34973536 duplicates .extend (duplications )
34983537
3538+ if len (duplicates ):
3539+ logger .warning (
3540+ "%s already existing images found that won't be uploaded." , len (duplicates )
3541+ )
3542+
34993543 return uploaded , failed_images , duplicates
35003544
35013545
0 commit comments