Skip to content

Commit 99fdf2a

Browse files
committed
Add remove_users/remove_users_from_project methods
1 parent 5ed4313 commit 99fdf2a

File tree

6 files changed

+104
-1
lines changed

6 files changed

+104
-1
lines changed

docs/source/api_reference/api_project.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,3 +30,4 @@ Projects
3030
.. automethod:: superannotate.SAClient.create_categories
3131
.. automethod:: superannotate.SAClient.list_categories
3232
.. automethod:: superannotate.SAClient.remove_categories
33+
.. automethod:: superannotate.SAClient.remove_users_from_project

docs/source/api_reference/api_team.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ Team
1111
.. automethod:: superannotate.SAClient.get_user_metadata
1212
.. automethod:: superannotate.SAClient.set_user_custom_field
1313
.. automethod:: superannotate.SAClient.list_users
14+
.. automethod:: superannotate.SAClient.remove_users
1415
.. automethod:: superannotate.SAClient.pause_user_activity
1516
.. automethod:: superannotate.SAClient.resume_user_activity
1617
.. automethod:: superannotate.SAClient.get_user_scores

src/superannotate/lib/app/interface/sdk_interface.py

Lines changed: 66 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,6 @@
7575
from lib.core.jsx_conditions import EmptyQuery
7676
from lib.core.entities.items import ProjectCategoryEntity
7777

78-
7978
logger = logging.getLogger("sa")
8079

8180
NotEmptyStr = constr(strict=True, min_length=1)
@@ -5337,3 +5336,69 @@ def list_workflows(self):
53375336
EmptyQuery()
53385337
)
53395338
return BaseSerializer.serialize_iterable(workflows.data)
5339+
5340+
def remove_users(self, users: Union[List[int], List[str]]):
5341+
"""
5342+
Allows removing users from the team.
5343+
:param users: A list of emails or IDs of the users.
5344+
:type users: Union[List[int], List[str]]
5345+
5346+
:rtype: None:
5347+
5348+
Request Example:
5349+
::
5350+
5351+
SAClient.remove_users(member=["example@gmail.com","example1@gmail.com"])
5352+
5353+
"""
5354+
success = 0
5355+
if users:
5356+
if isinstance(users[0], int):
5357+
users = self.controller.work_management.list_users(id__in=users)
5358+
user_emails = [user.email for user in users]
5359+
else:
5360+
user_emails = users
5361+
if user_emails:
5362+
success, _ = self.controller.work_management.remove_users(user_emails)
5363+
logger.info(
5364+
f"Successfully removed {success} user(s) out of the {len(users)} provided."
5365+
)
5366+
5367+
def remove_users_from_project(
5368+
self, project: Union[NotEmptyStr, int], users: Union[List[int], List[str]]
5369+
):
5370+
"""
5371+
Allows removing users from the team.
5372+
5373+
:param project: The name or ID of the project.
5374+
:type project: Union[NotEmptyStr, int]
5375+
5376+
:param users: A list of emails or IDs of the users.
5377+
:type users: Union[List[int], List[str]]
5378+
5379+
:rtype: None:
5380+
5381+
Request Example:
5382+
::
5383+
5384+
SAClient.remove_users_from_project(project="Test Project", users=["example@gmail.com","example1@gmail.com"])
5385+
5386+
"""
5387+
project = self.controller.get_project(project)
5388+
5389+
success = 0
5390+
if users:
5391+
if isinstance(users[0], int):
5392+
users = self.controller.work_management.list_users(
5393+
project=project, id__in=users
5394+
)
5395+
user_emails = [user.email for user in users]
5396+
else:
5397+
user_emails = users
5398+
if user_emails:
5399+
success, _ = self.controller.work_management.remove_users_from_project(
5400+
project, user_emails
5401+
)
5402+
logger.info(
5403+
f"Successfully removed {success} users(s) out of the {len(users)} provided from the project {project.name}."
5404+
)

src/superannotate/lib/core/serviceproviders.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -931,3 +931,11 @@ def get_custom_fields_templates(
931931
parent: CustomFieldEntityEnum,
932932
):
933933
raise NotImplementedError
934+
935+
@abstractmethod
936+
def remove_users(self, emails: List[str]):
937+
raise NotImplementedError
938+
939+
@abstractmethod
940+
def remove_users_from_project(self, project_id: int, emails: List[str]):
941+
raise NotImplementedError

src/superannotate/lib/infrastructure/controller.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,14 @@ def set_custom_field_value(
177177
context=_context,
178178
)
179179

180+
def remove_users(self, user_emails: List[str]):
181+
data = self.service_provider.remove_users(user_emails)
182+
return data.get("success", 0), data.get("error", 0)
183+
184+
def remove_users_from_project(self, project: ProjectEntity, user_emails: List[str]):
185+
data = self.service_provider.remove_users_from_project(project.id, user_emails)
186+
return len(data.get("succeeded", [])), len(data.get("failed", []))
187+
180188
def list_users(
181189
self,
182190
include: List[Literal["custom_fields", "categories"]] = None,

src/superannotate/lib/infrastructure/serviceprovider.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ class ServiceProvider(BaseServiceProvider):
4141
URL_INVITE_CONTRIBUTORS = "api/v1/team/{}/inviteUsers"
4242
URL_ANNOTATION_UPLOAD_PATH_TOKEN = "images/getAnnotationsPathsAndTokens"
4343
URL_CREATE_WORKFLOW = "api/v1/workflows/submit"
44+
URL_REMOVE_USERS_FROM_TEAM = "team/{team_id}/members/bulk"
45+
URL_REMOVE_USERS_FROM_PROJECT = "project/{project_id}/share/bulk"
4446

4547
def __init__(self, client: HttpClient):
4648
self.enum_mapping = {"approval_status": ApprovalStatus.get_mapping()}
@@ -339,3 +341,21 @@ def create_custom_workflow(self, org_id: str, data: dict):
339341
},
340342
data=data,
341343
)
344+
345+
def remove_users(self, emails: List[str]):
346+
response = self.client.request(
347+
url=self.URL_REMOVE_USERS_FROM_TEAM.format(team_id=self.client.team_id),
348+
method="delete",
349+
data={"data": [{"email": email} for email in emails]},
350+
)
351+
response.raise_for_status()
352+
return response.data
353+
354+
def remove_users_from_project(self, project_id: int, emails: List[str]):
355+
response = self.client.request(
356+
url=self.URL_REMOVE_USERS_FROM_PROJECT.format(project_id=project_id),
357+
method="delete",
358+
data={"user_id": emails},
359+
)
360+
response.raise_for_status()
361+
return response.data

0 commit comments

Comments
 (0)