Skip to content

Commit 6b43188

Browse files
authored
Add wrappers for new Admin API Endpoints (#31)
* #30 Correct REST verb in team_membership.update() Verb should be PUT instead of POST * #20 Add people.create() and people.update() Admin methods Add people.create() and people.update() methods to wrap the new people admin API endpoints. Update the Person properties to reflect new person object attributes. Add property docstrings and have properties return `None` if not present. * #20 Add Organizations Admin API Wrapper Add a wrapper for the new Organizations API endpoints. * #20 Add Licenses Admin API Wrapper Add a wrapper for the new Licenses API endpoints. * #20 Add Roles Admin API Wrapper Add a wrapper for the new Roles API endpoints. * #20 Add the new Admin API wrappers to CiscoSparkAPI Add the new Organizations, Licenses and Roles API wrappers to the CiscoSparkAPI class. * Correct REST verb in memberships.update() Verb should be PUT instead of POST
1 parent 7bfab09 commit 6b43188

23 files changed

+1088
-14
lines changed

ciscosparkapi/__init__.py

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,17 @@
1010

1111
from .exceptions import ciscosparkapiException, SparkApiError
1212
from .restsession import RestSession
13-
from .api.accesstokens import AccessToken, AccessTokensAPI
1413
from .api.people import Person, PeopleAPI
1514
from .api.rooms import Room, RoomsAPI
1615
from .api.memberships import Membership, MembershipsAPI
1716
from .api.messages import Message, MessagesAPI
1817
from .api.teams import Team, TeamsAPI
1918
from .api.teammemberships import TeamMembership, TeamMembershipsAPI
2019
from .api.webhooks import Webhook, WebhooksAPI
20+
from .api.organizations import Organization, OrganizationsAPI
21+
from .api.licenses import License, LicensesAPI
22+
from .api.roles import Role, RolesAPI
23+
from .api.accesstokens import AccessToken, AccessTokensAPI
2124

2225

2326
__author__ = "Chris Lunsford"
@@ -34,6 +37,7 @@
3437

3538
DEFAULT_BASE_URL = 'https://api.ciscospark.com/v1/'
3639
DEFAULT_TIMEOUT = 60
40+
ACCESS_TOKEN_ENVIRONMENT_VARIABLE = 'SPARK_ACCESS_TOKEN'
3741

3842

3943
class CiscoSparkAPI(object):
@@ -60,6 +64,12 @@ class CiscoSparkAPI(object):
6064
6165
:class:`webhooks <WebhooksAPI>`
6266
67+
:class:`organizations <OrganizationsAPI>`
68+
69+
:class:`licenses <LicensesAPI>`
70+
71+
:class:`roles <RolesAPI>`
72+
6373
:class:`access_tokens <AccessTokensAPI>`
6474
6575
"""
@@ -104,7 +114,7 @@ def __init__(self, access_token=None, base_url=DEFAULT_BASE_URL,
104114
assert access_token is None or isinstance(access_token, string_types)
105115
assert isinstance(base_url, string_types)
106116
assert isinstance(timeout, int)
107-
spark_access_token = os.environ.get('SPARK_ACCESS_TOKEN', None)
117+
spark_access_token = os.environ.get(ACCESS_TOKEN_ENVIRONMENT_VARIABLE)
108118
access_token = access_token if access_token else spark_access_token
109119
if not access_token:
110120
error_message = "You must provide an Spark access token to " \
@@ -128,6 +138,9 @@ def __init__(self, access_token=None, base_url=DEFAULT_BASE_URL,
128138
self.teams = TeamsAPI(self._session)
129139
self.team_memberships = TeamMembershipsAPI(self._session)
130140
self.webhooks = WebhooksAPI(self._session)
141+
self.organizations = OrganizationsAPI(self._session)
142+
self.licenses = LicensesAPI(self._session)
143+
self.roles = RolesAPI(self._session)
131144
self.access_tokens = AccessTokensAPI(self.base_url, timeout=timeout)
132145

133146
@property

ciscosparkapi/api/licenses.py

Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
# -*- coding: utf-8 -*-
2+
"""Cisco Spark Licenses API wrapper.
3+
4+
Classes:
5+
License: Models a Spark License JSON object as a native Python object.
6+
LicensesAPI: Wraps the Cisco Spark Licenses API and exposes the
7+
API calls as Python method calls that return native Python objects.
8+
9+
"""
10+
11+
12+
from builtins import object
13+
from six import string_types
14+
15+
from ciscosparkapi.utils import generator_container
16+
from ciscosparkapi.restsession import RestSession
17+
from ciscosparkapi.sparkdata import SparkData
18+
19+
20+
__author__ = "Chris Lunsford"
21+
__author_email__ = "chrlunsf@cisco.com"
22+
__copyright__ = "Copyright (c) 2016 Cisco Systems, Inc."
23+
__license__ = "MIT"
24+
25+
26+
class License(SparkData):
27+
"""Model a Spark License JSON object as a native Python object."""
28+
29+
def __init__(self, json):
30+
"""Init a new License data object from a dict or JSON string.
31+
32+
Args:
33+
json(dict, string_types): Input JSON object.
34+
35+
Raises:
36+
TypeError: If the input object is not a dictionary or string.
37+
38+
"""
39+
super(License, self).__init__(json)
40+
41+
@property
42+
def id(self):
43+
"""The unique id for the License."""
44+
return self._json.get('id')
45+
46+
@property
47+
def name(self):
48+
"""The name of the License."""
49+
return self._json.get('name')
50+
51+
@property
52+
def totalUnits(self):
53+
"""The total number of license units."""
54+
return self._json.get('totalUnits')
55+
56+
@property
57+
def consumedUnits(self):
58+
"""The total number of license units consumed."""
59+
return self._json.get('consumedUnits')
60+
61+
62+
class LicensesAPI(object):
63+
"""Cisco Spark Licenses API wrapper.
64+
65+
Wraps the Cisco Spark Licenses API and exposes the API calls as Python
66+
method calls that return native Python objects.
67+
68+
"""
69+
70+
def __init__(self, session):
71+
"""Init a new LicensesAPI object with the provided RestSession.
72+
73+
Args:
74+
session(RestSession): The RESTful session object to be used for
75+
API calls to the Cisco Spark service.
76+
77+
Raises:
78+
AssertionError: If the parameter types are incorrect.
79+
80+
"""
81+
assert isinstance(session, RestSession)
82+
super(LicensesAPI, self).__init__()
83+
self._session = session
84+
85+
@generator_container
86+
def list(self, orgId=None, max=None):
87+
"""List Licenses.
88+
89+
Optionally filtered by Organization (orgId parameter).
90+
91+
This method supports Cisco Spark's implementation of RFC5988 Web
92+
Linking to provide pagination support. It returns a generator
93+
container that incrementally yields all objects returned by the
94+
query. The generator will automatically request additional 'pages' of
95+
responses from Spark as needed until all responses have been returned.
96+
The container makes the generator safe for reuse. A new API call will
97+
be made, using the same parameters that were specified when the
98+
generator was created, every time a new iterator is requested from the
99+
container.
100+
101+
Args:
102+
orgId(string_types): Filters the returned licenses to only include
103+
those liceses associated with the specified Organization
104+
(orgId).
105+
max(int): Limits the maximum number of entries returned from the
106+
Spark service per request (page size; requesting additional
107+
pages is handled automatically).
108+
109+
Returns:
110+
GeneratorContainer: When iterated, the GeneratorContainer, yields
111+
the objects returned from the Cisco Spark query.
112+
113+
Raises:
114+
AssertionError: If the parameter types are incorrect.
115+
SparkApiError: If the Cisco Spark cloud returns an error.
116+
117+
"""
118+
# Process args
119+
assert orgId is None or isinstance(orgId, string_types)
120+
assert max is None or isinstance(max, int)
121+
params = {}
122+
if orgId:
123+
params['orgId'] = orgId
124+
if max:
125+
params['max'] = max
126+
# API request - get items
127+
items = self._session.get_items('licenses', params=params)
128+
# Yield License objects created from the returned JSON objects
129+
for item in items:
130+
yield License(item)
131+
132+
def get(self, licenseId):
133+
"""Get the details of a License, by id.
134+
135+
Args:
136+
licenseId(string_types): The id of the License.
137+
138+
Returns:
139+
License: With the details of the requested License.
140+
141+
Raises:
142+
AssertionError: If the parameter types are incorrect.
143+
SparkApiError: If the Cisco Spark cloud returns an error.
144+
145+
"""
146+
# Process args
147+
assert isinstance(licenseId, string_types)
148+
# API request
149+
json_obj = self._session.get('licenses/' + licenseId)
150+
# Return a License object created from the returned JSON object
151+
return License(json_obj)

ciscosparkapi/api/memberships.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -260,8 +260,8 @@ def update(self, membershipId, **update_attributes):
260260
"argument must be specified."
261261
raise ciscosparkapiException(error_message)
262262
# API request
263-
json_obj = self._session.post('memberships/' + membershipId,
264-
json=update_attributes)
263+
json_obj = self._session.put('memberships/' + membershipId,
264+
json=update_attributes)
265265
# Return a Membership object created from the response JSON data
266266
return Membership(json_obj)
267267

ciscosparkapi/api/organizations.py

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
# -*- coding: utf-8 -*-
2+
"""Cisco Spark Organizations API wrapper.
3+
4+
Classes:
5+
Organization: Models a Spark Organization JSON object as a native Python
6+
object.
7+
OrganizationsAPI: Wraps the Cisco Spark Organizations API and exposes the
8+
API calls as Python method calls that return native Python objects.
9+
10+
"""
11+
12+
13+
from builtins import object
14+
from six import string_types
15+
16+
from ciscosparkapi.utils import generator_container
17+
from ciscosparkapi.restsession import RestSession
18+
from ciscosparkapi.sparkdata import SparkData
19+
20+
21+
__author__ = "Chris Lunsford"
22+
__author_email__ = "chrlunsf@cisco.com"
23+
__copyright__ = "Copyright (c) 2016 Cisco Systems, Inc."
24+
__license__ = "MIT"
25+
26+
27+
class Organization(SparkData):
28+
"""Model a Spark Organization JSON object as a native Python object."""
29+
30+
def __init__(self, json):
31+
"""Init a new Organization data object from a dict or JSON string.
32+
33+
Args:
34+
json(dict, string_types): Input JSON object.
35+
36+
Raises:
37+
TypeError: If the input object is not a dictionary or string.
38+
39+
"""
40+
super(Organization, self).__init__(json)
41+
42+
@property
43+
def id(self):
44+
"""The unique id for the Organization."""
45+
return self._json.get('id')
46+
47+
@property
48+
def displayName(self):
49+
"""The human-friendly display name of the Organization."""
50+
return self._json.get('displayName')
51+
52+
@property
53+
def created(self):
54+
"""The date and time the Organization was created."""
55+
return self._json.get('created')
56+
57+
58+
class OrganizationsAPI(object):
59+
"""Cisco Spark Organizations API wrapper.
60+
61+
Wraps the Cisco Spark Organizations API and exposes the API calls as Python
62+
method calls that return native Python objects.
63+
64+
"""
65+
66+
def __init__(self, session):
67+
"""Init a new OrganizationsAPI object with the provided RestSession.
68+
69+
Args:
70+
session(RestSession): The RESTful session object to be used for
71+
API calls to the Cisco Spark service.
72+
73+
Raises:
74+
AssertionError: If the parameter types are incorrect.
75+
76+
"""
77+
assert isinstance(session, RestSession)
78+
super(OrganizationsAPI, self).__init__()
79+
self._session = session
80+
81+
@generator_container
82+
def list(self, max=None):
83+
"""List Organizations.
84+
85+
This method supports Cisco Spark's implementation of RFC5988 Web
86+
Linking to provide pagination support. It returns a generator
87+
container that incrementally yields all objects returned by the
88+
query. The generator will automatically request additional 'pages' of
89+
responses from Spark as needed until all responses have been returned.
90+
The container makes the generator safe for reuse. A new API call will
91+
be made, using the same parameters that were specified when the
92+
generator was created, every time a new iterator is requested from the
93+
container.
94+
95+
Args:
96+
max(int): Limits the maximum number of entries returned from the
97+
Spark service per request (page size; requesting additional
98+
pages is handled automatically).
99+
100+
Returns:
101+
GeneratorContainer: When iterated, the GeneratorContainer, yields
102+
the objects returned from the Cisco Spark query.
103+
104+
Raises:
105+
AssertionError: If the parameter types are incorrect.
106+
SparkApiError: If the Cisco Spark cloud returns an error.
107+
108+
"""
109+
# Process args
110+
assert max is None or isinstance(max, int)
111+
params = {}
112+
if max:
113+
params['max'] = max
114+
# API request - get items
115+
items = self._session.get_items('organizations', params=params)
116+
# Yield Organization objects created from the returned JSON objects
117+
for item in items:
118+
yield Organization(item)
119+
120+
def get(self, orgId):
121+
"""Get the details of an Organization, by id.
122+
123+
Args:
124+
orgId(string_types): The id of the Organization.
125+
126+
Returns:
127+
Organization: With the details of the requested Organization.
128+
129+
Raises:
130+
AssertionError: If the parameter types are incorrect.
131+
SparkApiError: If the Cisco Spark cloud returns an error.
132+
133+
"""
134+
# Process args
135+
assert isinstance(orgId, string_types)
136+
# API request
137+
json_obj = self._session.get('organizations/' + orgId)
138+
# Return a Organization object created from the returned JSON object
139+
return Organization(json_obj)

0 commit comments

Comments
 (0)