Skip to content

Commit 711c402

Browse files
committed
Add user.groups.add(group), user.groups.delete(group), group.members.add(user), and group.members.delete(user)
1 parent 5051cf4 commit 711c402

File tree

2 files changed

+314
-3
lines changed

2 files changed

+314
-3
lines changed

src/posit/connect/groups.py

Lines changed: 174 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
from __future__ import annotations
44

5-
from typing import TYPE_CHECKING, List, overload
5+
from typing import TYPE_CHECKING, List, Optional, overload
66

77
from .paginator import Paginator
88
from .resources import Resource, Resources
@@ -32,16 +32,36 @@ def members(self) -> GroupMembers:
3232
Examples
3333
--------
3434
```python
35+
from posit.connect import Client
36+
37+
client = Client("https://posit.example.com", "API_KEY")
38+
3539
group = client.groups.get("GROUP_GUID_HERE")
3640
group_users = group.members.find()
41+
42+
# Get count of group members
3743
group_user_count = group.members.count()
3844
```
3945
4046
"""
4147
return GroupMembers(self._ctx, group_guid=self["guid"])
4248

4349
def delete(self) -> None:
44-
"""Delete the group."""
50+
"""Delete the group.
51+
52+
Examples
53+
--------
54+
```python
55+
from posit.connect import Client
56+
57+
client = Client("https://posit.example.com", "API_KEY")
58+
59+
group = client.groups.get("GROUP_GUID_HERE")
60+
61+
# Delete the group
62+
group.delete()
63+
```
64+
"""
4565
path = f"v1/groups/{self['guid']}"
4666
url = self._ctx.url + path
4767
self._ctx.session.delete(url)
@@ -53,7 +73,146 @@ def __init__(self, ctx: Context, group_guid: str) -> None:
5373
self._group_guid = group_guid
5474
self._ctx: Context = ctx
5575

76+
@overload
77+
def add(self, *args: User) -> None: ...
78+
@overload
79+
def add(self, *, user_guid: str) -> None: ...
80+
81+
def add(self, *args: User, user_guid: Optional[str] = None) -> None:
82+
"""Add a user to the group.
83+
84+
Parameters
85+
----------
86+
*args : User
87+
User objects to add to the group.
88+
user_guid : str
89+
The user GUID.
90+
91+
Examples
92+
--------
93+
```python
94+
from posit.connect import Client
95+
96+
client = Client("https://posit.example.com", "API_KEY")
97+
98+
group = client.groups.get("GROUP_GUID_HERE")
99+
user = client.users.get("USER_GUID_HERE")
100+
101+
# Add a user to the group
102+
group.members.add(user)
103+
104+
# Add multiple users to the group
105+
users = client.users.find()
106+
group.members.add(*users)
107+
108+
# Add a user to the group by GUID
109+
group.members.add(user_guid="USER_GUID_HERE")
110+
```
111+
"""
112+
if len(args) > 0:
113+
from .users import User
114+
115+
if user_guid:
116+
raise ValueError("Only one of `*args` or `user_guid=` should be provided.")
117+
for i, user in enumerate(args):
118+
if not isinstance(user, User):
119+
raise ValueError(f"args[{i}] is not a User object.")
120+
121+
for user in args:
122+
self.add(user_guid=user["guid"])
123+
124+
return
125+
126+
if not isinstance(user_guid, str):
127+
raise TypeError("`user_guid=` should be a string.")
128+
if not user_guid:
129+
raise ValueError("`user_guid=` should not be empty")
130+
131+
path = f"v1/groups/{self._group_guid}/members"
132+
url = self._ctx.url + path
133+
self._ctx.session.post(url, json={"user_guid": user_guid})
134+
135+
@overload
136+
def delete(self, *args: User) -> None: ...
137+
@overload
138+
def delete(self, *, user_guid: str) -> None: ...
139+
140+
def delete(self, *args: User, user_guid: Optional[str] = None) -> None:
141+
"""Remove a user from the group.
142+
143+
Parameters
144+
----------
145+
*args : User
146+
User objects to remove from the group.
147+
user_guid : str
148+
The user GUID.
149+
150+
Examples
151+
--------
152+
```python
153+
from posit.connect import Client
154+
155+
client = Client("https://posit.example.com", "API_KEY")
156+
157+
group = client.groups.get("GROUP_GUID_HERE")
158+
159+
# Remove a user from the group
160+
first_user = group.members.find()[0]
161+
group.members.delete(first_user)
162+
163+
# Remove multiple users from the group
164+
group_users = group.members.find()[:2]
165+
group.members.delete(*group_users)
166+
167+
# Remove a user from the group by GUID
168+
group.members.delete(user_guid="USER_GUID_HERE")
169+
```
170+
171+
"""
172+
if len(args) > 0:
173+
from .users import User
174+
175+
if user_guid:
176+
raise ValueError("Only one of `*args` or `user_guid=` should be provided.")
177+
for i, user in enumerate(args):
178+
if not isinstance(user, User):
179+
raise TypeError(f"`args[{i}]` is not a `User` object.")
180+
181+
for user in args:
182+
self.delete(user_guid=user["guid"])
183+
184+
return
185+
186+
if not isinstance(user_guid, str):
187+
raise TypeError("`user_guid=` should be a string.")
188+
if not user_guid:
189+
raise ValueError("`user_guid=` should not be empty")
190+
191+
path = f"v1/groups/{self._group_guid}/members/{user_guid}"
192+
url = self._ctx.url + path
193+
self._ctx.session.delete(url)
194+
56195
def find(self) -> list[User]:
196+
"""Find group members.
197+
198+
Returns
199+
-------
200+
list[User]
201+
All the users in the group.
202+
203+
Examples
204+
--------
205+
```python
206+
from posit.connect import Client
207+
208+
client = Client("https://posit.example.com", "API_KEY")
209+
210+
group = client.groups.get("GROUP_GUID_HERE")
211+
212+
# Find all users in the group
213+
group_users = group.members.find()
214+
```
215+
"""
57216
# Avoid circular import
58217
from .users import User
59218

@@ -72,6 +231,19 @@ def count(self) -> int:
72231
Returns
73232
-------
74233
int
234+
235+
Examples
236+
--------
237+
```python
238+
from posit.connect import Client
239+
240+
client = Client("https://posit.example.com", "API_KEY")
241+
242+
group = client.groups.get("GROUP_GUID_HERE")
243+
244+
# Get count of group members
245+
group_user_count = group.members.count()
246+
```
75247
"""
76248
path = f"v1/groups/{self._group_guid}/members"
77249
url = self._ctx.url + path

