8000 Merge pull request #124 from Roguelazer/expose_timeouts · Web5design/twilio-python@1afcbfd · GitHub
[go: up one dir, main page]

Skip to content

Commit 1afcbfd

Browse files
committed
Merge pull request twilio#124 from Roguelazer/expose_timeouts
Expose timeouts
2 parents 6d72166 + e6d6817 commit 1afcbfd

File tree

10 files changed

+131
-47
lines changed

10 files changed

+131
-47
lines changed

tests/test_available_phonenumber.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
from twilio.rest.resources import AvailablePhoneNumber
1212
from twilio.rest.resources import AvailablePhoneNumbers
1313
from twilio.rest.resources import PhoneNumbers
14+
from twilio.rest.resources import UNSET_TIMEOUT
1415

1516

1617
class AvailablePhoneNumberTest(unittest.TestCase):
@@ -35,7 +36,7 @@ class AvailabePhoneNumbersTest(unittest.TestCase):
3536

3637
def setUp(self):
3738
self.resource = AvailablePhoneNumbers("http://api.twilio.com",
38-
("user", "pass"), Mock())
39+
("user", "pass"), UNSET_TIMEOUT, Mock())
3940

4041
def test_get(self):
4142
with self.assertRaises(TwilioException):

tests/test_base_resource.py

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,9 @@
66
else:
77
import unittest2 as unittest
88

9-
from mock import Mock
9+
from mock import Mock, sentinel, patch, ANY
1010
from nose.tools import assert_equal, assert_true
11+
from twilio.rest.resources.imports import json
1112
from twilio.rest.resources import Resource
1213
from twilio.rest.resources import ListResource
1314
from twilio.rest.resources import InstanceResource
@@ -127,4 +128,29 @@ def testLoadSubresources(self):
127128
m = Mock()
128129
self.r.subresources = [m]
129130
self.r.load_subresources()
130-
m.assert_called_with(self.r.uri, self.r.auth)
131+
m.assert_called_with(self.r.uri, self.r.auth, self.r.timeout)
132+
133+
134+
class testTimeoutPropagation(unittest.TestCase):
135+
def setUp(self):
136+
self.parent = ListResource(base_uri, auth, timeout=sentinel.timeout)
137+
self.r = InstanceResource(self.parent, "123")
138+
self.uri = "%s/%s" % (self.parent.uri, "123")
139+
140+
@patch('twilio.rest.resources.base.make_request')
141+
def testPassThrough(self, mock_request):
142+
mock_response = Mock()
143+
mock_response.ok = True,
144+
mock_response.content = json.dumps({'key': 'value'})
145+
mock_request.return_value = mock_response
146+
147+
self.assertEquals(self.r.timeout, sentinel.timeout)
148+
self.assertEquals((mock_response, {'key': 'value'}), self.r.request('GET', base_uri))
149+
150+
mock_request.assert_called_once_with(
151+
'GET',
152+
base_uri + '.json',
153+
headers=ANY,
154+
timeout=sentinel.timeout,
155+
auth=ANY
156+
)

tests/test_client.py

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,9 @@
44
else:
55
import unittest2 as unittest
66

7+
from twilio.rest.resources.imports import json
78
from twilio.rest import TwilioRestClient, resources
8-
from mock import patch, Mock
9+
from mock import patch, Mock, sentinel, ANY
910
from tools import create_mock_json
1011

1112
AUTH = ("ACCOUNT_SID", "AUTH_TOKEN")
@@ -46,3 +47,24 @@ def test_members(self, mock):
4647
self.client.members("QU123").list()
4748
uri = "https://api.twilio.com/2010-04-01/Accounts/ACCOUNT_SID/Queues/QU123/Members"
4849
mock.assert_called_with("GET", uri, params={}, auth=AUTH)
50+
51+
52+
class RestClientTimeoutTest(unittest.TestCase):
53+
def setUp(self):
54+
self.client = TwilioRestClient("ACCOUNT_SID", "AUTH_TOKEN", timeout=sentinel.timeout)
55+
56+
@patch("twilio.rest.resources.base.make_twilio_request")
57+
def test_members(self, mock_request):
58+
resp = create_mock_json("tests/resources/members_list.json")
59+
mock_request.return_value = resp
60+
self.client.members("QU123").list()
61+
mock_request.assert_called_with("GET", ANY, params=ANY, auth=AUTH, timeout=sentinel.timeout)
62+
63+
@patch("twilio.rest.resources.base.make_twilio_request")
64+
def test_arbitrary_member(self, mock_request):
65+
mock_response = Mock()
66+
mock_response.ok = True
67+
mock_response.content = json.dumps({"short_codes": []})
68+
mock_request.return_value = mock_response
69+
self.assertEqual([], self.client.sms.short_codes.list())
70+
mock_request.assert_called_once_with("GET", ANY, params=ANY, auth=AUTH, timeout=sentinel.timeout)

