Skip to content

Commit 3154b9d

Browse files
authored
Merge pull request #2 from umn-microsoft-automation/documentation
Documentation
2 parents 5ebc3f5 + d01d454 commit 3154b9d

30 files changed

+1343
-292
lines changed

README.md

+30
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,36 @@
22

33
This is a module to interact with the [Grouper Web Services API](https://spaces.at.internet2.edu/display/Grouper/Grouper+Web+Services).
44

5+
## Basic Usage
6+
7+
Operations will start by creating a `GrouperClient` object.
8+
9+
``` python
10+
from grouper_python import GrouperClient
11+
12+
grouper_client = GrouperClient(base_url, username, password)
13+
```
14+
15+
`GrouperClient` can also be used as a context manager.
16+
17+
``` python
18+
from grouper_python import GrouperClient
19+
20+
with GrouperClient(base_url, username, password) as grouper_client:
21+
...
22+
```
23+
24+
The `base_url` should end in something like
25+
`grouper-ws/servicesRest/v2_6_000`.
26+
27+
With a `GrouperClient` object, you can query for a subject, stem, or group.
28+
You can also "search" for groups or subjects.
29+
30+
Once you have an object, you can perform various operations against it.
31+
To create a new group or stem for example, you would get the "parent" stem,
32+
and then use `create_child_stem()` or `create_child_group()` to create that
33+
stem or group in that parent.
34+
535
## Installation
636

737
To install grouper library only:

grouper_python/__init__.py

+6-7
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
1-
from .objects.client import Client
2-
from .objects.group import Group
3-
from .objects.stem import Stem
4-
from .objects.subject import Subject
5-
from .objects.person import Person
1+
"""grouper_python, a Python package for interacting with Grouper Web Services."""
62

7-
__version__ = "0.1.0"
3+
from .objects.client import GrouperClient
84

9-
__all__ = ["Client", "Group", "Stem", "Subject", "Person"]
5+
Client = GrouperClient
6+
7+
__version__ = "0.1.1"
8+
__all__ = ["GrouperClient"]

grouper_python/group.py

+88-11
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,18 @@
1+
"""grouper-python.group - functions to interact with group objects.
2+
3+
These are "helper" functions that most likely will not be called directly.
4+
Instead, a GrouperClient class should be created, then from there use that
5+
GrouperClient's methods to find and create objects, and use those objects' methods.
6+
These helper functions are used by those objects, but can be called
7+
directly if needed.
8+
"""
9+
110
from __future__ import annotations
211
from typing import TYPE_CHECKING, Any
312

413
if TYPE_CHECKING: # pragma: no cover
514
from .objects.group import CreateGroup, Group
6-
from .objects.client import Client
15+
from .objects.client import GrouperClient
716
from .objects.subject import Subject
817
from .objects.exceptions import (
918
GrouperGroupNotFoundException,
@@ -15,10 +24,25 @@
1524

1625
def find_group_by_name(
1726
group_name: str,
18-
client: Client,
27+
client: GrouperClient,
1928
stem: str | None = None,
2029
act_as_subject: Subject | None = None,
2130
) -> list[Group]:
31+
"""Find a group or groups by approximate name.
32+
33+
:param group_name: The group name to search for
34+
:type group_name: str
35+
:param client: The GrouperClient to use
36+
:type client: GrouperClient
37+
:param stem: Optional stem to limit the search to, defaults to None
38+
:type stem: str | None, optional
39+
:param act_as_subject: Optional subject to act as, defaults to None
40+
:type act_as_subject: Subject | None, optional
41+
:raises GrouperStemNotFoundException: The specified stem cannot be found
42+
:raises GrouperSuccessException: An otherwise unhandled issue with the result
43+
:return: List of found groups, will be an empty list if no groups are found
44+
:rtype: list[Group]
45+
"""
2246
from .objects.group import Group
2347

2448
body = {
@@ -45,10 +69,10 @@ def find_group_by_name(
4569
raise GrouperStemNotFoundException(str(stem), r)
4670
else: # pragma: no cover
4771
# Some other issue, so pass the failure through
48-
raise
72+
raise err
4973
if "groupResults" in r["WsFindGroupsResults"]:
5074
return [
51-
Group.from_results(client, grp)
75+
Group(client, grp)
5276
for grp in r["WsFindGroupsResults"]["groupResults"]
5377
]
5478
else:
@@ -57,9 +81,20 @@ def find_group_by_name(
5781

5882
def create_groups(
5983
groups: list[CreateGroup],
60-
client: Client,
84+
client: GrouperClient,
6185
act_as_subject: Subject | None = None,
6286
) -> list[Group]:
87+
"""Create groups.
88+
89+
:param groups: List of groups to create
90+
:type groups: list[CreateGroup]
91+
:param client: The GrouperClient to use
92+
:type client: GrouperClient
93+
:param act_as_subject: Optional subject to act as, defaults to None
94+
:type act_as_subject: Subject | None, optional
95+
:return: Group objects representing the created groups
96+
:rtype: list[Group]
97+
"""
6398
from .objects.group import Group
6499

65100
groups_to_save = []
@@ -87,16 +122,29 @@ def create_groups(
87122
act_as_subject=act_as_subject,
88123
)
89124
return [
90-
Group.from_results(client, result["wsGroup"])
125+
Group(client, result["wsGroup"])
91126
for result in r["WsGroupSaveResults"]["results"]
92127
]
93128

94129

95130
def delete_groups(
96131
group_names: list[str],
97-
client: Client,
132+
client: GrouperClient,
98133
act_as_subject: Subject | None = None,
99134
) -> None:
135+
"""Delete the given groups.
136+
137+
:param group_names: The names of groups to delete
138+
:type group_names: list[str]
139+
:param client: The GrouperClient to use
140+
:type client: GrouperClient
141+
:param act_as_subject: Optional subject to act as, defaults to None
142+
:type act_as_subject: Subject | None, optional
143+
:raises GrouperPermissionDenied: Permission denied to complete the operation
144+
:raises GrouperGroupNotFoundException: A group with the given name cannot
145+
be found
146+
:raises GrouperSuccessException: An otherwise unhandled issue with the result
147+
"""
100148
group_lookup = [{"groupName": group} for group in group_names]
101149
body = {
102150
"WsRestGroupDeleteRequest": {
@@ -139,10 +187,25 @@ def delete_groups(
139187

140188
def get_groups_by_parent(
141189
parent_name: str,
142-
client: Client,
190+
client: GrouperClient,
143191
recursive: bool = False,
144192
act_as_subject: Subject | None = None,
145193
) -> list[Group]:
194+
"""Get Groups within the given parent stem.
195+
196+
:param parent_name: The parent stem to look in
197+
:type parent_name: str
198+
:param client: The GrouperClient to use
199+
:type client: GrouperClient
200+
:param recursive: Whether to look recursively through the entire subtree (True),
201+
or only one level in the given parent (False), defaults to False
202+
:type recursive: bool, optional
203+
:param act_as_subject: Optional subject to act as, defaults to None
204+
:type act_as_subject: Subject | None, optional
205+
:raises GrouperSuccessException: An otherwise unhandled issue with the result
206+
:return: The list of Groups found
207+
:rtype: list[Group]
208+
"""
146209
from .objects.group import Group
147210

148211
body = {
@@ -162,7 +225,7 @@ def get_groups_by_parent(
162225
)
163226
if "groupResults" in r["WsFindGroupsResults"]:
164227
return [
165-
Group.from_results(client, grp)
228+
Group(client, grp)
166229
for grp in r["WsFindGroupsResults"]["groupResults"]
167230
]
168231
else:
@@ -171,9 +234,23 @@ def get_groups_by_parent(
171234

172235
def get_group_by_name(
173236
group_name: str,
174-
client: Client,
237+
client: GrouperClient,
175238
act_as_subject: Subject | None = None,
176239
) -> Group:
240+
"""Get a group with the given name.
241+
242+
:param group_name: The name of the group to get
243+
:type group_name: str
244+
:param client: The GrouperClient to use
245+
:type client: GrouperClient
246+
:param act_as_subject: Optional subject to act as, defaults to None
247+
:type act_as_subject: Subject | None, optional
248+
:raises GrouperGroupNotFoundException: A group with the given name cannot
249+
be found
250+
:raises GrouperSuccessException: An otherwise unhandled issue with the result
251+
:return: The group with the given name
252+
:rtype: Group
253+
"""
177254
from .objects.group import Group
178255

179256
body = {
@@ -186,4 +263,4 @@ def get_group_by_name(
186263
r = client._call_grouper("/groups", body, act_as_subject=act_as_subject)
187264
if "groupResults" not in r["WsFindGroupsResults"]:
188265
raise GrouperGroupNotFoundException(group_name, r)
189-
return Group.from_results(client, r["WsFindGroupsResults"]["groupResults"][0])
266+
return Group(client, r["WsFindGroupsResults"]["groupResults"][0])

0 commit comments

Comments
 (0)