Skip to content

Commit

Permalink
Merge pull request #1 from umn-microsoft-automation/pre
Browse files Browse the repository at this point in the history
Initial 0.10.0 release
  • Loading branch information
FISHMANPET authored May 1, 2023
2 parents 60027bb + f221845 commit 5ebc3f5
Show file tree
Hide file tree
Showing 33 changed files with 2,281 additions and 263 deletions.
26 changes: 2 additions & 24 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# grouper-python

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

## Installation

To install grouper library only:
Expand All @@ -8,12 +10,6 @@ To install grouper library only:
pip install .
```

To install additional requirements for running the included scripts:

``` sh
pip install .[script]
```

To install for development:

``` sh
Expand All @@ -22,21 +18,3 @@ pip install --editable .[dev]

This will install so the `grouper` module is based off the source code,
and also installs neccessary linters and testing requirements.
Currently there are no "tests" written for this code,
but at the very least it passes `pylama` and `mypy`.

## Script usage

To use the included scripts (`docs_base.py` and `docs_site.py`)
you will need to setup a `.env` file.
Copy `.env.template` to `.env`.
Change the values for GROUPER_USER, GROUPER_PWD, and if neccessary, GROUPER_BASE_URL.
If there are double quotes (`"`) in your password, surround it with single quotes (`'`)
instead of the double quotes in the sample file.

### Specifying sites

Specify the sites to create groups for using a text file (by default, `sites.txt`)
in the root of this repository.
Specify the URLs, one per line.
This file will be read by `docs_site.py`.
59 changes: 31 additions & 28 deletions azure-pipelines.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
name: $(Date:yyyyMMdd).$(Rev:rr)

pool:
vmImage: ubuntu-latest