twilio/rest/__init__.py

Lines changed: 24 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
from twilio.rest.resources import Conferences
2020
from twilio.rest.resources import Sandboxes
2121
from twilio.rest.resources import Usage
22+
from twilio.rest.resources import UNSET_TIMEOUT
2223

2324

2425
def find_credentials():
@@ -86,7 +87,7 @@ def request(self, path, method=None, vars=None):
8687
return resp.content
8788

8889
def __init__(self, account=None, token=None, base="https://api.twilio.com",
89-
version="2010-04-01", client=None):
90+
version="2010-04-01", client=None, timeout=UNSET_TIMEOUT):
9091
"""
9192
Create a Twilio REST API client.
9293
"""
B37A
@@ -116,37 +117,42 @@ def __init__(self, account=None, token=None, base="https://api.twilio.com",
116117
version_uri = "%s/%s" % (base, version)
117118
account_uri = "%s/%s/Accounts/%s" % (base, version, account)
118119

119-
self.accounts = Accounts(version_uri, auth)
120-
self.applications = Applications(account_uri, auth)
121-
self.authorized_connect_apps = AuthorizedConnectApps(account_uri, auth)
122-
self.calls = Calls(account_uri, auth)
123-
self.caller_ids = CallerIds(account_uri, auth)
124-
self.connect_apps = ConnectApps(account_uri, auth)
125-
self.notifications = Notifications(account_uri, auth)
126-
self.recordings = Recordings(account_uri, auth)
127-
self.transcriptions = Transcriptions(account_uri, auth)
128-
self.sms = Sms(account_uri, auth)
129-
self.phone_numbers = PhoneNumbers(account_uri, auth)
130-
self.conferences = Conferences(account_uri, auth)
131-
self.queues = Queues(account_uri, auth)
132-
self.sandboxes = Sandboxes(account_uri, auth)
133-
self.usage = Usage(account_uri, auth)
120+
self.accounts = Accounts(version_uri, auth, timeout)
121+
self.applications = Applications(account_uri, auth, timeout)
122+
self.authorized_connect_apps = AuthorizedConnectApps(
123+
account_uri,
124+
auth,
125+
timeout
126+
)
127+
self.calls = Calls(account_uri, auth, timeout)
128+
self.caller_ids = CallerIds(account_uri, auth, timeout)
129+
self.connect_apps = ConnectApps(account_uri, auth, timeout)
130+
self.notifications = Notifications(account_uri, auth, timeout)
131+
self.recordings = Recordings(account_uri, auth, timeout)
132+
self.transcriptions = Transcriptions(account_uri, auth, timeout)
133+
self.sms = Sms(account_uri, auth, timeout)
134+
self.phone_numbers = PhoneNumbers(account_uri, auth, timeout)
135+
self.conferences = Conferences(account_uri, auth, timeout)
136+
self.queues = Queues(account_uri, auth, timeout)
137+
self.sandboxes = Sandboxes(account_uri, auth, timeout)
138+
self.usage = Usage(account_uri, auth, timeout)
134139

135140
self.auth = auth
136141
self.account_uri = account_uri
142+
self.timeout = timeout
137143

138144
def participants(self, conference_sid):
139145
"""
140146
Return a :class:`Participants` instance for the :class:`Conference`
141147
with the given conference_sid
142148
"""
143149
base_uri = "%s/Conferences/%s" % (self.account_uri, conference_sid)
144-
return Participants(base_uri, self.auth)
150+
return Participants(base_uri, self.auth, self.timeout)
145151

146152
def members(self, queue_sid):
147153
"""
148154
Return a :class:`Members` instance for the :class:`Queue`
149155
with the given queue_sid
150156
"""
151157
base_uri = "%s/Queues/%s" % (self.account_uri, queue_sid)
152-
return Members(base_uri, self.auth)
158+
return Members(base_uri, self.auth, self.timeout)

twilio/rest/resources/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
from twilio.rest.resources.util import (
1212
transform_params, format_name, parse_date, convert_boolean, convert_case,
13-
convert_keys, normalize_dates
13+
convert_keys, normalize_dates, UNSET_TIMEOUT
1414
)
1515
from twilio.rest.resources.base import (
1616
Response, Resource, InstanceResource, ListResource,

twilio/rest/resources/base.py

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
import twilio
77
from twilio import TwilioException, TwilioRestException
8+
from twilio.rest.resources import UNSET_TIMEOUT
89
from twilio.rest.resources.imports import parse_qs, httplib2, json
910
from twilio.rest.resources.util import transform_params, parse_rfc2822_date
1011

@@ -100,9 +101,10 @@ class Resource(object):
100101

101102
name = "Resource"
102103

103-
def __init__(self, base_uri, auth):
104+
def __init__(self, base_uri, auth, timeout=UNSET_TIMEOUT):
104105
self.base_uri = base_uri
105106
self.auth = auth
107+
self.timeout = timeout
106108

107109
def __eq__(self, other):
108110
return (isinstance(other, self.__class__)
@@ -120,6 +122,8 @@ def request(self, method, uri, **kwargs):
120122
121123
Raise a TwilioRestException
122124
"""
125+
if 'timeout' not in kwargs and self.timeout is not UNSET_TIMEOUT:
126+
kwargs['timeout'] = self.timeout
123127
resp = make_twilio_request(method, uri, auth=self.auth, **kwargs)
124128

125129
logging.debug(resp.content)
@@ -143,7 +147,11 @@ class InstanceResource(Resource):
143147
def __init__(self, parent, sid):
144148
self.parent = parent
145149
self.name = sid
146-
super(InstanceResource, self).__init__(parent.uri, parent.auth)
150+
super(InstanceResource, self).__init__(
151+
parent.uri,
152+
parent.auth,
153+
parent.timeout
154+
)
147155

148156
def load(self, entries):
149157
if "from" in entries.keys():
@@ -164,7 +172,11 @@ def load_subresources(self):
164172
Load all subresources
165173
"""
166174
for resource in self.subresources:
167-
list_resource = resource(self.uri, self.parent.auth)
175+
list_resource = resource(
176+
self.uri,
177+
self.parent.auth,
178+
self.parent.timeout
179+
)
168180
self.__dict__[list_resource.key] = list_resource
169181

170182
def update_instance(self, **kwargs):

twilio/rest/resources/phone_numbers.py

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
from twilio import TwilioException
44
from twilio.rest.resources.util import change_dict_key, transform_params
5+
from twilio.rest.resources.util import UNSET_TIMEOUT
56
from twilio.rest.resources import InstanceResource, ListResource
67

78

@@ -25,8 +26,8 @@ class AvailablePhoneNumbers(ListResource):
2526

2627
types = {"local": "Local", "tollfree": "TollFree"}
2728

28-
def __init__(self, base_uri, auth, phone_numbers):
29-
super(AvailablePhoneNumbers, self).__init__(base_uri, auth)
29+
def __init__(self, base_uri, auth, timeout, phone_numbers):
30+
super(AvailablePhoneNumbers, self).__init__(base_uri, auth, timeout)
3031
self.phone_numbers = phone_numbers
3132

3233
def get(self, sid):
@@ -66,7 +67,11 @@ def load(self, entries):
6667
uri = re.sub(r'AC(.*)', entries["account_sid"],
6768
self.parent.base_uri)
6869

69-
self.parent = PhoneNumbers(uri, self.parent.auth)
70+
self.parent = PhoneNumbers(
71+
uri,
72+
self.parent.auth,
73+
self.parent.timeout
74+
)
7075
self.base_uri = self.parent.uri
7176

7277
super(PhoneNumber, self).load(entries)
@@ -107,10 +112,10 @@ class PhoneNumbers(ListResource):
107112
key = "incoming_phone_numbers"
108113
instance = PhoneNumber
109114

110-
def __init__(self, base_uri, auth):
111-
super(PhoneNumbers, self).__init__(base_uri, auth)
115+
def __init__(self, base_uri, auth, timeout=UNSET_TIMEOUT):
116+
super(PhoneNumbers, self).__init__(base_uri, auth, timeout)
112117
self.available_phone_numbers = \
113-
AvailablePhoneNumbers(base_uri, auth, self)
118+
AvailablePhoneNumbers(base_uri, auth, timeout, self)
114119

115120
def delete(self, sid):
116121
"""

twilio/rest/resources/sms_messages.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,10 +61,10 @@ class Sms(object):
6161
name = "SMS"
6262
key = "sms"
6363

64-
def __init__(self, base_uri, auth):
64+
def __init__(self, base_uri, auth, timeout):
6565
self.uri = "%s/SMS" % base_uri
66-
self.messages = SmsMessages(self.uri, auth)
67-
self.short_codes = ShortCodes(self.uri, auth)
66+
self.messages = SmsMessages(self.uri, auth, timeout)
67+
self.short_codes = ShortCodes(self.uri, auth, timeout)
6868

6969

7070
class SmsMessage(InstanceResource):

twilio/rest/resources/usage.py

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
from twilio.rest.resources import InstanceResource, ListResource
2+
from twilio.rest.resources.util import UNSET_TIMEOUT
23

34

45
class UsageTrigger(InstanceResource):
@@ -119,15 +120,15 @@ def load_instance(self, data):
119120

120121
class UsageRecords(BaseUsageRecords):
121122

122-
def __init__(self, base_uri, auth):
123-
super(UsageRecords, self).__init__(base_uri, auth)
124-
self.daily = UsageRecordsDaily(base_uri, auth)
125-
self.monthly = UsageRecordsMonthly(base_uri, auth)
126-
self.yearly = UsageRecordsYearly(base_uri, auth)
127-
self.today = UsageRecordsToday(base_uri, auth)
128-
self.yesterday = UsageRecordsYesterday(base_uri, auth)
129-
self.this_month = UsageRecordsThisMonth(base_uri, auth)
130-
self.last_month = UsageRecordsLastMonth(base_uri, auth)
123+
def __init__(self, base_uri, auth, timeout=UNSET_TIMEOUT):
124+
super(UsageRecords, self).__init__(base_uri, auth, timeout)
125+
self.daily = UsageRecordsDaily(base_uri, auth, timeout)
126+
self.monthly = UsageRecordsMonthly(base_uri, auth, timeout)
127+
self.yearly = UsageRecordsYearly(base_uri, auth, timeout)
128+
self.today = UsageRecordsToday(base_uri, auth, timeout)
129+
self.yesterday = UsageRecordsYesterday(base_uri, auth, timeout)
130+
self.this_month = UsageRecordsThisMonth(base_uri, auth, timeout)
131+
self.last_month = UsageRecordsLastMonth(base_uri, auth, timeout)
131132

132133

133134
class UsageRecordsDaily(BaseUsageRecords):
@@ -173,6 +174,7 @@ class Usage(object):
173174
Holds all the specific Usage list resources
174175
"""
175176

176-
def __init__(self, base_uri, auth):
177-
self.records = UsageRecords(base_uri, auth)
178-
self.triggers = UsageTriggers(base_uri, auth)
177+
def __init__(self, base_uri, auth, timeout=UNSET_TIMEOUT):
178+
self.records = UsageRecords(base_uri, auth, timeout=timeout)
179+
self.triggers = UsageTriggers(base_uri, auth, timeout=timeout< 9CB5 /span>)
180+
self.timeout = timeout

twilio/rest/resources/util.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,3 +121,13 @@ def change_dict_key(d, from_key, to_key):
121121
d[to_key] = d.pop(from_key)
122122
except KeyError:
123123
pass
124+
125+
126+
class _UnsetTimeoutKls(object):
127+
def __repr__(self):
128+
return u'<Timeout Unset>'
129+
130+
131+
# None has special meaning for timeouts, so we use this sigil to indicate
132+
# that we don't care
133+
UNSET_TIMEOUT = _UnsetTimeoutKls()

0 commit comments

Comments
 (0)
0