diff --git a/README.md b/README.md
index 07b9446..c4ac0ff 100644
--- a/README.md
+++ b/README.md
@@ -10,6 +10,7 @@ Available at PyPi: [https://pypi.org/project/fabric-comanage-api/](https://pypi.
- [TL;DR](#tldr)
- [API endpoints](#endpoints)
+ - [CoGroupMember](#cogroupmember)
- [CoOrgIdentityLink](#coorgidentitylinks)
- [CoPerson](#coperson)
- [CoPersonRole](#copersonrole)
@@ -120,6 +121,24 @@ Return types based on implementation status of wrapped API endpoints
- `-> dict`: raise exception (`HTTPError - 501 Server Error: Not Implemented for url: mock://not_implemented_501.local`)
- `-> bool`: raise exception (`HTTPError - 501 Server Error: Not Implemented for url: mock://not_implemented_501.local`)
+### [CoGroupMember API](https://spaces.at.internet2.edu/display/COmanage/CoGroupMember+API) (COmanage v4.0.0+)
+- `cogroupmember_add(group_id: int, person_id: int) -> dict`
+ - Add a new CoGroupMember (ie: a member of a CO group).
+- `cogroupmember_delete() -> bool`
+ - `### NOT IMPLEMENTED ###`
+ - Remove a CoGroupMember.
+- `cogroupmember_edit() -> bool`
+ - `### NOT IMPLEMENTED ###`
+ - Edit an existing CoGroupMember.
+- `cogroupmember_view_all() -> dict`
+ - `### NOT IMPLEMENTED ###`
+ - Retrieve all existing CoGroupMembers.
+- `cogroupmember_view_per_group(group_id: int) -> dict`
+ - Retrieve CoGroupMembers attached to a CoGroup.
+- `cogroupmember_view_one() -> dict`
+ - `### NOT IMPLEMENTED ###`
+ - Retrieve an existing CoGroupMember.
+
### [CoOrgIdentityLink API](https://spaces.at.internet2.edu/display/COmanage/CoOrgIdentityLink+API) (COmanage v4.0.0+)
- `coorg_identity_links_add() -> dict`
diff --git a/comanage_api/__init__.py b/comanage_api/__init__.py
index 39118f1..bcc1318 100644
--- a/comanage_api/__init__.py
+++ b/comanage_api/__init__.py
@@ -1,6 +1,8 @@
import requests_mock
from requests import Session
+from ._cogroupmember import cogroupmember_add, cogroupmember_delete, cogroupmember_edit, \
+ cogroupmember_view_all, cogroupmember_view_per_group, cogroupmember_view_one
from ._coorgidentitylinks import coorg_identity_links_add, coorg_identity_links_delete, coorg_identity_links_edit, \
coorg_identity_links_view_all, coorg_identity_links_view_by_identity, coorg_identity_links_view_one
from ._copeople import copeople_add, copeople_delete, copeople_edit, copeople_find, copeople_match, \
@@ -92,6 +94,25 @@ def __init__(self, co_api_url: str, co_api_user: str, co_api_pass: str, co_api_o
self._s.headers = {'Content-Type': 'application/json'}
self._s.auth = (self._CO_API_USER, self._CO_API_PASS)
+ # CoGroupMember API
+ def cogroupmember_add(self, group_id: int, person_id: int):
+ return cogroupmember_add(self, group_id=group_id, person_id=person_id)
+
+ def cogroupmember_delete(self):
+ return cogroupmember_delete(self)
+
+ def cogroupmember_edit(self):
+ return cogroupmember_edit(self)
+
+ def cogroupmember_view_all(self):
+ return cogroupmember_view_all(self)
+
+ def cogroupmember_view_per_group(self, group_id: int):
+ return cogroupmember_view_per_group(self, group_id=group_id)
+
+ def cogroupmember_view_one(self):
+ return cogroupmember_view_one(self)
+
# CoOrgIdentityLink API
def coorg_identity_links_add(self):
return coorg_identity_links_add(self)
diff --git a/comanage_api/_cogroupmember.py b/comanage_api/_cogroupmember.py
new file mode 100644
index 0000000..0abdb78
--- /dev/null
+++ b/comanage_api/_cogroupmember.py
@@ -0,0 +1,222 @@
+# comanage_api/_cogroupmember.py
+
+"""
+CoGroupMember API - https://spaces.at.internet2.edu/display/COmanage/CoGroupMember+API
+
+Methods
+-------
+cogroupmember_add(group_id: int, person_id: int) -> dict
+ Add a new CoGroupMember (ie: a member of a CO group).
+cogroupmember_delete() -> bool
+ ### NOT IMPLEMENTED ###
+ Remove a CoGroupMember.
+cogroupmember_edit() -> bool
+ ### NOT IMPLEMENTED ###
+ Edit an existing CoGroupMember.
+cogroupmember_view_all() -> dict
+ ### NOT IMPLEMENTED ###
+ Retrieve all existing CoGroupMembers.
+cogroupmember_view_per_group(group_id: int) -> dict
+ Retrieve CoGroupMembers attached to a CoGroup.
+cogroupmember_view_one() -> dict
+ ### NOT IMPLEMENTED ###
+ Retrieve an existing CoGroupMember.
+"""
+
+import json
+
+
+def cogroupmember_add(self, group_id: int, person_id: int) -> dict:
+ """
+ Add a new CoGroupMember (ie: a member of a CO group).
+ group_id: COmanage COGroup Id
+ person_id: COmanage COPerson Id
+ :request
+ {
+ "RequestType":"CoGroupMembers",
+ "Version":"1.0",
+ "CoGroupMembers":
+ [
+ {
+ "Version":"1.0",
+ "CoGroupId":"",
+ "Person":
+ {
+ "Type":"CO",
+ "Id":""
+ },
+ "Member":true|false,
+ "Owner":true|false,
+ "ValidFrom":"",
+ "ValidThrough":""
+ }
+ ]
+ }:
+ Response Format
+ HTTP Status Response Body Description
+ 201 Added NewObjectResponse CoGroupMember added
+ 400 Bad Request CoGroupMember Request not
+ provided in POST body
+ 400 Invalid Fields ErrorResponse An error in one or more
+ provided fields
+ 401 Unauthorized Authentication required
+ 403 CoGroup Does Not Exist The specified CoGroup does not exist
+ 403 CoPerson Does Not Exist The specified CoPerson does not exist
+ 403 CoPerson Already Member The specified CoPerson is already a
+ member of the specified CoGroup
+ 500 Other Error Unknown error
+ """
+
+ post_body = {
+ "RequestType":"CoGroupMembers",
+ "Version":"1.0",
+ "CoGroupMembers":
+ [
+ {
+ "Version":"1.0",
+ "CoGroupId":"",
+ "Person":
+ {
+ "Type":"CO",
+ "Id":""
+ },
+ "Member":True,
+ "Owner":False
+ }
+ ]
+ }
+
+ post_body['CoGroupMembers'][0]['CoGroupId'] = group_id
+ post_body['CoGroupMembers'][0]['Person']['Id'] = person_id
+
+ post_body = json.dumps(post_body)
+ url = self._CO_API_URL + '/co_group_members.json'
+ resp = self._s.post(
+ url=url,
+ data=post_body
+ )
+ if resp.status_code == 201:
+ return json.loads(resp.text)
+ else:
+ resp.raise_for_status()
+
+
+def cogroupmember_delete(self) -> bool:
+ """
+ ### NOT IMPLEMENTED ###
+ Remove a CoGroupMember.
+
+ :param self:
+ :return
+ 501 Server Error: Not Implemented for url: mock://not_implemented_501.local:
+ """
+ url = self._MOCK_501_URL
+ resp = self._mock_session.get(
+ url=url
+ )
+ if resp.status_code == 200:
+ return True
+ else:
+ resp.raise_for_status()
+
+
+def cogroupmember_edit(self) -> bool:
+ """
+ ### NOT IMPLEMENTED ###
+ Edit an existing CoGroupMember.
+
+ :param self:
+ :return
+ 501 Server Error: Not Implemented for url: mock://not_implemented_501.local:
+ """
+ url = self._MOCK_501_URL
+ resp = self._mock_session.get(
+ url=url
+ )
+ if resp.status_code == 200:
+ return True
+ else:
+ resp.raise_for_status()
+
+
+def cogroupmember_view_all(self) -> dict:
+ """
+ ### NOT IMPLEMENTED ###
+ Retrieve all existing CoGroupMembers.
+
+ :param self:
+ :return
+ 501 Server Error: Not Implemented for url: mock://not_implemented_501.local:
+ """
+ url = self._MOCK_501_URL
+ resp = self._mock_session.get(
+ url=url
+ )
+ if resp.status_code == 200:
+ return json.loads(resp.text)
+ else:
+ resp.raise_for_status()
+
+
+def cogroupmember_view_per_group(self, group_id: int) -> dict:
+ """
+ Retrieve CoGroupMembers attached to a CoGroup.
+ group_id: COmanage COGroup Id
+ :request
+ {
+ "RequestType":"CoGroupMembers",
+ "Version":"1.0",
+ "CoGroupMembers":
+ [
+ {
+ "Version":"1.0",
+ "CoGroupId":"",
+ "Person":
+ {
+ "Type":"CO",
+ "Id":""
+ },
+ "Member":true|false,
+ "Owner":true|false,
+ "ValidFrom":"",
+ "ValidThrough":""
+ }
+ ]
+ }:
+ Response Format
+ HTTP Status Response Body Description
+ 200 OK CoGroupMemberResponse CoGroupMember returned
+ 401 Unauthorized Authentication required
+ 403 CoGroup Unknown id not found
+ 500 Other Error Unknown error
+ """
+
+ url = self._CO_API_URL + '/co_group_members.json'
+ params = {'cogroupid': group_id}
+ resp = self._s.get(
+ url=url,
+ params=params
+ )
+ if resp.status_code == 200:
+ return json.loads(resp.text)
+ else:
+ resp.raise_for_status()
+
+
+def cogroupmember_view_one(self) -> dict:
+ """
+ ### NOT IMPLEMENTED ###
+ Retrieve an existing CoGroupMember.
+
+ :param self:
+ :return
+ 501 Server Error: Not Implemented for url: mock://not_implemented_501.local:
+ """
+ url = self._MOCK_501_URL
+ resp = self._mock_session.get(
+ url=url
+ )
+ if resp.status_code == 200:
+ return json.loads(resp.text)
+ else:
+ resp.raise_for_status()
diff --git a/examples/README.md b/examples/README.md
index 39c6d61..e8f9aec 100644
--- a/examples/README.md
+++ b/examples/README.md
@@ -7,6 +7,7 @@ Examples demonstrating basic usage for each wrapped endpoint. Some of the values
## Table of Contents
- [Configuration](#config) `__init__.py` used by all examples
+- [CoGroupMember API](#cogroupmember) example output
- [CoOrgIdentityLink API](#coorgidentitylink) example output
- [CoPerson API](#coperson) example output
- [CoPersonRole API](#copersonrole) example output
@@ -61,6 +62,33 @@ api = ComanageApi(
)
```
+## CoGroupMember API
+
+Example: `cogroupmember_example.py`
+
+```console
+$ python examples/cogroupmember_example.py
+### cogroupmember_add
+[ERROR] Exception caught
+--> HTTPError - 501 Server Error: Not Implemented for url: mock://not_implemented_501.local
+### cogroupmember_delete
+[ERROR] Exception caught
+--> HTTPError - 501 Server Error: Not Implemented for url: mock://not_implemented_501.local
+### cogroupmember_edit
+[ERROR] Exception caught
+--> HTTPError - 501 Server Error: Not Implemented for url: mock://not_implemented_501.local
+### cogroupmember_view_all
+[ERROR] Exception caught
+--> HTTPError - 501 Server Error: Not Implemented for url: mock://not_implemented_501.local
+### cogroupmember_view_per_group
+[ERROR] Exception caught
+--> HTTPError - 501 Server Error: Not Implemented for url: mock://not_implemented_501.local
+### cogroupmember_view_one
+[ERROR] Exception caught
+--> HTTPError - 501 Server Error: Not Implemented for url: mock://not_implemented_501.local
+
+```
+
## CoOrgIdentityLink API
Example: `co_org_identity_links_example.py`
diff --git a/examples/cogroupmember_example.py b/examples/cogroupmember_example.py
new file mode 100644
index 0000000..ee5230f
--- /dev/null
+++ b/examples/cogroupmember_example.py
@@ -0,0 +1,75 @@
+# examples/cogroupmember_example.py
+# CoGroupMember API examples
+
+import os
+import sys
+
+sys.path.append(
+ os.path.abspath(os.path.join(os.path.dirname(__file__), os.path.pardir))
+)
+from examples import *
+
+# cogroupmember_add, cogroupmember_delete, cogroupmember_edit, cogroupmember_view_all, cogroupmember_view_per_group, cogroupmember_view_one
+
+# must be set ahead of time and be valid within the CO
+CO_PERSON_ID = 163
+CO_GROUP_ID = 2
+
+# cogroupmember_add(group_id: int, person_id: int) -> dict
+print('### cogroupmember_add')
+try:
+ new_cogroupmember = api.cogroupmember_add(
+ group_id=CO_GROUP_ID,
+ person_id=CO_PERSON_ID
+ )
+ print(json.dumps(new_cogroupmember, indent=4))
+except HTTPError as err:
+ print('[ERROR] Exception caught')
+ print('--> ', type(err).__name__, '-', err)
+
+# cogroupmember_delete() -> bool
+print('### cogroupmember_delete')
+try:
+ delete_cogroupmember = api.cogroupmember_delete()
+ print(json.dumps(delete_cogroupmember, indent=4))
+except HTTPError as err:
+ print('[ERROR] Exception caught')
+ print('--> ', type(err).__name__, '-', err)
+
+# cogroupmember_edit() -> bool
+print('### cogroupmember_edit')
+try:
+ edit_cogroupmember = api.cogroupmember_edit()
+ print(json.dumps(edit_cogroupmember, indent=4))
+except HTTPError as err:
+ print('[ERROR] Exception caught')
+ print('--> ', type(err).__name__, '-', err)
+
+# cogroupmember_view_all() -> dict
+print('### cogroupmember_view_all')
+try:
+ view_all_cogroupmember = api.cogroupmember_view_all()
+ print(json.dumps(view_all_cogroupmember, indent=4))
+except HTTPError as err:
+ print('[ERROR] Exception caught')
+ print('--> ', type(err).__name__, '-', err)
+
+# cogroupmember_view_per_group(group_id: int) -> dict
+print('### cogroupmember_view_per_group')
+try:
+ view_per_group_cogroupmember = api.cogroupmember_view_per_group(
+ group_id=CO_GROUP_ID
+ )
+ print(json.dumps(view_per_group_cogroupmember, indent=4))
+except HTTPError as err:
+ print('[ERROR] Exception caught')
+ print('--> ', type(err).__name__, '-', err)
+
+# cogroupmember_view_one() -> dict
+print('### cogroupmember_view_one')
+try:
+ view_one_cogroupmember = api.cogroupmember_view_one()
+ print(json.dumps(view_one_cogroupmember, indent=4))
+except HTTPError as err:
+ print('[ERROR] Exception caught')
+ print('--> ', type(err).__name__, '-', err)