10000 Merge branch 'addresses' · codemunkee/twilio-python@26d02d0 · GitHub
[go: up one dir, main page]

Skip to content

Commit 26d02d0

Browse files
committed
Merge branch 'addresses'
Conflicts: twilio/rest/resources/__init__.py
2 parents ce4ad99 + 726d963 commit 26d02d0

File tree

6 files changed

+239
-1
lines changed

6 files changed

+239
-1
lines changed

docs/api/rest/resources.rst

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,27 @@ Accounts
4343

4444
The authorization token for this account. This token should be kept a secret, so no sharing.
4545

46+
Addresses
47+
>>>>>>>>>
48+
49+
.. autoclass:: Addresses
50+
:members:
51+
:exclude-members: instance
52+
53+
.. autoclass:: Address
54+
:members:
55+
56+
57+
DependentPhoneNumbers
58+
>>>>>>>>>>>>>>>>>>>>>
59+
60+
.. autoclass:: DependentPhoneNumbers
61+
:members:
62+
:exclude-members: instance
63+
64+
.. autoclass:: DependentPhoneNumber
65+
:members:
66+
4667

4768
Applications
4869
>>>>>>>>>>>>>>>
@@ -129,7 +150,7 @@ Applications
129150
.. attribute:: uri
130151

131152
The URI for this resource, relative to https://api.twilio.com
132-
153+
133154

134155
Calls
135156
>>>>>>

tests/test_addresses.py

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import unittest
2+
3+
from mock import Mock
4+
from nose.tools import assert_equal, raises
5+
6+
from twilio.exceptions import TwilioException
7+
from twilio.rest.resources import Addresses, DependentPhoneNumbers
8+
9+
10+
class AddressesTest(unittest.TestCase):
11+
def setUp(self):
12+
self.parent = Mock()
13+
self.resource = Addresses("http://api.twilio.com", ("user", "pass"))
14+
15+
def test_update(self):
16+
request = Mock()
17+
request.return_value = (Mock(), {"sid": "123"})
18+
self.resource.request = request
19+
20+
self.resource.update("123", friendly_name="hi")
21+
22+
uri = "http://api.twilio.com/Addresses/123"
23+
request.assert_called_with("POST", uri, data={"FriendlyName": "hi"})
24+
25+
@raises(TwilioException)
26+
def test_update_rejects_iso_country(self):
27+
self.resource.update("123", iso_country="CA")
28+
29+
def test_dependent_phone_numbers(self):
30+
pn_list = DependentPhoneNumbers(
31+
'http://api.twilio.com/mock',
32+
('user', 'pass'),
33+
)
34+
request = Mock()
35+
request.return_value = (
36+
Mock(),
37+
{
38+
"dependent_phone_numbers": [{"sid": "PN123"}],
39+
"total": 1,
40+
"page": 0,
41+
"page_size": 50,
42+
},
43+
)
44+
pn_list.request = request
45+
46+
result = pn_list.list()
47+
request.assert_called_with(
48+
"GET",
49+
"http://api.twilio.com/mock/DependentPhoneNumbers",
50+
params={},
51+
)
52+
assert_equal(result[0].sid, 'PN123')

