11import logging
22
3- from .endpoint import QuerysetEndpoint , api
4- from .exceptions import MissingRequiredFieldError
3+ from tableauserverclient . server . endpoint .endpoint import QuerysetEndpoint , api
4+ from tableauserverclient . server . endpoint .exceptions import MissingRequiredFieldError
55from tableauserverclient .server import RequestFactory
66from tableauserverclient .models import GroupItem , UserItem , PaginationItem , JobItem
7- from . .pager import Pager
7+ from tableauserverclient . server .pager import Pager
88
99from tableauserverclient .helpers .logging import logger
1010
11- from typing import List , Optional , TYPE_CHECKING , Tuple , Union
11+ from typing import Iterable , List , Optional , TYPE_CHECKING , Tuple , Union
1212
1313if TYPE_CHECKING :
14- from . .request_options import RequestOptions
14+ from tableauserverclient . server .request_options import RequestOptions
1515
1616
1717class Groups (QuerysetEndpoint [GroupItem ]):
1818 @property
1919 def baseurl (self ) -> str :
2020 return "{0}/sites/{1}/groups" .format (self .parent_srv .baseurl , self .parent_srv .site_id )
2121
22- # Gets all groups
2322 @api (version = "2.0" )
2423 def get (self , req_options : Optional ["RequestOptions" ] = None ) -> Tuple [List [GroupItem ], PaginationItem ]:
24+ """Gets all groups"""
2525 logger .info ("Querying all groups on site" )
2626 url = self .baseurl
2727 server_response = self .get_request (url , req_options )
2828 pagination_item = PaginationItem .from_response (server_response .content , self .parent_srv .namespace )
2929 all_group_items = GroupItem .from_response (server_response .content , self .parent_srv .namespace )
3030 return all_group_items , pagination_item
3131
32- # Gets all users in a given group
3332 @api (version = "2.0" )
34- def populate_users (self , group_item , req_options : Optional ["RequestOptions" ] = None ) -> None :
33+ def populate_users (self , group_item : GroupItem , req_options : Optional ["RequestOptions" ] = None ) -> None :
34+ """Gets all users in a given group"""
3535 if not group_item .id :
3636 error = "Group item missing ID. Group must be retrieved from server first."
3737 raise MissingRequiredFieldError (error )
@@ -47,7 +47,7 @@ def user_pager():
4747 group_item ._set_users (user_pager )
4848
4949 def _get_users_for_group (
50- self , group_item , req_options : Optional ["RequestOptions" ] = None
50+ self , group_item : GroupItem , req_options : Optional ["RequestOptions" ] = None
5151 ) -> Tuple [List [UserItem ], PaginationItem ]:
5252 url = "{0}/{1}/users" .format (self .baseurl , group_item .id )
5353 server_response = self .get_request (url , req_options )
@@ -56,9 +56,9 @@ def _get_users_for_group(
5656 logger .info ("Populated users for group (ID: {0})" .format (group_item .id ))
5757 return user_item , pagination_item
5858
59- # Deletes 1 group by id
6059 @api (version = "2.0" )
6160 def delete (self , group_id : str ) -> None :
61+ """Deletes 1 group by id"""
6262 if not group_id :
6363 error = "Group ID undefined."
6464 raise ValueError (error )
@@ -87,17 +87,17 @@ def update(self, group_item: GroupItem, as_job: bool = False) -> Union[GroupItem
8787 else :
8888 return GroupItem .from_response (server_response .content , self .parent_srv .namespace )[0 ]
8989
90- # Create a 'local' Tableau group
9190 @api (version = "2.0" )
9291 def create (self , group_item : GroupItem ) -> GroupItem :
92+ """Create a 'local' Tableau group"""
9393 url = self .baseurl
9494 create_req = RequestFactory .Group .create_local_req (group_item )
9595 server_response = self .post_request (url , create_req )
9696 return GroupItem .from_response (server_response .content , self .parent_srv .namespace )[0 ]
9797
98- # Create a group based on Active Directory
9998 @api (version = "2.0" )
10099 def create_AD_group (self , group_item : GroupItem , asJob : bool = False ) -> Union [GroupItem , JobItem ]:
100+ """Create a group based on Active Directory"""
101101 asJobparameter = "?asJob=true" if asJob else ""
102102 url = self .baseurl + asJobparameter
103103 create_req = RequestFactory .Group .create_ad_req (group_item )
@@ -107,9 +107,9 @@ def create_AD_group(self, group_item: GroupItem, asJob: bool = False) -> Union[G
107107 else :
108108 return GroupItem .from_response (server_response .content , self .parent_srv .namespace )[0 ]
109109
110- # Removes 1 user from 1 group
111110 @api (version = "2.0" )
112111 def remove_user (self , group_item : GroupItem , user_id : str ) -> None :
112+ """Removes 1 user from 1 group"""
113113 if not group_item .id :
114114 error = "Group item missing ID."
115115 raise MissingRequiredFieldError (error )
@@ -120,9 +120,22 @@ def remove_user(self, group_item: GroupItem, user_id: str) -> None:
120120 self .delete_request (url )
121121 logger .info ("Removed user (id: {0}) from group (ID: {1})" .format (user_id , group_item .id ))
122122
123- # Adds 1 user to 1 group
123+ @api (version = "3.21" )
124+ def remove_users (self , group_item : GroupItem , users : Iterable [Union [str , UserItem ]]) -> None :
125+ """Removes multiple users from 1 group"""
126+ group_id = group_item .id if hasattr (group_item , "id" ) else group_item
127+ if not isinstance (group_id , str ):
128+ raise ValueError (f"Invalid group provided: { group_item } " )
129+
130+ url = f"{ self .baseurl } /{ group_id } /users/remove"
131+ add_req = RequestFactory .Group .remove_users_req (users )
132+ _ = self .put_request (url , add_req )
133+ logger .info ("Removed users to group (ID: {0})" .format (group_item .id ))
134+ return None
135+
124136 @api (version = "2.0" )
125137 def add_user (self , group_item : GroupItem , user_id : str ) -> UserItem :
138+ """Adds 1 user to 1 group"""
126139 if not group_item .id :
127140 error = "Group item missing ID."
128141 raise MissingRequiredFieldError (error )
@@ -135,3 +148,17 @@ def add_user(self, group_item: GroupItem, user_id: str) -> UserItem:
135148 user = UserItem .from_response (server_response .content , self .parent_srv .namespace ).pop ()
136149 logger .info ("Added user (id: {0}) to group (ID: {1})" .format (user_id , group_item .id ))
137150 return user
151+
152+ @api (version = "3.21" )
153+ def add_users (self , group_item : GroupItem , users : Iterable [Union [str , UserItem ]]) -> List [UserItem ]:
154+ """Adds multiple users to 1 group"""
155+ group_id = group_item .id if hasattr (group_item , "id" ) else group_item
156+ if not isinstance (group_id , str ):
157+ raise ValueError (f"Invalid group provided: { group_item } " )
158+
159+ url = f"{ self .baseurl } /{ group_id } /users"
160+ add_req = RequestFactory .Group .add_users_req (users )
161+ server_response = self .post_request (url , add_req )
162+ users = UserItem .from_response (server_response .content , self .parent_srv .namespace )
163+ logger .info ("Added users to group (ID: {0})" .format (group_item .id ))
164+ return users
0 commit comments