Skip to content

Commit b46054a

Browse files
authored
Merge pull request #45 from superannotateai/SAS-3457
assign images by chunk
2 parents 222b78d + 29bdb34 commit b46054a

File tree

2 files changed

+135
-113
lines changed

2 files changed

+135
-113
lines changed

superannotate/db/project_images.py

Lines changed: 60 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -21,20 +21,21 @@
2121
)
2222
from .teams import get_team_metadata
2323
from ..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

2627
logger = logging.getLogger("superannotate-python-sdk")
2728
_api = API.get_instance()
2829

2930

3031
@Trackable
3132
def 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

138139
def _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
194195
def 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
309310
def 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
374375
def 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

442443
def _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
481482
def 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,40 +566,28 @@ 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
logging.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-
)
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)
602591

603592
@Trackable
604593
def assign_folder(project, folder_name, users):
@@ -614,9 +603,9 @@ 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

@@ -626,6 +615,9 @@ def assign_folder(project, folder_name, users):
626615
)
627616
continue
628617

618+
if not verified_users:
619+
return
620+
629621
params = {
630622
"project_id": project_meta['id'],
631623
"team_id": project_meta["team_id"]
@@ -689,27 +681,12 @@ def unassign_images(project, image_names):
689681
:type image_names: list of str
690682
"""
691683
project, folder = get_project_and_folder_metadata(project)
684+
692685
folder_name = 'root'
693686
if folder:
694687
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-
)
688+
if not image_names:
689+
return
690+
logs = _unassign_images(folder_name=folder_name,image_names=image_names,project_id=project['id'],team_id=project['team_id'])
691+
for log in logs:
692+
logger.warn(log)

0 commit comments

Comments
 (0)