twilio/rest/__init__.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from .resources import (
77
make_request,
88
Accounts,
9+
Addresses,
910
Applications,
1011
AuthorizedConnectApps,
1112
CallerIds,
@@ -95,6 +96,7 @@ def __init__(self, account=None, token=None, base="https://api.twilio.com",
9596
account_uri = "%s/%s/Accounts/%s" % (base, version, account)
9697

9798
self.accounts = Accounts(version_uri, auth, timeout)
99+
self.addresses = Addresses(account_uri, auth, timeout)
98100
self.applications = Applications(account_uri, auth, timeout)
99101
self.authorized_connect_apps = AuthorizedConnectApps(
100102
account_uri,
@@ -153,6 +155,14 @@ def feedback(self, call_sid):
153155
)
154156
return CallFeedback(call_feedback_list)
155157

158+
def dependent_phone_numbers(self, address_sid):
159+
"""
160+
Return a :class:`DependentPhoneNumbers <twilio.rest.resources.DependentPhoneNumbers>` instance for
161+
the :class:`Address <twilio.rest.resources.Address>` with the given address_sid
162+
"""
163+
base_uri = "%s/Addresses/%s" % (self.account_uri, address_sid)
164+
return DependentPhoneNumbers(base_uri, self.auth, self.timeout)
165+
156166
def request(self, path, method=None, vars=None):
157167
"""sends a request and gets a response from the Twilio REST API
158168

twilio/rest/resources/__init__.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,3 +53,10 @@
5353
from .sip import Sip
5454

5555
from .tokens import Token, Tokens
56+
57+
from .addresses import (
58+
Address,
59+
Addresses,
60+
DependentPhoneNumber,
61+
DependentPhoneNumbers,
62+
)

twilio/rest/resources/addresses.py

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
from twilio.exceptions import TwilioException
2+
from twilio.rest.resources import InstanceResource, ListResource
3+
4+
5+
class DependentPhoneNumber(InstanceResource):
6+
"""A purchased phone number that depends on a particular
7+
:class:`Address`.
8+
9+
Attributes are the same as :class:`PhoneNumber`.
10+
11+
DependentPhoneNumbers are a read-only resource and cannot
12+
be updated or deleted.
13+
"""
14+
pass
15+
16+
17+
class DependentPhoneNumbers(ListResource):
18+
"""A list of purchased phone numbers that depend on a particular
19+
:class:`Address`.
20+
21+
Included numbers are those that require an
22+
address on file and have no other candidate addresses of the appropriate
23+
type (local, foreign) associated with the owning account.
24+
25+
If this list has entries for a given Address, that address cannot be
26+
deleted until the numbers are released from your account or alternate
27+
addresses are provided to satisfy the requirements.
28+
29+
This resource is read-only and cannot be updated or deleted, but will
30+
reflect the current state of the owning account's addresses (i.e. if
31+
you add another address that satisfies a number's requirements, it will
32+
not appear in subsequent requests to this list resource).
33+
"""
34+
name = "DependentPhoneNumbers"
35+
key = "dependent_phone_numbers"
36+
instance = DependentPhoneNumber
37+
38+
39+
class Address(InstanceResource):
40+
"""An Address resource. See https://www.twilio.com/docs/api/rest/address
41+
42+
.. attribute:: friendly_name
43+
44+
A human-readable description of this address. Maximum 64 characters.
45+
46+
.. attribute:: customer_name
47+
48+
Your or your customer's name or business name.
49+
50+
.. attribute:: street
51+
52+
The number and street address where you or your customer are located.
53+
54+
.. attribute:: city
55+
56+
The city in which you or your customer are located.
57+
58+
.. attribute:: region
59+
60+
The state or region in which you or your customer are located.
61+
62+
.. attribute:: postal_code
63+
64+
The postal code in which you or your customer are located.
65+
66+
.. attribute:: iso_country
67+
68+
The ISO country code of your or your customer's address.
69+
"""
70+
subresources = [DependentPhoneNumbers]
71+
72+
def update(self, **kwargs):
73+
"""Update this phone number instance.
74+
75+
Parameters are as described in :meth:`Addresses.create`, with
76+
the exception that `iso_country` cannot be updated on an existing
77+
Address (create a new one instead).
78+
"""
79+
return self.parent.update(self.sid, kwargs)
80+
81+
82+
class Addresses(ListResource):
83+
name = "Addresses"
84+
key = "addresses"
85+
instance = Address
86+
87+
def list(self, customer_name=None, friendly_name=None, iso_country=None):
88+
kwargs = {
89+
'customer_name': customer_name,
90+
'friendly_name': friendly_name,
91+
'iso_country': iso_country,
92+
}
93+
return self.get_instances(kwargs)
94+
95+
def create(self, customer_name, street, city, region, postal_code,
96+
iso_country, friendly_name=None):
97+
"""Create an :class:`Address`.
98+
99+
:param str customer_name: Your customer's name
100+
:param str street: The number and street of your address
101+
:param str city: The city of you or your customer's address
102+
:param str region: The region or state
103+
:param str postal_code: The postal code of your address
104+
:param str iso_country: The ISO 3166-1 alpha-2 (two-character)
105+
country code, e.g. 'US' or 'AU'
106+
:param str friendly_name: A user-defined name for this address
107+
(optional; up to 64 characters)
108+
"""
109+
kwargs = {
110+
'customer_name': customer_name,
111+
'street': street,
112+
'city': city,
113+
'region': region,
114+
'postal_code': postal_code,
115+
'iso_country': iso_country,
116+
}
117+
118+
if friendly_name is not None:
119+
kwargs['friendly_name'] = friendly_name
120+
121+
return self.create_instance(kwargs)
122+
123+
def update(self, sid, **kwargs):
124+
"""Update an :class:`Address` with the given parameters.
125+
126+
Parameters are described above in :meth:`create`, with
127+
the exception that `iso_country` cannot be updated on
128+
an existing Address (create a new one instead).
129+
"""
130+
if 'iso_country' in kwargs:
131+
raise TwilioException(
132+
"Cannot update iso_country on an existing Address",
133+
)
134+
135+
return self.update_instance(sid, kwargs)
136+
137+
def delete(self, sid):
138+
"""Delete an :class:`Address`.
139+
140+
:param str sid: The sid of the Address to delete.
141+
"""
142+
return self.delete_instance(sid)

twilio/rest/resources/phone_numbers.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,12 @@ class AvailablePhoneNumber(InstanceResource):
4848
4949
The country for this number
5050
51+
.. attribute:: address_requirements
52+
53+
Whether the phone number requires you or your customer to have an
54+
Address registered with Twilio. Possible values are 'none', 'any',
55+
'local', or 'foreign'.
56+
5157
"""
5258

5359
def __init__(self, parent):

0 commit comments

Comments
 (0)
0