8000 Merge branch 'conversations' into edge · twilio/twilio-python@ce08b3d · GitHub
[go: up one dir, main page]

Skip to content

Commit ce08b3d

Browse files
author
Carlos Diaz-Padron
committed
Merge branch 'conversations' into edge
2 parents 9f62d18 + dbdb4a8 commit ce08b3d

File tree

13 files changed

+321
-1
lines changed

13 files changed

+321
-1
lines changed

tests/conversations/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+

tests/conversations/test_client.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
from mock import patch
2+
3+
from tests.tools import create_mock_json
4+
from twilio.rest.conversations import TwilioConversationsClient
5+
6+
7+
@patch("twilio.rest.resources.base.make_twilio_request")
8+
def test_conversations(mock):
9+
client = TwilioConversationsClient("ACCOUNT_SID", "AUTH_TOKEN")
10+
resp = create_mock_json("tests/resources/conversations/conversation_instance.json")
11+
mock.return_value = resp
12+
client.conversations.get("CV4bbc4afc943cd2a5d29f0ce01c5656db")
13+
uri = "https://conversations.twilio.com/v1/Conversations/CV4bbc4afc943cd2a5d29f0ce01c5656db"
14+
mock.assert_called_with("GET", uri, auth=("ACCOUNT_SID", "AUTH_TOKEN"), use_json_extension=False)
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import unittest
2+
3+
from mock import patch
4+
5+
from tests.tools import create_mock_json
6+
from twilio.rest.resources.conversations.conversations import ConversationsRoot
7+
8+
9+
AUTH = ("AC123", "token")
10+
BASE_URI = "https://conversations.twilio.com/v1"
11+
CONVERSATION_SID = "CVaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
12+
13+
14+
class ConversationTest(unittest.TestCase):
15+
@patch('twilio.rest.resources.base.make_twilio_request')
16+
def test_get(self, request):
17+
resp = create_mock_json('tests/resources/conversations/conversation_instance.json')
18+
resp.status_code = 200
19+
request.return_value = resp
20+
21+
uri = "{0}/Conversations/{1}".format(BASE_URI, CONVERSATION_SID)
22+
list_resource = ConversationsRoot(BASE_URI, AUTH)
23+
list_resource.get(CONVERSATION_SID)
24+
request.assert_called_with("GET", uri, use_json_extension=False, auth=AUTH)
25+
26+
@patch('twilio.rest.resources.base.make_twilio_request')
27+
def test_list_in_progress(self, request):
28+
resp = create_mock_json('tests/resources/conversations/conversation_list.json')
29+
resp.status_code = 200
30+
request.return_value = resp
31+
32+
uri = "{0}/Conversations/InProgress".format(BASE_URI)
33+
list_resource = ConversationsRoot(BASE_URI, AUTH)
34+
list_resource.in_progress.list()
35+
request.assert_called_with("GET", uri, params={}, auth=AUTH, use_json_extension=False)
36+
37+
@patch('twilio.rest.resources.base.make_twilio_request')
38+
def test_list_completed(self, request):
39+
resp = create_mock_json('tests/resources/conversations/conversation_list.json')
40+
resp.status_code = 200
41+
request.return_value = resp
42+
43+
uri = "{0}/Conversations/Completed".format(BASE_URI)
44+
list_resource = ConversationsRoot(BASE_URI, AUTH)
45+
list_resource.completed.list()
46+
request.assert_called_with("GET", uri, params={}, auth=AUTH, use_json_extension=False)
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import unittest
2+
3+
from mock import patch
4+
5+
from tests.tools import create_mock_json
6+
from twilio.rest.resources.conversations.participants import Participants
7+
8+
9+
AUTH = ("AC123", "token")
10+
BASE_URI = "https://conversations.twilio.com/v1"
11+
CONVERSATION_SID = "CVaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
12+
PARTICIPANT_SID = "PAaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
13+
14+
15+
class ParticipantTest(unittest.TestCase):
16+
@patch('twilio.rest.resources.base.make_twilio_request')
17+
def test_get(self, request):
18+
resp = create_mock_json('tests/resources/conversations/participant_instance.json')
19+
resp.status_code = 200
20+
request.return_value = resp
21+
22+
uri = "{0}/Conversations/{1}".format(BASE_URI, CONVERSATION_SID)
23+
expected = "{0}/Participants/{1}".format(uri, PARTICIPANT_SID)
24+
list_resource = Participants(uri, AUTH)
25+
list_resource.get(PARTICIPANT_SID)
26+
request.assert_called_with("GET", expected, use_json_extension=False, auth=AUTH)
27+
28+
@patch('twilio.rest.resources.base.make_twilio_request')
29+
def test_list_in_progress(self, request):
30+
resp = create_mock_json('tests/resources/conversations/participant_list.json')
31+
resp.status_code = 200
32+
request.return_value = resp
33+
34+
uri = "{0}/Conversations/{1}".format(BASE_URI, CONVERSATION_SID)
35+
expected = "{0}/Participants".format(uri)
36+
list_resource = Participants(uri, AUTH)
37+
list_resource.list()
38+
request.assert_called_with("GET", expected, params={}, auth=AUTH, use_json_extension=False)
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"links": {
3+
"participants": "htt 10000 ps://conversations.stage.twilio.com/v1/Conversations/CV4bbc4afc943cd2a5d29f0ce01c5656db/Participants"
4+
},
5+
"sid": "CV4bbc4afc943cd2a5d29f0ce01c5656db",
6+
"status": "created",
7+
"account_sid": "AC998c10b68cbfda9f67277f7d8f4439c9",
8+
"date_created": "2015-05-12T21:13:15Z",
9+
"start_time": "2015-05-12T21:13:15Z",
10+
"end_time": "2015-05-12T21:14:15Z",
11+
"duration": 60,
12+
"url": "https://conversations.stage.twilio.com/v1/Conversations/CV4bbc4afc943cd2a5d29f0ce01c5656db"
13+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
{
2+
"meta": {
3+
"key": "conversations",
4+
"next_page_url": null,
5+
"url": "https://conversations.stage.twilio.com/v1/Conversations/Completed?PageSize=50&Page=0",
6+
"previous_page_url": null,
7+
"first_page_url": "https://conversations.stage.twilio.com/v1/Conversations/Completed?PageSize=50&Page=0",
8+
"page_size": 50,
9+
"page": 0
10+
},
11+
"conversations": [
12+
{
13+
"links": {
14+
"participants": "https://conversations.stage.twilio.com/v1/Conversations/CV5cd9d2f155da05660b5d487b1b69e27d/Participants"
15+
},
16+
"sid": "CV5cd9d2f155da05660b5d487b1b69e27d",
17+
"status": "completed",
18+
"account_sid": "AC998c10b68cbfda9f67277f7d8f4439c9",
19+
"date_created": "2015-05-12T21:08:50Z",
20+
"start_time": "2015-05-12T21:08:50Z",
21+
"end_time": "2015-05-12T21:09:50Z",
22+
"duration": 60,
23+
"url": "https://conversations.stage.twilio.com/v1/Conversations/CV5cd9d2f155da05660b5d487b1b69e27d"
24+
},
25+
{
26+
"links": {
27+
"participants": "https://conversations.stage.twilio.com/v1/Conversations/CV878937a518876bece719861b02a4984a/Participants"
28+
},
29+
"sid": "CV878937a518876bece719861b02a4984a",
30+
"status": "completed",
31+
"account_sid": "AC998c10b68cbfda9f67277f7d8f4439c9",
32+
"date_created": "2015-05-12T16:57:03Z",
33+
"start_time": "2015-05-12T16:57:03Z",
34+
"end_time": "2015-05-12T16:58:03Z",
35+
"duration": 60,
36+
"url": "https://conversations.stage.twilio.com/v1/Conversations/CV878937a518876bece719861b02a4984a"
37+
}
38+
]
39+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"url": "https://conversations.stage.twilio.com/v1/Conversations/CVe42fecfaefadbb03cbe27d94e4cef8c2/Participants/PA97239ce0bff1491fa82986a543bcd9c9",
3+
"account_sid": "AC998c10b68cbfda9f67277f7d8f4439c9",
4+
"sid": "PA97239ce0bff1491fa82986a543bcd9c9",
5+
"address": "torkel2@AC998c10b68cbfda9f67277f7d8f4439c9.endpoint.twilio.com",
6+
"status": "disconnected",
7+
"conversation_sid": "CVe42fecfaefadbb03cbe27d94e4cef8c2",
8+
"date_created": "2015-05-13T23:03:12Z",
9+
"start_time": "2015-05-13T23:03:15Z",
10+
"end_time": "2015-05-13T23:14:40Z",
11+
"duration": 685
12+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
{
2+
"meta": {
3+
"key": "participants",
4+
"next_page_url": null,
5+
"url": "https://conversations.stage.twilio.com/v1/Conversations/CVe42fecfaefadbb03cbe27d94e4cef8c2/Participants?PageSize=50&Page=0",
6+
"previous_page_url": null,
7+
"first_page_url": "https://conversations.stage.twilio.com/v1/Conversations/CVe42fecfaefadbb03cbe27d94e4cef8c2/Participants?PageSize=50&Page=0",
8+
"page_size": 50,
9+
"page": 0
10+
},
11+
"participants": [
12+
{
13+
"url": "https://conversations.stage.twilio.com/v1/Conversations/CVe42fecfaefadbb03cbe27d94e4cef8c2/Participants/PA97239ce0bff1491fa82986a543bcd9c9",
14+
"account_sid": "AC998c10b68cbfda9f67277f7d8f4439c9",
15+
"sid": "PA97239ce0bff1491fa82986a543bcd9c9",
16+
"address": "torkel2@AC998c10b68cbfda9f67277f7d8f4439c9.endpoint.twilio.com",
17+
"status": "disconnected",
18+
"conversation_sid": "CVe42fecfaefadbb03cbe27d94e4cef8c2",
19+
"date_created": "2015-05-13T23:03:12Z",
20+
"start_time": "2015-05-13T23:03:15Z",
21+
"end_time": "2015-05-13T23:14:40Z",
22+
"duration": 685
23+
},
24+
{
25+
"url": "https://conversations.stage.twilio.com/v1/Conversations/CVe42fecfaefadbb03cbe27d94e4cef8c2/Participants/PA78810fba996f4087c8894b801669b9b2",
26+
"account_sid": "AC998c10b68cbfda9f67277f7d8f4439c9",
27+
"sid": "PA78810fba996f4087c8894b801669b9b2",
28+
"address": "torkel1@AC998c10b68cbfda9f67277f7d8f4439c9.endpoint.twilio.com",
29+
"status": "disconnected",
30+
"conversation_sid": "CVe42fecfaefadbb03cbe27d94e4cef8c2",
31+
"date_created": "2015-05-13T23:03:12Z",
32+
"start_time": "2015-05-13T23:03:15Z",
33+
"end_time": "2015-05-13T23:14:40Z",
34+
"duration": 685
35+
}
36+
]
37+
}

twilio/rest/conversations.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
from twilio.rest.base import TwilioClient
2+
from twilio.rest.resources import UNSET_TIMEOUT
3+
from twilio.rest.resources.conversations.conversations import ConversationsRoot
4+
5+
6+
class TwilioConversationsClient(TwilioClient):
7+
"""
8+
A client for accessing the Twilio Conversations API.
9+
10+
XXX more verbiage here
11+
12+
:param str account: Your Account Sid from `your dashboard
13+
<https://www.twilio.com/user/account>`_
14+
:param str token: Your Auth Token from `your dashboard
15+
<https://www.twilio.com/user/account>`_
16+
:param float timeout: The socket and read timeout for requests to Twilio
17+
"""
18+
19+
def __init__(self, account=None, token=None,
20+
base="https://conversations.twilio.com", version="v1",
21+
timeout=UNSET_TIMEOUT):
22+
23+
super(TwilioConversationsClient, self).__init__(account, token, base,
24+
version, timeout)
25+
26+
self.version_uri = "%s/%s" % (base, version)
27+
self.conversations = ConversationsRoot(self.version_uri, self.auth,
28+
timeout)

twilio/rest/resources/base.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,7 @@ def load(self, entries):
244244
del entries["uri"]
245245

246246
for key in entries.keys():
247-
if (key.startswith("date_") and
247+
if ((key.startswith("date_") or key.endswith("_time")) and
248248
isinstance(entries[key], string_types)):
249249
entries[key] = self._parse_date(entries[key])
250250

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
from twilio.rest.resources import NextGenInstanceResource, NextGenListResource
2+
3+
4+
class ConversationsRoot(object):
5+
6+
def __init__(self, base_uri, *args, **kwargs):
7+
self.uri = "%s/Conversations" % base_uri
8+
self._instance_base = Conversations(self.uri, *args, **kwargs)
9+
self.in_progress = Conversations("%s/InProgress" % self.uri, *args,
10+
10000 **kwargs)
11+
self.completed = Conversations("%s/Completed" % self.uri, *args,
12+
**kwargs)
13+
14+
def get(self, sid):
15+
return self._instance_base.get(sid)
16+
17+
def delete_instance(self, sid):
18+
return self._instance_base.delete_instance(sid)
19+
20+
21+
class Conversation(NextGenInstanceResource):
22+
"""A Conversation instance representing a call between two or more participants.
23+
24+
.. attribute:: sid
25+
26+
.. attribute:: account_sid
27+
28+
.. attribute:: status
29+
30+
.. attribute:: date_created
31+
32+
.. attribute:: start_time
33+
34+
.. attribute:: end_time
35+
36+
.. attribute:: duration
37+
38+
.. attribute:: url
39+
"""
40+
pass
41+
42+
43+
class Conversations(NextGenListResource):
44+
45+
name = "Conversations"
46+
instance = Conversation
47+
48+
def __init__(self, uri, *args, **kwargs):
49+
super(Conversations, self).__init__(uri, *args, **kwargs)
50+
# This list is exposed at two different locations: /InProgress
51+
# and /Completed. The parent Root object will hand us the full URL
52+
# to set up at.
53+
self._uri = uri
54+
55+
@property
56+
def uri(self):
57+
return self._uri
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
from twilio.rest.resources import NextGenInstanceResource, NextGenListResource
2+
3+
4+
class Participant(NextGenInstanceResource):
5+
"""A participant in a Conversation.
6+
7+
.. attribute:: sid
8+
9+
.. attribute:: conversation_sid
10+
11+
.. attribute:: account_sid
12+
13+
.. attribute:: status
14+
15+
.. attribute:: address
16+
17+
.. attribute:: date_created
18+
19+
.. attribute:: start_time
20+
21+
.. attribute:: end_time
22+
23+
.. attribute:: duration
24+
25+
.. attribute:: url
26+
"""
27+
pass
28+
29+
30+
class Participants(NextGenListResource):
31+
"""A list of :class:`Participant` objects."""
32+
33+
name = "Participants"
34+
instance = Participant

0 commit comments

Comments
 (0)
0