diff --git a/.travis.yml b/.travis.yml index b280906a2c..1dde2fa18e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,4 +7,8 @@ python: install: - pip install . --use-mirrors - pip install -r requirements.txt --use-mirrors -script: nosetests + - pip install -r tests/requirements.txt --use-mirrors +script: + - flake8 --ignore=F401 twilio + - flake8 --ignore=E123,E126,E128,E501 tests + - nosetests diff --git a/tests/requirements.txt b/tests/requirements.txt index 0817d5dc69..8e9f8fbe9b 100644 --- a/tests/requirements.txt +++ b/tests/requirements.txt @@ -1,8 +1,6 @@ sphinx mock==0.8.0 nose -simplejson -unittest2 coverage nosexcover -six +flake8 diff --git a/tests/test_authorized_connect_apps.py b/tests/test_authorized_connect_apps.py index 606ee5888c..372ed89b9c 100644 --- a/tests/test_authorized_connect_apps.py +++ b/tests/test_authorized_connect_apps.py @@ -25,7 +25,7 @@ def test_get(self, mock): self.resource.get("SID") mock.assert_called_with("GET", "/base/AuthorizedConnectApps/SID", - auth=self.auth) + auth=self.auth) @patch("twilio.rest.resources.base.make_twilio_request") def test_list(self, mock): @@ -34,7 +34,7 @@ def test_list(self, mock): self.resource.list() mock.assert_called_with("GET", "/base/AuthorizedConnectApps", - params={}, auth=self.auth) + params={}, auth=self.auth) def test_load(self): instance = AuthorizedConnectApp(Mock(), "sid") @@ -47,7 +47,7 @@ def test_load(self): "connect_app_company_name": "bar", "connect_app_homepage_url": "http://www.google.com", "uri": "/2010-04-01/Accounts/", - }) + }) self.assertEquals(instance.permissions, ["get-all"]) self.assertEquals(instance.sid, "SID") diff --git a/tests/test_base_resource.py b/tests/test_base_resource.py index ace8c14f71..b50aa83859 100644 --- a/tests/test_base_resource.py +++ b/tests/test_base_resource.py @@ -6,9 +6,8 @@ else: import unittest2 as unittest -from mock import Mock, patch +from mock import Mock from nose.tools import assert_equals -from nose.tools import raises from twilio.rest.resources import Resource from twilio.rest.resources import ListResource from twilio.rest.resources import InstanceResource @@ -27,6 +26,7 @@ def test_resource_init(): assert_equals(r.auth, auth) assert_equals(r.uri, uri) + def test_equivalence(): p = ListResource(base_uri, auth) r1 = p.load_instance({"sid": "AC123"}) @@ -43,7 +43,7 @@ def testListResourceInit(self): uri = "%s/%s" % (base_uri, self.r.name) self.assertEquals(self.r.uri, uri) - def testKeyValue(self): + def testKeyValueLower(self): self.assertEquals(self.r.key, self.r.name.lower()) def testIterNoKey(self): @@ -58,7 +58,7 @@ def testRequest(self): self.r.request.return_value = Mock(), {self.r.key: [{'sid': 'foo'}]} advance_iterator(self.r.iter()) self.r.request.assert_called_with("GET", "https://api.twilio.com/2010-04-01/Resources", params={}) - + def testIterOneItem(self): self.r.request = Mock() self.r.request.return_value = Mock(), {self.r.key: [{'sid': 'foo'}]} @@ -68,24 +68,17 @@ def testIterOneItem(self): with self.assertRaises(StopIteration): advance_iterator(items) - + def testIterNoNextPage(self): self.r.request = Mock() self.r.request.return_value = Mock(), {self.r.key: []} with self.assertRaises(StopIteration): advance_iterator(self.r.iter()) - + def testKeyValue(self): self.r.key = "Hey" self.assertEquals(self.r.key, "Hey") - - def testInstanceLoading(self): - instance = self.r.load_instance({"sid": "foo"}) - - self.assertIsInstance(instance, InstanceResource) - self.assertEquals(instance.sid, "foo") - def testInstanceLoading(self): instance = self.r.load_instance({"sid": "foo"}) @@ -122,4 +115,3 @@ def testLoadSubresources(self): self.r.subresources = [m] self.r.load_subresources() m.assert_called_with(self.r.uri, self.r.auth) - diff --git a/tests/test_client.py b/tests/test_client.py index e87a668ac1..04487d2d61 100644 --- a/tests/test_client.py +++ b/tests/test_client.py @@ -8,9 +8,9 @@ from mock import patch, Mock from tools import create_mock_json - AUTH = ("ACCOUNT_SID", "AUTH_TOKEN") + class RestClientTest(unittest.TestCase): def setUp(self): diff --git a/tests/test_conferences.py b/tests/test_conferences.py index 493ea4e41e..362657589e 100644 --- a/tests/test_conferences.py +++ b/tests/test_conferences.py @@ -5,7 +5,7 @@ import unittest2 as unittest from datetime import date -from mock import patch, Mock +from mock import Mock from twilio.rest.resources import Conferences DEFAULT = { @@ -46,6 +46,3 @@ def test_list_before(self): self.resource.list(created_before=date(2011, 1, 1)) self.params["DateCreated<"] = "2011-01-01" self.resource.get_instances.assert_called_with(self.params) - - - diff --git a/tests/test_core.py b/tests/test_core.py index d1c21b77d3..c1b60ceeea 100644 --- a/tests/test_core.py +++ b/tests/test_core.py @@ -16,33 +16,33 @@ class CoreTest(unittest.TestCase): def test_date(self): - d = date(2009,10,10) + d = date(2009, 10, 10) self.assertEquals(parse_date(d), "2009-10-10") def test_datetime(self): - d = datetime(2009,10,10) + d = datetime(2009, 10, 10) self.assertEquals(parse_date(d), "2009-10-10") def test_string_date(self): d = "2009-10-10" self.assertEquals(parse_date(d), "2009-10-10") - def test_string_date(self): + def test_string_date_none(self): d = None self.assertEquals(parse_date(d), None) - def test_string_date(self): + def test_string_date_false(self): d = False self.assertEquals(parse_date(d), None) def test_fparam(self): d = {"HEY": None, "YOU": 3} - ed = {"YOU":3} + ed = {"YOU": 3} self.assertEquals(transform_params(d), ed) def test_fparam_booleans(self): d = {"HEY": None, "YOU": 3, "Activated": False} - ed = {"YOU":3, "Activated": "false"} + ed = {"YOU": 3, "Activated": "false"} self.assertEquals(transform_params(d), ed) def test_normalize_dates(self): @@ -55,8 +55,8 @@ def foo(on=None, before=None, after=None): "after": after, } - d = foo(on="2009-10-10", before=date(2009,10,10), - after=datetime(2009,10,10)) + d = foo(on="2009-10-10", before=date(2009, 10, 10), + after=datetime(2009, 10, 10)) self.assertEquals(d["on"], "2009-10-10") self.assertEquals(d["after"], "2009-10-10") @@ -88,4 +88,3 @@ def test_convert_keys(self): } self.assertEquals(ed, convert_keys(d)) - diff --git a/tests/test_jwt.py b/tests/test_jwt.py index ec635b6772..a2e2f9fec8 100644 --- a/tests/test_jwt.py +++ b/tests/test_jwt.py @@ -8,6 +8,7 @@ from twilio.util import TwilioCapability + class JwtTest(unittest.TestCase): def assertIn(self, foo, bar, msg=None): @@ -64,7 +65,6 @@ def test_events_with_filters(self): event_uri = "scope:stream:subscribe?path=%2F2010-04-01%2FEvents¶ms=foobar%3Dhey" self.assertEquals(payload["scope"], event_uri) - def test_decode(self): token = TwilioCapability("AC123", "XXXXX") token.allow_client_outgoing("AP123", foobar=3) @@ -106,18 +106,14 @@ def test_decodes_valid_jwt(self): def test_allow_skip_verification(self): right_secret = 'foo' - bad_secret = 'bar' jwt_message = jwt.encode(self.payload, right_secret) decoded_payload = jwt.decode(jwt_message, verify=False) self.assertEqual(decoded_payload, self.payload) def test_no_secret(self): right_secret = 'foo' - bad_secret = 'bar' jwt_message = jwt.encode(self.payload, right_secret) self.assertRaises(jwt.DecodeError, jwt.decode, jwt_message) def test_invalid_crypto_alg(self): self.assertRaises(NotImplementedError, jwt.encode, self.payload, "secret", "HS1024") - - diff --git a/tests/test_make_request.py b/tests/test_make_request.py index 0101af7c4a..f5b3a7ee5c 100644 --- a/tests/test_make_request.py +++ b/tests/test_make_request.py @@ -3,12 +3,6 @@ Uses the awesome httpbin.org to validate responses """ -try: - import json -except ImportError: - import simplejson as json - - import twilio from nose.tools import raises from mock import patch, Mock diff --git a/tests/test_phone_numbers.py b/tests/test_phone_numbers.py index e5633f296f..8e4a9aa9fa 100644 --- a/tests/test_phone_numbers.py +++ b/tests/test_phone_numbers.py @@ -8,8 +8,7 @@ import unittest else: import unittest2 as unittest -from mock import Mock, patch -from twilio import TwilioException +from mock import Mock from twilio.rest.resources import PhoneNumbers from twilio.rest.resources import PhoneNumber @@ -55,7 +54,6 @@ def test_sms_application_sid(self): resource.update_instance.assert_called_with( "SID", {"sms_application_sid": "foo"}) - def test_status_callback_url(self): resource = PhoneNumbers(self.uri, self.auth) resource.update_instance = Mock() @@ -86,8 +84,6 @@ def test_base_uri(self): entry = json.load(f) resource.load(entry) - self.assertEquals(resource.parent.base_uri, + self.assertEquals(resource.parent.base_uri, ("https://api.twilio.com/2010-04-01/Accounts/AC4bf2dafbed59a573" "3d2c1c1c69a83a28")) - - diff --git a/tests/test_twiml.py b/tests/test_twiml.py index c413d91315..2ab01aeec1 100644 --- a/tests/test_twiml.py +++ b/tests/test_twiml.py @@ -34,6 +34,7 @@ def improperAppend(self, verb): self.assertRaises(TwimlException, verb.append, twiml.Sms("")) self.assertRaises(TwimlException, verb.append, twiml.Pause()) + class TestResponse(TwilioTest): def testEmptyResponse(self): @@ -44,6 +45,7 @@ def testResponseAddAttribute(self): r = Response(foo="bar") self.assertEquals(self.strip(r), '') + class TestSay(TwilioTest): def testEmptySay(self): @@ -62,7 +64,7 @@ def testSayHelloWorld(self): def testSayFrench(self): """should say hello monkey""" r = Response() - r.append(twiml.Say(u("n\xe9cessaire et d'autres"))) # it works on python 2.6 with the from __future__ import unicode_literal + r.append(twiml.Say(u("n\xe9cessaire et d'autres"))) # it works on python 2.6 with the from __future__ import unicode_literal self.assertEquals(text_type(r), 'nécessaire et d\'autres') @@ -96,7 +98,7 @@ def testSayConvienceMethod(self): def testSayAddAttribute(self): """add attribute""" - r = twiml.Say("",foo="bar") + r = twiml.Say("", foo="bar") r = self.strip(r) self.assertEquals(r, '') @@ -104,6 +106,7 @@ def testSayBadAppend(self): """ should raise exceptions for wrong appending""" self.improperAppend(twiml.Say("")) + class TestPlay(TwilioTest): def testEmptyPlay(self): @@ -111,7 +114,7 @@ def testEmptyPlay(self): r = Response() r.append(twiml.Play("")) r = self.strip(r) - self.assertEqual(r,'') + self.assertEqual(r, '') def testPlayHello(self): """should play hello monkey""" @@ -136,7 +139,7 @@ def testPlayConvienceMethod(self): def testPlayAddAttribute(self): """add attribute""" - r = twiml.Play("",foo="bar") + r = twiml.Play("", foo="bar") r = self.strip(r) self.assertEquals(r, '') @@ -144,6 +147,7 @@ def testPlayBadAppend(self): """ should raise exceptions for wrong appending""" self.improperAppend(twiml.Play("")) + class TestRecord(TwilioTest): def testRecordEmpty(self): @@ -163,7 +167,7 @@ def testRecordActionMethod(self): def testRecordMaxlengthFinishTimeout(self): """should record with an maxlength, finishonkey, and timeout""" r = Response() - r.append(twiml.Record(timeout=4,finishOnKey="#", maxLength=30)) + r.append(twiml.Record(timeout=4, finishOnKey="#", maxLength=30)) r = self.strip(r) self.assertEquals(r, '') @@ -174,13 +178,6 @@ def testRecordTranscribeCallback(self): r = self.strip(r) self.assertEquals(r, '') - def testRecordMaxlengthFinishTimeout(self): - """should record with an maxlength, finishonkey, and timeout""" - r = Response() - r.addRecord(timeout=4,finishOnKey="#", maxLength=30) - r = self.strip(r) - self.assertEquals(r, '') - def testRecordAddAttribute(self): """add attribute""" r = twiml.Record(foo="bar") @@ -191,6 +188,7 @@ def testRecordBadAppend(self): """ should raise exceptions for wrong appending""" self.improperAppend(twiml.Record()) + class TestRedirect(TwilioTest): def testRedirectEmpty(self): @@ -213,7 +211,7 @@ def testRedirectMethodGetParams(self): def testAddAttribute(self): """add attribute""" - r = twiml.Redirect("",foo="bar") + r = twiml.Redirect("", foo="bar") r = self.strip(r) self.assertEquals(r, '') @@ -231,7 +229,6 @@ def testHangup(self): r = self.strip(r) self.assertEquals(r, '') - def testHangupConvience(self): """should raises exceptions for wrong appending""" r = Response() @@ -278,6 +275,7 @@ def testBadAppend(self): """ should raise exceptions for wrong appending""" self.improperAppend(twiml.Reject()) + class TestSms(TwilioTest): def testEmpty(self): @@ -476,11 +474,10 @@ def testAddConferenceConvenceMethod(self): def testAddAttribute(self): """add attribute""" - r = twiml.Conference("MyRoom",foo="bar") + r = twiml.Conference("MyRoom", foo="bar") r = self.strip(r) self.assertEquals(r, 'MyRoom') - def testBadAppend(self): """ should raise exceptions for wrong appending""" self.improperAppend(twiml.Conference("Hello")) @@ -513,7 +510,6 @@ def testNestedSayPlayPause(self): r = self.strip(r) self.assertEquals(r, 'Heyhey.mp3') - def testNestedSayPlayPauseConvience(self): """ a gather with a say, play, and pause""" r = Response() diff --git a/tests/tools.py b/tests/tools.py index f1e3ac4292..070853ba67 100644 --- a/tests/tools.py +++ b/tests/tools.py @@ -1,6 +1,7 @@ from __future__ import with_statement from mock import Mock + def create_mock_json(path): with open(path) as f: resp = Mock() diff --git a/twilio/jwt/__init__.py b/twilio/jwt/__init__.py index 8c04448293..edb4062433 100644 --- a/twilio/jwt/__init__.py +++ b/twilio/jwt/__init__.py @@ -7,6 +7,8 @@ import hashlib import hmac from six import text_type, b + + # default text to binary representation conversion def binary(txt): return txt.encode('utf-8') @@ -15,10 +17,13 @@ def binary(txt): import json except ImportError: import simplejson as json - + + __all__ = ['encode', 'decode', 'DecodeError'] -class DecodeError(Exception): pass + +class DecodeError(Exception): + pass signing_methods = { 'HS256': lambda msg, key: hmac.new(key, msg, hashlib.sha256).digest(), @@ -26,26 +31,30 @@ class DecodeError(Exception): pass 'HS512': lambda msg, key: hmac.new(key, msg, hashlib.sha512).digest(), } + def base64url_decode(input): input += b('=') * (4 - (len(input) % 4)) return base64.urlsafe_b64decode(input) + def base64url_encode(input): return base64.urlsafe_b64encode(input).decode('utf-8').replace('=', '') + def encode(payload, key, algorithm='HS256'): segments = [] header = {"typ": "JWT", "alg": algorithm} segments.append(base64url_encode(binary(json.dumps(header)))) segments.append(base64url_encode(binary(json.dumps(payload)))) - signing_input = '.'.join(segments) + sign_input = '.'.join(segments) try: - signature = signing_methods[algorithm](binary(signing_input), binary(key)) + signature = signing_methods[algorithm](binary(sign_input), binary(key)) except KeyError: raise NotImplementedError("Algorithm not supported") segments.append(base64url_encode(signature)) return '.'.join(segments) + def decode(jwt, key='', verify=True): try: signing_input, crypto_segment = jwt.rsplit('.', 1) @@ -53,14 +62,17 @@ def decode(jwt, key='', verify=True): except ValueError: raise DecodeError("Not enough segments") try: - header = json.loads(base64url_decode(binary(header_segment)).decode('utf-8')) - payload = json.loads(base64url_decode(binary(payload_segment)).decode('utf-8')) + header_raw = base64url_decode(binary(header_segment)).decode('utf-8') + payload_raw = base64url_decode(binary(payload_segment)).decode('utf-8') + header = json.loads(header_raw) + payload = json.loads(payload_raw) signature = base64url_decode(binary(crypto_segment)) except (ValueError, TypeError): raise DecodeError("Invalid segment encoding") if verify: try: - if not signature == signing_methods[header['alg']](binary(signing_input), binary(key)): + method = signing_methods[header['alg']] + if not signature == method(binary(signing_input), binary(key)): raise DecodeError("Signature verification failed") except KeyError: raise DecodeError("Algorithm not supported") diff --git a/twilio/rest/__init__.py b/twilio/rest/__init__.py index 556b5ff048..f8e0cf0747 100644 --- a/twilio/rest/__init__.py +++ b/twilio/rest/__init__.py @@ -77,7 +77,7 @@ def request(self, path, method=None, vars=None): headers = { "User-Agent": "twilio-python", - } + } resp = make_request(method, uri, auth=self.auth, data=data, params=params, headers=headers) diff --git a/twilio/rest/resources/accounts.py b/twilio/rest/resources/accounts.py index 93aa13afc1..a5098c99e5 100644 --- a/twilio/rest/resources/accounts.py +++ b/twilio/rest/resources/accounts.py @@ -33,7 +33,7 @@ class Account(InstanceResource): ConnectApps, Queues, AuthorizedConnectApps, - ] + ] def update(self, **kwargs): """ diff --git a/twilio/rest/resources/base.py b/twilio/rest/resources/base.py index 4a2016077e..512326f017 100644 --- a/twilio/rest/resources/base.py +++ b/twilio/rest/resources/base.py @@ -21,9 +21,9 @@ def __init__(self, httplib_resp, content, url): self.url = url -def make_request(method, url, - params=None, data=None, headers=None, cookies=None, files=None, - auth=None, timeout=None, allow_redirects=False, proxies=None): +def make_request(method, url, params=None, data=None, headers=None, + cookies=None, files=None, auth=None, timeout=None, + allow_redirects=False, proxies=None): """Sends an HTTP request Returns :class:`Response ` See the requests documentation for explanation of all these parameters @@ -107,7 +107,7 @@ def __eq__(self, other): and self.__dict__ == other.__dict__) def __hash__(self): - return hash(frozenset(self.__dict__)) + return hash(frozenset(self.__dict__)) def __ne__(self, other): return not self.__eq__(other) @@ -141,8 +141,7 @@ class InstanceResource(Resource): def __init__(self, parent, sid): self.parent = parent self.name = sid - super(InstanceResource, self).__init__(parent.uri, - parent.auth) + super(InstanceResource, self).__init__(parent.uri, parent.auth) def load(self, entries): if "from" in entries.keys(): diff --git a/twilio/rest/resources/calls.py b/twilio/rest/resources/calls.py index 6891f5b5a4..de6c124aca 100644 --- a/twilio/rest/resources/calls.py +++ b/twilio/rest/resources/calls.py @@ -85,7 +85,8 @@ def create(self, to, from_, url, status_method=None, **kwargs): occurs requesting or executing the TwiML at url :param string fallback_method: The HTTP method that Twilio should use to request the fallback_url - :type fallback_method: None (will make 'POST' request), 'GET', or 'POST' + :type fallback_method: None (will make 'POST' request), + 'GET', or 'POST' :param string status_callback: A URL that Twilio will request when the call ends to notify your app. :param string status_method: The HTTP method Twilio should use when @@ -93,7 +94,7 @@ def create(self, to, from_, url, status_method=None, **kwargs): :param string if_machine: Tell Twilio to try and determine if a machine (like voicemail) or a human has answered the call. See more in our `answering machine documentation - `_. + `_. :type if_machine: None, 'Continue', or 'Hangup' :param string send_digits: A string of keys to dial after connecting to the number. diff --git a/twilio/rest/resources/conferences.py b/twilio/rest/resources/conferences.py index bb187cd5b2..b5e771ee5d 100644 --- a/twilio/rest/resources/conferences.py +++ b/twilio/rest/resources/conferences.py @@ -76,7 +76,7 @@ class Conference(InstanceResource): subresources = [ Participants - ] + ] class Conferences(ListResource): diff --git a/twilio/rest/resources/connect_apps.py b/twilio/rest/resources/connect_apps.py index 75f32f1f0d..97cd25926e 100644 --- a/twilio/rest/resources/connect_apps.py +++ b/twilio/rest/resources/connect_apps.py @@ -1,6 +1,7 @@ from twilio.rest.resources import InstanceResource, ListResource from six import iteritems + class ConnectApp(InstanceResource): """ An authorized connect app """ pass diff --git a/twilio/rest/resources/imports.py b/twilio/rest/resources/imports.py index c4c5af5c7c..1b24b45d1e 100644 --- a/twilio/rest/resources/imports.py +++ b/twilio/rest/resources/imports.py @@ -15,5 +15,3 @@ # httplib2 import httplib2 - - diff --git a/twilio/rest/resources/phone_numbers.py b/twilio/rest/resources/phone_numbers.py index 8352ff22b6..013e73c7d6 100644 --- a/twilio/rest/resources/phone_numbers.py +++ b/twilio/rest/resources/phone_numbers.py @@ -64,7 +64,7 @@ def load(self, entries): if "account_sid" in entries: # Parse the parent's uri to get the scheme and base uri = re.sub(r'AC(.*)', entries["account_sid"], - self.parent.base_uri) + self.parent.base_uri) self.parent = PhoneNumbers(uri, self.parent.auth) self.base_uri = self.parent.uri @@ -84,7 +84,8 @@ def update(self, **kwargs): Update this phone number instance. """ kwargs_copy = dict(kwargs) - change_dict_key(kwargs_copy, from_key="status_callback_url", to_key="status_callback") + change_dict_key(kwargs_copy, from_key="status_callback_url", + to_key="status_callback") a = self.parent.update(self.name, **kwargs_copy) self.load(a.__dict__) @@ -171,7 +172,8 @@ def update(self, sid, **kwargs): Update this phone number instance """ kwargs_copy = dict(kwargs) - change_dict_key(kwargs_copy, from_key="status_callback_url", to_key="status_callback") + change_dict_key(kwargs_copy, from_key="status_callback_url", + to_key="status_callback") if "application_sid" in kwargs_copy: for sid_type in ["voice_application_sid", "sms_application_sid"]: diff --git a/twilio/rest/resources/queues.py b/twilio/rest/resources/queues.py index 5cb4f40d8c..8081aa3cc4 100644 --- a/twilio/rest/resources/queues.py +++ b/twilio/rest/resources/queues.py @@ -61,8 +61,8 @@ class Queues(ListResource): def list(self, **kwargs): """ - Returns a page of :class:`Queue` resources as a list sorted by DateUpdated. - For paging informtion see :class:`ListResource` + Returns a page of :class:`Queue` resources as a list sorted + by DateUpdated. For paging informtion see :class:`ListResource` """ return self.get_instances(kwargs) diff --git a/twilio/rest/resources/recordings.py b/twilio/rest/resources/recordings.py index 1c4482d3ef..e800e9aa98 100644 --- a/twilio/rest/resources/recordings.py +++ b/twilio/rest/resources/recordings.py @@ -28,7 +28,7 @@ def __init__(self, *args, **kwargs): self.formats = { "mp3": self.uri + ".mp3", "wav": self.uri + ".wav", - } + } def delete(self): """ diff --git a/twilio/rest/resources/usage.py b/twilio/rest/resources/usage.py index 89e34af41b..cff21acf2e 100644 --- a/twilio/rest/resources/usage.py +++ b/twilio/rest/resources/usage.py @@ -1,5 +1,6 @@ from twilio.rest.resources import InstanceResource, ListResource + class UsageTrigger(InstanceResource): """ A usage trigger resource """ @@ -63,12 +64,10 @@ def create(self, **kwargs): """ return self.create_instance(kwargs) - def update(self, sid, **kwargs): """ Update the UsageTrigger with the given sid to have the kwargs """ return self.update_instance(sid, kwargs) - def delete(self, sid): """ Delete a :class:`UsageTrigger` @@ -88,6 +87,7 @@ def load(self, entries): def uri(self): return self.__dict__.get('uri') + class BaseUsageRecords(ListResource): name = "Usage/Records" instance = UsageRecord @@ -118,6 +118,7 @@ def load_instance(self, data): class UsageRecords(BaseUsageRecords): + def __init__(self, base_uri, auth): super(UsageRecords, self).__init__(base_uri, auth) self.daily = UsageRecordsDaily(base_uri, auth) @@ -166,6 +167,7 @@ class UsageRecordsLastMonth(BaseUsageRecords): UsageRecordsLastMonth ] + class Usage(object): """ Holds all the specific Usage list resources diff --git a/twilio/rest/resources/util.py b/twilio/rest/resources/util.py index 142d53b560..61a35f03db 100644 --- a/twilio/rest/resources/util.py +++ b/twilio/rest/resources/util.py @@ -2,7 +2,7 @@ from six import iteritems -def transform_params(p): +def transform_params(parameters): """ Transform parameters, throwing away any None values and convert False and True values to strings @@ -13,10 +13,13 @@ def transform_params(p): becomes: {"Record": "true", "DateCreated": "2012-01-02"} """ - p = [(format_name(d), convert_boolean(p[d])) for d in p - if p[d] is not None - ] - return dict(p) + transformed_parameters = {} + + for key, value in iteritems(parameters): + if value is not None: + transformed_parameters[format_name(key)] = convert_boolean(value) + + return transformed_parameters def format_name(word): @@ -61,12 +64,12 @@ def convert_keys(d): """ special = { "started_before": "StartTime<", - "started_after": "StartTime>", - "started": "StartTime", - "ended_before": "EndTime<", - "ended_after": "EndTime>", - "ended": "EndTime", - "from_": "From", + "started_after": "StartTime>", + "started": "StartTime", + "ended_before": "EndTime<", + "ended_after": "EndTime>", + "ended": "EndTime", + "from_": "From", } result = {} @@ -91,9 +94,11 @@ def inner_func(*args, **kwargs): inner_func.__repr__ = myfunc.__repr__ return inner_func + def change_dict_key(d, from_key, to_key): """ - Changes a dictionary's key from from_key to to_key. No-op if the key does not exist. + Changes a dictionary's key from from_key to to_key. + No-op if the key does not exist. :param d: Dictionary with key to change :param from_key: Old key diff --git a/twilio/twiml.py b/twilio/twiml.py index 2cf9248f5d..d5947f43dc 100644 --- a/twilio/twiml.py +++ b/twilio/twiml.py @@ -84,7 +84,7 @@ def xml(self): def append(self, verb): if not self.nestables or verb.name not in self.nestables: raise TwimlException("%s is not nestable inside %s" % - (verb.name, self.name)) + (verb.name, self.name)) self.verbs.append(verb) return verb @@ -104,7 +104,7 @@ class Response(Verb): 'Sms', 'Enqueue', 'Leave' - ] + ] def __init__(self, **kwargs): """Version: Twilio API version e.g. 2008-08-01 """ diff --git a/twilio/util.py b/twilio/util.py index 3e7f60c300..2ca78efc36 100644 --- a/twilio/util.py +++ b/twilio/util.py @@ -6,6 +6,7 @@ from twilio import jwt from twilio.compat import urlencode + class RequestValidator(object): def __init__(self, token):