Skip to content

Commit 080fa43

Browse files
committed
Initial MessagesAPI wrapper
Add wrapper classes for the Cisco Spark Messages-API.
1 parent f7b1a73 commit 080fa43

File tree

2 files changed

+283
-0
lines changed

2 files changed

+283
-0
lines changed

ciscosparkapi/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
from api.people import Person, PeopleAPI
44
from api.rooms import Room, RoomsAPI
55
from api.memberships import Membership, MembershipsAPI
6+
from api.messages import Message, MessagesAPI
67

78
class CiscoSparkAPI(object):
89
"""Cisco Spark API wrapper class."""
@@ -25,6 +26,7 @@ def __init__(self, access_token, base_url=None, timeout=None):
2526
self.people = PeopleAPI(self.session)
2627
self.rooms = RoomsAPI(self.session)
2728
self.memberships = MembershipsAPI(self.session)
29+
self.messages = MessagesAPI(self.session)
2830

2931
@property
3032
def access_token(self):

ciscosparkapi/api/messages.py

Lines changed: 281 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,281 @@
1+
"""Cisco Spark Messages-API wrapper classes.
2+
3+
Classes:
4+
Message: Models a Spark 'message' JSON object as a native Python object.
5+
MessagesAPI: Wrappers the Cisco Spark Messages-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 Message(SparkData):
18+
"""Model a Spark 'message' JSON object as a native Python object."""
19+
20+
def __init__(self, json):
21+
"""Init a new Message 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(Message, self).__init__(json)
31+
32+
@property
33+
def id(self):
34+
return self._json[u'id']
35+
36+
@property
37+
def roomId(self):
38+
return self._json[u'roomId']
39+
40+
@property
41+
def roomType(self):
42+
return self._json[u'roomType']
43+
44+
@property
45+
def toPersonId(self):
46+
"""Optional attribute; returns None if not present."""
47+
return self._json.get(u'toPersonId')
48+
49+
@property
50+
def toPersonEmail(self):
51+
"""Optional attribute; returns None if not present."""
52+
return self._json.get(u'toPersonEmail')
53+
54+
@property
55+
def text(self):
56+
"""Optional attribute; returns None if not present."""
57+
return self._json.get(u'text')
58+
59+
@property
60+
def markdown(self):
61+
"""Optional attribute; returns None if not present."""
62+
return self._json.get(u'markdown')
63+
64+
65+
@property
66+
def files(self):
67+
"""Optional attribute; returns None if not present."""
68+
return self._json.get(u'files')
69+
70+
71+
@property
72+
def personId(self):
73+
return self._json[u'personId']
74+
75+
76+
@property
77+
def personEmail(self):
78+
return self._json[u'personEmail']
79+
80+
81+
@property
82+
def created(self):
83+
return self._json[u'created']
84+
85+
@property
86+
def mentionedPeople(self):
87+
"""Optional attribute; returns None if not present."""
88+
return self._json.get(u'mentionedPeople')
89+
90+
91+
class MessagesAPI(object):
92+
"""Cisco Spark Messages-API wrapper class.
93+
94+
Wrappers the Cisco Spark Messages-API and exposes the API calls as Python
95+
method calls that return native Python objects.
96+
97+
Attributes:
98+
session(RestSession): The RESTful session object to be used for API
99+
calls to the Cisco Spark service.
100+
101+
"""
102+
103+
def __init__(self, session):
104+
"""Init a new MessagesAPI object with the provided RestSession.
105+
106+
Args:
107+
session(RestSession): The RESTful session object to be used for
108+
API calls to the Cisco Spark service.
109+
110+
Raises:
111+
AssertionError: If the parameter types are incorrect.
112+
113+
"""
114+
assert isinstance(session, RestSession)
115+
super(MessagesAPI, self).__init__()
116+
self.session = session
117+
118+
@generator_container
119+
def list(self, roomId, mentionedPeople=None, before=None,
120+
beforeMessage=None, max=None):
121+
"""List all messages in a room.
122+
123+
If present, includes the associated media content attachment for each
124+
message. The list sorts the messages in descending order by creation
125+
date.
126+
127+
This method supports Cisco Spark's implementation of RFC5988 Web
128+
Linking to provide pagination support. It returns a generator
129+
container that incrementally yield all messages returned by the
130+
query. The generator will automatically request additional 'pages' of
131+
responses from Spark as needed until all responses have been returned.
132+
The container makes the generator safe for reuse. A new API call will
133+
be made, using the same parameters that were specified when the
134+
generator was created, every time a new iterator is requested from the
135+
container.
136+
137+
Args:
138+
roomId(unicode, str): List messages for the room with roomId.
139+
mentionedPeople(unicode, str): List messages for a person, by
140+
personId or me.
141+
before(unicode, str): List messages sent before a date and time,
142+
in ISO8601 format
143+
beforeMessage(unicode, str): List messages sent before a message,
144+
by message ID
145+
max(int): Limit the maximum number of messages returned from the
146+
Spark service per request.
147+
148+
Yields:
149+
Message: The the next message from the Cisco Spark query.
150+
151+
Raises:
152+
AssertionError: If the parameter types are incorrect.
153+
SparkApiError: If the Cisco Spark cloud returns an error.
154+
155+
"""
156+
# Process args
157+
assert isinstance(roomId, basestring)
158+
assert mentionedPeople is None or \
159+
isinstance(mentionedPeople, basestring)
160+
assert before is None or isinstance(before, basestring)
161+
assert beforeMessage is None or isinstance(beforeMessage, basestring)
162+
assert max is None or isinstance(max, int)
163+
params = {}
164+
params[u'roomId'] = utf8(roomId)
165+
if mentionedPeople:
166+
params[u'mentionedPeople'] = utf8(mentionedPeople)
167+
if before:
168+
params[u'before'] = utf8(before)
169+
if beforeMessage:
170+
params[u'beforeMessage'] = utf8(beforeMessage)
171+
if max:
172+
params[u'max'] = max
173+
# API request - get items
174+
items = self.session.get_items('messages', params=params)
175+
# Yield Message objects created from the returned items JSON objects
176+
for item in items:
177+
yield Message(item)
178+
179+
def create(self, roomId=None, toPersonId=None, toPersonEmail=None,
180+
text=None, markdown=None, files=None):
181+
"""Posts a message to a room.
182+
183+
Posts a message, and optionally, a media content attachment, to a room.
184+
185+
You must specify either a roomId, toPersonId or toPersonEmail when
186+
posting a message, and you must supply some message content (text,
187+
markdown, files).
188+
189+
Args:
190+
roomId(unicode, str): The room ID.
191+
toPersonId(unicode, str): The ID of the recipient when sending a
192+
private 1:1 message.
193+
toPersonEmail(unicode, str): The email address of the recipient
194+
when sending a private 1:1 message.
195+
text(unicode, str): The message, in plain text. If markdown is
196+
speficied this parameter may be optionally used to provide
197+
alternate text forUI clients that do not support rich text.
198+
markdown(unicode, str): The message, in markdown format.
199+
files(list): A list of URL references for the message attachments.
200+
201+
Returns:
202+
Message: With the details of the created message.
203+
204+
Raises:
205+
AssertionError: If the parameter types are incorrect.
206+
ciscosparkapiException: If the required arguments are not
207+
specified.
208+
SparkApiError: If the Cisco Spark cloud returns an error.
209+
210+
"""
211+
# Process args
212+
assert roomId is None or isinstance(roomId, basestring)
213+
assert toPersonId is None or isinstance(toPersonId, basestring)
214+
assert toPersonEmail is None or isinstance(toPersonEmail, basestring)
215+
assert text is None or isinstance(text, basestring)
216+
assert markdown is None or isinstance(markdown, basestring)
217+
assert files is None or isinstance(files, list)
218+
post_data = {}
219+
if roomId:
220+
post_data[u'roomId'] = utf8(roomId)
221+
elif toPersonId:
222+
post_data[u'toPersonId'] = utf8(toPersonId)
223+
elif toPersonEmail:
224+
post_data[u'toPersonEmail'] = utf8(toPersonEmail)
225+
else:
226+
error_message = "You must specify a roomId, toPersonId, or " \
227+
"toPersonEmail to which you want to post a new " \
228+
"message."
229+
raise ciscosparkapiException(error_message)
230+
if not text and not markdown and not files:
231+
error_message = "You must supply some message content (text, " \
232+
"markdown, files) when posting a message."
233+
raise ciscosparkapiException(error_message)
234+
if text:
235+
post_data[u'text'] = utf8(text)
236+
if markdown:
237+
post_data[u'markdown'] = utf8(markdown)
238+
if files:
239+
post_data[u'files'] = utf8(files)
240+
# API request
241+
json_obj = self.session.post('messages', json=post_data)
242+
# Return a Message object created from the response JSON data
243+
return Message(json_obj)
244+
245+
def get(self, messageId):
246+
"""Get the details of a message, by ID.
247+
248+
Args:
249+
messageId(unicode, str): The messageId of the message.
250+
251+
Returns:
252+
Message: With the details of the requested message.
253+
254+
Raises:
255+
AssertionError: If the parameter types are incorrect.
256+
SparkApiError: If the Cisco Spark cloud returns an error.
257+
258+
"""
259+
# Process args
260+
assert isinstance(messageId, basestring)
261+
# API request
262+
json_obj = self.session.get('messages/'+messageId)
263+
# Return a Message object created from the response JSON data
264+
return Message(json_obj)
265+
266+
def delete(self, messageId):
267+
"""Delete a message.
268+
269+
Args:
270+
messageId(unicode, str): The messageId of the message to be
271+
deleted.
272+
273+
Raises:
274+
AssertionError: If the parameter types are incorrect.
275+
SparkApiError: If the Cisco Spark cloud returns an error.
276+
277+
"""
278+
# Process args
279+
assert isinstance(messageId, basestring)
280+
# API request
281+
self.session.delete('messages/'+messageId)

0 commit comments

Comments
 (0)