Skip to content

Commit 8a53ea0

Browse files
committed
Initial WebhooksAPI wrapper
Add wrapper classes for the Cisco Spark Webhooks-API.
1 parent ca98b8b commit 8a53ea0

File tree

2 files changed

+272
-0
lines changed

2 files changed

+272
-0
lines changed

ciscosparkapi/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from api.messages import Message, MessagesAPI
77
from api.teams import Team, TeamsAPI
88
from api.teammemberships import TeamMembership, TeamMembershipsAPI
9+
from api.webhooks import Webhook, WebhooksAPI
910

1011
class CiscoSparkAPI(object):
1112
"""Cisco Spark API wrapper class."""
@@ -31,6 +32,7 @@ def __init__(self, access_token, base_url=None, timeout=None):
3132
self.messages = MessagesAPI(self.session)
3233
self.teams = TeamsAPI(self.session)
3334
self.team_memberships = TeamMembershipsAPI(self.session)
35+
self.webhooks = WebhooksAPI(self.session)
3436

3537
@property
3638
def access_token(self):

ciscosparkapi/api/webhooks.py

Lines changed: 270 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,270 @@
1+
"""Cisco Spark Webhooks-API wrapper classes.
2+
3+
Classes:
4+
Webhook: Models a Spark 'webhook' JSON object as a native Python object.
5+
WebhooksAPI: Wrappers the Cisco Spark Webhooks-API and exposes the API
6+
calls as Python method calls that return native Python objects.
7+
8+
"""
9+
10+
11+
from ciscosparkapi.exceptions import ciscosparkapiException
12+
from ciscosparkapi.helper import utf8, generator_container
13+
from ciscosparkapi.restsession import RestSession
14+
from ciscosparkapi.sparkdata import SparkData
15+
16+
17+
class Webhook(SparkData):
18+
"""Model a Spark 'webhook' JSON object as a native Python object."""
19+
20+
def __init__(self, json):
21+
"""Init a new Webhook data object from a JSON dictionary or string.
22+
23+
Args:
24+
json(dict, unicode, str): Input JSON object.
25+
26+
Raises:
27+
TypeError: If the input object is not a dictionary or string.
28+
29+
"""
30+
super(Webhook, self).__init__(json)
31+
32+
@property
33+
def id(self):
34+
"""Webhook ID."""
35+
return self._json.get(u'id')
36+
37+
@property
38+
def name(self):
39+
"""A user-friendly name for this webhook."""
40+
return self._json.get(u'name')
41+
42+
@property
43+
def targetUrl(self):
44+
"""The URL that receives POST requests for each event."""
45+
return self._json.get(u'targetUrl')
46+
47+
@property
48+
def resource(self):
49+
"""The resource type for the webhook."""
50+
return self._json.get(u'resource')
51+
52+
@property
53+
def event(self):
54+
"""The event type for the webhook."""
55+
return self._json.get(u'event')
56+
57+
@property
58+
def filter(self):
59+
"""The filter that defines the webhook scope."""
60+
return self._json.get(u'filter')
61+
62+
@property
63+
def secret(self):
64+
"""Secret used to generate payload signature."""
65+
return self._json.get(u'secret')
66+
67+
@property
68+
def created(self):
69+
"""Creation date and time in ISO8601 format."""
70+
return self._json.get(u'created')
71+
72+
@property
73+
def data(self):
74+
"""The object representation of the resource triggering the webhook.
75+
76+
The data property contains the object representation of the resource
77+
that triggered the webhook. For example, if you registered a webhook
78+
that triggers when messages are created (i.e. posted into a room) then
79+
the data property will contain the representation for a message
80+
resource, as specified in the Messages API documentation.
81+
82+
"""
83+
object_data = self._json.get(u'data', None)
84+
if object_data:
85+
return SparkData(object_data)
86+
else:
87+
return None
88+
89+
90+
class WebhooksAPI(object):
91+
"""Cisco Spark Webhooks-API wrapper class.
92+
93+
Wrappers the Cisco Spark Webhooks-API and exposes the API calls as Python
94+
method calls that return native Python objects.
95+
96+
Attributes:
97+
session(RestSession): The RESTful session object to be used for API
98+
calls to the Cisco Spark service.
99+
100+
"""
101+
102+
def __init__(self, session):
103+
"""Init a new WebhooksAPI object with the provided RestSession.
104+
105+
Args:
106+
session(RestSession): The RESTful session object to be used for
107+
API calls to the Cisco Spark service.
108+
109+
Raises:
110+
AssertionError: If the parameter types are incorrect.
111+
112+
"""
113+
assert isinstance(session, RestSession)
114+
super(WebhooksAPI, self).__init__()
115+
self.session = session
116+
117+
@generator_container
118+
def list(self, max=None):
119+
"""List all of the authenticated user's webhooks.
120+
121+
This method supports Cisco Spark's implementation of RFC5988 Web
122+
Linking to provide pagination support. It returns a generator
123+
container that incrementally yields all webhooks returned by the
124+
query. The generator will automatically request additional 'pages' of
125+
responses from Spark as needed until all responses have been returned.
126+
The container makes the generator safe for reuse. A new API call will
127+
be made, using the same parameters that were specified when the
128+
generator was created, every time a new iterator is requested from the
129+
container.
130+
131+
Args:
132+
max(int): Limits the maximum number of webhooks returned from the
133+
Spark service per request.
134+
135+
Yields:
136+
Webhook: The the next webhook from the Cisco Spark query.
137+
138+
Raises:
139+
AssertionError: If the parameter types are incorrect.
140+
SparkApiError: If the Cisco Spark cloud returns an error.
141+
142+
"""
143+
# Process args
144+
assert max is None or isinstance(max, int)
145+
params = {}
146+
if max:
147+
params[u'max'] = max
148+
# API request - get items
149+
items = self.session.get_items('webhooks', params=params)
150+
# Yield Webhook objects created from the returned items JSON objects
151+
for item in items:
152+
yield Webhook(item)
153+
154+
def create(self, name, targetUrl, resource, event,
155+
filter=None, secret=None):
156+
"""Create a webhook.
157+
158+
Args:
159+
name(unicode, str): A user-friendly name for this webhook.
160+
targetUrl(unicode, str): The URL that receives POST requests for
161+
each event.
162+
resource(unicode, str): The resource type for the webhook.
163+
event(unicode, str): The event type for the webhook.
164+
filter(unicode, str): The filter that defines the webhook scope.
165+
secret(unicode, str): secret used to generate payload signature.
166+
167+
Returns:
168+
Webhook: With the details of the created webhook.
169+
170+
Raises:
171+
AssertionError: If the parameter types are incorrect.
172+
SparkApiError: If the Cisco Spark cloud returns an error.
173+
174+
"""
175+
# Process args
176+
assert isinstance(name, basestring)
177+
assert isinstance(targetUrl, basestring)
178+
assert isinstance(resource, basestring)
179+
assert isinstance(event, basestring)
180+
assert filter is None or isinstance(filter, basestring)
181+
assert secret is None or isinstance(secret, basestring)
182+
post_data = {}
183+
post_data[u'name'] = utf8(name)
184+
post_data[u'targetUrl'] = utf8(targetUrl)
185+
post_data[u'resource'] = utf8(resource)
186+
post_data[u'event'] = utf8(event)
187+
if filter:
188+
post_data[u'filter'] = utf8(filter)
189+
if secret:
190+
post_data[u'secret'] = utf8(secret)
191+
# API request
192+
json_obj = self.session.post('webhooks', json=post_data)
193+
# Return a Webhook object created from the response JSON data
194+
return Webhook(json_obj)
195+
196+
def get(self, webhookId):
197+
"""Get the details of a webhook, by ID.
198+
199+
Args:
200+
webhookId(unicode, str): The webhookId of the webhook.
201+
202+
Returns:
203+
Webhook: With the details of the requested webhook.
204+
205+
Raises:
206+
AssertionError: If the parameter types are incorrect.
207+
SparkApiError: If the Cisco Spark cloud returns an error.
208+
209+
"""
210+
# Process args
211+
assert isinstance(webhookId, basestring)
212+
# API request
213+
json_obj = self.session.get('webhooks/' + webhookId)
214+
# Return a Webhook object created from the response JSON data
215+
return Webhook(json_obj)
216+
217+
def update(self, webhookId, **update_attributes):
218+
"""Update details for a webhook.
219+
220+
Args:
221+
webhookId(unicode, str): The webhookId of the webhook to be
222+
updated.
223+
224+
**update_attributes:
225+
name(unicode, str): A user-friendly name for this webhook.
226+
targetUrl(unicode, str): The URL that receives POST requests
227+
for each event.
228+
229+
Returns:
230+
Webhook: With the updated Spark webhook details.
231+
232+
Raises:
233+
AssertionError: If the parameter types are incorrect.
234+
ciscosparkapiException: If an update attribute is not provided.
235+
SparkApiError: If the Cisco Spark cloud returns an error.
236+
237+
"""
238+
# Process args
239+
assert isinstance(webhookId, basestring)
240+
# Process update_attributes keyword arguments
241+
if not update_attributes:
242+
error_message = "At least one **update_attributes keyword " \
243+
"argument must be specified."
244+
raise ciscosparkapiException(error_message)
245+
put_data = {}
246+
for param, value in update_attributes.items():
247+
if isinstance(value, basestring):
248+
value = utf8(value)
249+
put_data[utf8(param)] = value
250+
# API request
251+
json_obj = self.session.post('webhooks/' + webhookId, json=put_data)
252+
# Return a Webhook object created from the response JSON data
253+
return Webhook(json_obj)
254+
255+
def delete(self, webhookId):
256+
"""Delete a webhook.
257+
258+
Args:
259+
webhookId(unicode, str): The webhookId of the webhook to be
260+
deleted.
261+
262+
Raises:
263+
AssertionError: If the parameter types are incorrect.
264+
SparkApiError: If the Cisco Spark cloud returns an error.
265+
266+
"""
267+
# Process args
268+
assert isinstance(webhookId, basestring)
269+
# API request
270+
self.session.delete('webhooks/' + webhookId)

0 commit comments

Comments
 (0)