Expand All @@ -16,11 +18,11 @@ stages:
displayName: Run Tests
continueOnError: true
- script: |
pytest --pylama -k 'pylama' --junit-xml=junit/test-pylama-results.xml -o addopts= tests/ pygrouper/
pytest --pylama -k 'pylama' --junit-xml=junit/test-pylama-results.xml -o addopts= tests/ grouper_python/
displayName: Run Linter Tests
continueOnError: true
- script: |
mypy -p pygrouper --junit-xml junit/test-mypy-results.xml
mypy --junit-xml junit/test-mypy-results.xml
displayName: Run MyPy Tests
continueOnError: true
- task: PublishTestResults@2
Expand All @@ -43,36 +45,37 @@ stages:
- task: TwineAuthenticate@1
inputs:
artifactFeed: 'ITAC-API/pygrouper'
- task: PythonScript@0
inputs:
scriptSource: inline
script: |
with open('pygrouper/__init__.py', 'r+') as f:
content = f.read()
- ${{ if ne(variables['Build.SourceBranchName'], 'main') }}:
- task: PythonScript@0
inputs:
scriptSource: inline
script: |
with open('grouper_python/__init__.py', 'r+') as f:
content = f.read()
for line in content.splitlines():
if line.startswith('__version__'):
delim = '"' if '"' in line else "'"
version = line.split(delim)[1]
break
else:
raise RuntimeError("Unable to find version string.")
for line in content.splitlines():
if line.startswith('__version__'):
delim = '"' if '"' in line else "'"
version = line.split(delim)[1]
break
else:
raise RuntimeError("Unable to find version string.")
print(f"found {version}")
build_number = "$(Build.BuildNumber)".replace(".", "")
new_version = f"{version}b{build_number}"
print(f"new version: {new_version}")
print(f"found {version}")
build_number = "$(Build.BuildNumber)".replace(".", "")
new_version = f"{version}b{build_number}"
print(f"new version: {new_version}")
content = content.replace(version, new_version)
f.seek(0)
f.write(content)
f.truncate()
displayName: Set prerelease Version
content = content.replace(version, new_version)
f.seek(0)
f.write(content)
f.truncate()
displayName: Set prerelease Version
- script: |
pip install build twine
python -m build
cat $(PYPIRC_PATH)
# twine upload -r mkdocs-material-umn --config-file $(PYPIRC_PATH) dist/* --verbose
pwd
ls -l
- publish: $(Pipeline.Workspace)/s/dist
twine upload -r pygrouper --config-file $(PYPIRC_PATH) dist/* --verbose
# pwd
# ls -l
# - publish: $(Pipeline.Workspace)/s/dist
9 changes: 9 additions & 0 deletions grouper_python/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
from .objects.client import Client
from .objects.group import Group
from .objects.stem import Stem
from .objects.subject import Subject
from .objects.person import Person

__version__ = "0.1.0"

__all__ = ["Client", "Group", "Stem", "Subject", "Person"]
45 changes: 35 additions & 10 deletions pygrouper/group.py → grouper_python/group.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
from __future__ import annotations
from typing import TYPE_CHECKING, Any

if TYPE_CHECKING:
if TYPE_CHECKING: # pragma: no cover
from .objects.group import CreateGroup, Group
from .objects.client import Client
from .objects.subject import Subject
from .objects.exceptions import (
GrouperGroupNotFoundException,
GrouperSuccessException,
GrouperStemNotFoundException,
GrouperPermissionDenied,
)


Expand Down Expand Up @@ -41,8 +42,9 @@ def find_group_by_name(
if r_metadata["resultCode"] == "INVALID_QUERY" and r_metadata[
"resultMessage"
].startswith("Cant find stem"):
raise GrouperStemNotFoundException(str(stem))
raise GrouperStemNotFoundException(str(stem), r)
else: # pragma: no cover
# Some other issue, so pass the failure through
raise
if "groupResults" in r["WsFindGroupsResults"]:
return [
Expand Down Expand Up @@ -101,14 +103,38 @@ def delete_groups(
"wsGroupLookups": group_lookup,
}
}
r = client._call_grouper(
"/groups",
body,
act_as_subject=act_as_subject,
)
try:
r = client._call_grouper(
"/groups",
body,
act_as_subject=act_as_subject,
)
except GrouperSuccessException as err:
r = err.grouper_result
r_metadata = r["WsGroupDeleteResults"]["resultMetadata"]
if r_metadata["resultCode"] == "PROBLEM_DELETING_GROUPS":
raise GrouperPermissionDenied(r)
else: # pragma: no cover
# Some other issue, so pass the failure through
raise
for result in r["WsGroupDeleteResults"]["results"]:
if result["resultMetadata"]["resultCode"] != "SUCCESS":
meta = result["resultMetadata"]
if meta["resultCode"] == "SUCCESS_GROUP_NOT_FOUND":
try:
result_message = meta["resultMessage"]
split_message = result_message.split(",")
group_name = split_message[1].split("=")[1]
except Exception: # pragma: no cover
# The try above feels fragile, so if it fails,
# throw a SuccessException
raise GrouperSuccessException(r)
raise GrouperGroupNotFoundException(group_name, r)
elif meta["resultCode"] != "SUCCESS": # pragma: no cover
# Whatever the error here, we don't understand it
# well enough to process it into something more specific
raise GrouperSuccessException(r)
else:
pass


def get_groups_by_parent(
Expand All @@ -134,7 +160,6 @@ def get_groups_by_parent(
body,
act_as_subject=act_as_subject,
)
print(r)
if "groupResults" in r["WsFindGroupsResults"]:
return [
Group.from_results(client, grp)
Expand All @@ -160,5 +185,5 @@ def get_group_by_name(
}
r = client._call_grouper("/groups", body, act_as_subject=act_as_subject)
if "groupResults" not in r["WsFindGroupsResults"]:
raise GrouperGroupNotFoundException(group_name)
raise GrouperGroupNotFoundException(group_name, r)
return Group.from_results(client, r["WsFindGroupsResults"]["groupResults"][0])
Loading

0 comments on commit 5ebc3f5

Please sign in to comment.