src/posit/connect/users.py

Lines changed: 140 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
from __future__ import annotations
44

5-
from typing import TYPE_CHECKING, List, Literal
5+
from typing import TYPE_CHECKING, List, Literal, Optional, overload
66

77
from typing_extensions import NotRequired, Required, TypedDict, Unpack
88

@@ -157,6 +157,145 @@ def __init__(self, ctx: Context, user_guid: str) -> None:
157157
self._ctx: Context = ctx
158158
self._user_guid: str = user_guid
159159

160+
@overload
161+
def add(self, *args: Group) -> None: ...
162+
@overload
163+
def add(self, *, group_guid: str) -> None: ...
164+
165+
def add(
166+
self,
167+
*args: Group,
168+
group_guid: Optional[str] = None,
169+
) -> None:
170+
"""
171+
Add the user to the specified groups.
172+
173+
Parameters
174+
----------
175+
*args : Group
176+
The groups to which the user will be added.
177+
group_guid : str
178+
The unique identifier (guid) of the group to which the user will be added.
179+
180+
Returns
181+
-------
182+
None
183+
184+
Examples
185+
--------
186+
```python
187+
from posit.connect import Client
188+
189+
client = Client("https://posit.example.com", "API_KEY")
190+
191+
group = client.groups.get("GROUP_GUID_HERE")
192+
user = client.users.get("USER_GUID_HERE")
193+
194+
# Add the user to the group
195+
user.groups.add(group)
196+
197+
# Add the user to multiple groups
198+
groups = [
199+
client.groups.get("GROUP_GUID_1"),
200+
client.groups.get("GROUP_GUID_2"),
201+
]
202+
user.groups.add(*groups)
203+
204+
# Add the user to a group by GUID
205+
user.groups.add(group_guid="GROUP_GUID_HERE")
206+
```
207+
"""
208+
if len(args) > 0:
209+
from .groups import Group
210+
211+
if group_guid:
212+
raise ValueError("Only one of `*args` or `group_guid` may be be provided.")
213+
214+
for i, group in enumerate(args):
215+
if not isinstance(group, Group):
216+
raise TypeError(
217+
f"`args[{i}]` is not an instance of Group",
218+
)
219+
for group in args:
220+
group.members.add(user_guid=self._user_guid)
221+
return
222+
223+
if not group_guid:
224+
raise ValueError("Only one of `*args` or `group_guid` may be be provided.")
225+
group = self._ctx.client.groups.get(group_guid)
226+
group.members.add(user_guid=self._user_guid)
227+
228+
@overload
229+
def delete(self, *args: Group) -> None: ...
230+
@overload
231+
def delete(self, *, group_guid: str) -> None: ...
232+
233+
def delete(
234+
self,
235+
*args: Group,
236+
group_guid: Optional[str] = None,
237+
) -> None:
238+
"""
239+
Remove the user from the specified groups.
240+
241+
Parameters
242+
----------
243+
*args : Group
244+
The groups from which the user will be removed.
245+
group_guid : str
246+
The unique identifier (guid) of the group from which the user will be removed.
247+
248+
Returns
249+
-------
250+
None
251+
252+
Examples
253+
--------
254+
```python
255+
from posit.connect import Client
256+
257+
client = Client("https://posit.example.com", "API_KEY")
258+
259+
group = client.groups.get("GROUP_GUID_HERE")
260+
user = client.users.get("USER_GUID_HERE")
261+
262+
# Remove the user from the group
263+
user.groups.delete(group)
264+
265+
# Remove the user from multiple groups
266+
groups = [
267+
client.groups.get("GROUP_GUID_1"),
268+
client.groups.get("GROUP_GUID_2"),
269+
]
270+
user.groups.delete(*groups)
271+
272+
# Remove the user from a group by GUID
273+
user.groups.delete(group_guid="GROUP_GUID_HERE")
274+
```
275+
"""
276+
if len(args) > 0:
277+
from .groups import Group
278+
279+
if group_guid:
280+
raise ValueError("Only one of `*args` or `group_guid=` may be be provided.")
281+
282+
for i, group in enumerate(args):
283+
if not isinstance(group, Group):
284+
raise TypeError(
285+
f"`args[{i}]` is not an instance of Group",
286+
)
287+
for group in args:
288+
group.members.delete(user_guid=self._user_guid)
289+
return
290+
291+
if not isinstance(group_guid, str):
292+
raise TypeError("`group_guid=` must be a string.")
293+
if not group_guid:
294+
raise ValueError("`group_guid=` must not be empty.")
295+
296+
group = self._ctx.client.groups.get(group_guid)
297+
group.members.delete(user_guid=self._user_guid)
298+
160299
def find(self) -> List[Group]:
161300
"""
162301
Retrieve the groups to which the user belongs.

0 commit comments

Comments
 (0)