2121)
2222from .teams import get_team_metadata
2323from ..mixp .decorators import Trackable
24- from .utils import _get_upload_auth_token , _get_boto_session_by_credentials , upload_image_array_to_s3 , get_image_array_to_upload , __create_image , __copy_images , __move_images , get_project_folder_string
24+ from .utils import _unassign_images , _assign_images , _get_upload_auth_token , _get_boto_session_by_credentials , upload_image_array_to_s3 , \
25+ get_image_array_to_upload , __create_image , __copy_images , __move_images , get_project_folder_string
2526
2627logger = logging .getLogger ("superannotate-python-sdk" )
2728_api = API .get_instance ()
2829
2930
3031@Trackable
3132def upload_image_to_project (
32- project ,
33- img ,
34- image_name = None ,
35- annotation_status = "NotStarted" ,
36- from_s3_bucket = None ,
37- image_quality_in_editor = None
33+ project ,
34+ img ,
35+ image_name = None ,
36+ annotation_status = "NotStarted" ,
37+ from_s3_bucket = None ,
38+ image_quality_in_editor = None
3839):
3940 """Uploads image (io.BytesIO() or filepath to image) to project.
4041 Sets status of the uploaded image to set_status if it is not None.
@@ -136,8 +137,8 @@ def upload_image_to_project(
136137
137138
138139def _copy_images (
139- source_project , destination_project , image_names , include_annotations ,
140- copy_annotation_status , copy_pin
140+ source_project , destination_project , image_names , include_annotations ,
141+ copy_annotation_status , copy_pin
141142):
142143 NUM_TO_SEND = 500
143144 source_project , source_project_folder = source_project
@@ -166,7 +167,7 @@ def _copy_images(
166167 res ['completed' ] = []
167168 for start_index in range (0 , len (image_names ), NUM_TO_SEND ):
168169 json_req ["image_names" ] = image_names [start_index :start_index +
169- NUM_TO_SEND ]
170+ NUM_TO_SEND ]
170171 response = _api .send_request (
171172 req_type = 'POST' ,
172173 path = '/image/copy' ,
@@ -192,12 +193,12 @@ def _copy_images(
192193
193194@Trackable
194195def copy_images (
195- source_project ,
196- image_names ,
197- destination_project ,
198- include_annotations = True ,
199- copy_annotation_status = True ,
200- copy_pin = True
196+ source_project ,
197+ image_names ,
198+ destination_project ,
199+ include_annotations = True ,
200+ copy_annotation_status = True ,
201+ copy_pin = True
201202):
202203 """Copy images in bulk between folders in a project
203204
@@ -307,12 +308,12 @@ def delete_images(project, image_names):
307308
308309@Trackable
309310def move_images (
310- source_project ,
311- image_names ,
312- destination_project ,
313- include_annotations = True ,
314- copy_annotation_status = True ,
315- copy_pin = True ,
311+ source_project ,
312+ image_names ,
313+ destination_project ,
314+ include_annotations = True ,
315+ copy_annotation_status = True ,
316+ copy_pin = True ,
316317):
317318 """Move images in bulk between folders in a project
318319
@@ -372,12 +373,12 @@ def move_images(
372373
373374@Trackable
374375def copy_image (
375- source_project ,
376- image_name ,
377- destination_project ,
378- include_annotations = False ,
379- copy_annotation_status = False ,
380- copy_pin = False
376+ source_project ,
377+ image_name ,
378+ destination_project ,
379+ include_annotations = False ,
380+ copy_annotation_status = False ,
381+ copy_pin = False
381382):
382383 """Copy image to a project. The image's project is the same as destination
383384 project then the name will be changed to <image_name>_(<num>).<image_ext>,
@@ -417,10 +418,10 @@ def copy_image(
417418 else :
418419 for m in p .finditer (new_name ):
419420 if m .start () + len (m .group ()
420- ) + len (extension ) - 1 == len (new_name ):
421+ ) + len (extension ) - 1 == len (new_name ):
421422 num = int (m .group ()[2 :- 2 ])
422423 new_name = new_name [:m .start () +
423- 2 ] + str (num + 1 ) + ")" + extension
424+ 2 ] + str (num + 1 ) + ")" + extension
424425 break
425426 else :
426427 new_name = Path (new_name ).stem + "_(1)" + extension
@@ -440,9 +441,9 @@ def copy_image(
440441
441442
442443def _copy_annotations_and_metadata (
443- source_project , source_project_folder , image_name , destination_project ,
444- destination_project_folder , new_name , include_annotations ,
445- copy_annotation_status , copy_pin
444+ source_project , source_project_folder , image_name , destination_project ,
445+ destination_project_folder , new_name , include_annotations ,
446+ copy_annotation_status , copy_pin
446447):
447448 if include_annotations :
448449 annotations = get_image_annotations (
@@ -479,12 +480,12 @@ def _copy_annotations_and_metadata(
479480
480481@Trackable
481482def move_image (
482- source_project ,
483- image_name ,
484- destination_project ,
485- include_annotations = True ,
486- copy_annotation_status = True ,
487- copy_pin = True
483+ source_project ,
484+ image_name ,
485+ destination_project ,
486+ include_annotations = True ,
487+ copy_annotation_status = True ,
488+ copy_pin = True
488489):
489490 """Move image from source_project to destination_project. source_project
490491 and destination_project cannot be the same.
@@ -565,42 +566,30 @@ def assign_images(project, image_names, user):
565566 :param user: user email
566567 :type user: str
567568 """
568- logger .info ("Assign %s images to user %s" , len (image_names ), user )
569569 if len (image_names ) == 0 :
570570 return
571571
572572 project , folder = get_project_and_folder_metadata (project )
573-
574- verified_users = get_team_metadata ()[ "users " ]
575- verified_users = [i ['id ' ] for i in verified_users ]
573+ project_meta = get_project_metadata ( project , include_contributors = True )
574+ verified_users = project_meta [ "contributors " ]
575+ verified_users = [i ['user_id ' ] for i in verified_users ]
576576 if user not in verified_users :
577577 logger .warn (
578578 f'Skipping { user } . { user } is not a verified contributor for the { project ["name" ]} '
579579 )
580+ return
580581
581582 folder_name = 'root'
582583 if folder :
583584 folder_name = folder ['name' ]
584585
585- params = {"project_id" : project ['id' ], "team_id" : project ["team_id" ]}
586- json_req = {
587- "image_names" : image_names ,
588- "assign_user_id" : user ,
589- "folder_name" : folder_name ,
590- }
591- response = _api .send_request (
592- req_type = 'PUT' ,
593- path = '/images/editAssignment' ,
594- params = params ,
595- json_req = json_req
596- )
597-
598- if not response .ok :
599- raise SABaseException (
600- response .status_code , "Couldn't assign images " + response .text
601- )
602-
586+ logs = _assign_images (folder_name = folder_name , image_names = image_names , user = user , project_id = project ['id' ],
587+ team_id = project ['team_id' ])
588+ for log in logs :
589+ logger .warn (log )
590+ logger .info ("Assign images to user %s" , user )
603591
592+ @Trackable
604593def assign_folder (project , folder_name , users ):
605594 """Assigns folder to users. With SDK, the user can be
606595 assigned to a role in the project with the share_project function.
@@ -614,17 +603,19 @@ def assign_folder(project, folder_name, users):
614603 """
615604
616605 project_meta = get_project_metadata (project , include_contributors = True )
617- verified_users = get_team_metadata ()["users" ]
606+ verified_users = project_meta ["contributors" ]
607+ verified_users = [i ['user_id' ] for i in verified_users ]
618608 project_name = project_meta ['name' ]
619- verified_users = [i ['id' ] for i in verified_users ]
620609 verified_users = set (users ).intersection (set (verified_users ))
621610 unverified_contributor = set (users ) - verified_users
622611
623612 for user in unverified_contributor :
624613 logger .warn (
625614 f'Skipping { user } from assignees. { user } is not a verified contributor for the { project_name } '
626615 )
627- continue
616+
617+ if not verified_users :
618+ return
628619
629620 params = {
630621 "project_id" : project_meta ['id' ],
@@ -647,7 +638,7 @@ def assign_folder(project, folder_name, users):
647638 )
648639 logger .info (f'Assigned { folder_name } to users: { list (verified_users )} ' )
649640
650-
641+ @ Trackable
651642def unassign_folder (project , folder_name ):
652643 """Removes assignment of given folder for all assignees.
653644 With SDK, the user can be assigned to a role in the project
@@ -677,7 +668,7 @@ def unassign_folder(project, folder_name):
677668 response .status_code , "Couldn't unassign folder " + response .text
678669 )
679670
680-
671+ @ Trackable
681672def unassign_images (project , image_names ):
682673 """Removes assignment of given images for all assignees.With SDK,
683674 the user can be assigned to a role in the project with the share_project
@@ -688,28 +679,13 @@ def unassign_images(project, image_names):
688679 :param image_names: list of image unassign
689680 :type image_names: list of str
690681 """
682+ if not image_names :
683+ return
691684 project , folder = get_project_and_folder_metadata (project )
685+
692686 folder_name = 'root'
693687 if folder :
694688 folder_name = folder ['name' ]
695- params = {
696- "project_id" : project ['id' ],
697- "team_id" : project ["team_id" ]
698- }
699- json_req = {
700- "image_names" : image_names ,
701- "remove_user_ids" : ["all" ],
702- "folder_name" : folder_name
703- }
704-
705- response = _api .send_request (
706- req_type = 'PUT' ,
707- path = '/images/editAssignment' ,
708- params = params ,
709- json_req = json_req
710- )
711-
712- if not response .ok :
713- raise SABaseException (
714- response .status_code , "Couldn't unassign images " + response .text
715- )
689+ logs = _unassign_images (folder_name = folder_name ,image_names = image_names ,project_id = project ['id' ],team_id = project ['team_id' ])
690+ for log in logs :
691+ logger .warn (log )
0 commit comments