8000 Merge pull request #12 from twilio/pricing · stomatocode/twilio-python@e5f0bcc · GitHub
[go: up one dir, main page]

Skip to content

Commit e5f0bcc

Browse files
committed
Merge pull request twilio#12 from twilio/pricing
Add Pricing API support
2 parents 5e84f43 + eb2a46b commit e5f0bcc

15 files changed

+688
-6
lines changed

docs/usage/pricing.rst

Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
.. module::twilio.rest
2+
3+
======================================
4+
Accessing Twilio Pricing API Resources
5+
======================================
6+
7+
To access the Twilio Pricing API resources, you'll first need to instantiate
8+
a :class:`TwilioPricingClient`.
9+
10+
Authentication
11+
--------------
12+
13+
The :class:`TwilioPricingClient` needs your Twilio credentials. While these can be
14+
passed in directly to the constructor, we suggest storing your credentials as
15+
environment variables. Why? You'll never have to worry about committing your
16+
credentials and accidentally posting them somewhere public.
17+
18+
The :class:`TwilioPricingClient` looks for :const:`TWILIO_ACCOUNT_SID` and
19+
:const:`TWILIO_AUTH_TOKEN` inside the current environment.
20+
21+
With those two values set, create a new :class:`TwilioPricingClient`.
22+
23+
.. code-block:: python
24+
25+
from twilio.rest import TwilioPricingClient
26+
27+
conn = TwilioPricingClient()
28+
29+
If you'd rather not use environment variables, pass your account credentials
30+
directly to the the constructor.
31+
32+
.. code-block:: python
33+
34+
from twilio.rest import TwilioPricingClient
35+
36+
ACCOUNT_SID = "AXXXXXXXXXXXXXXXXX"
37+
AUTH_TOKEN = "YYYYYYYYYYYYYYYYYY"
38+
client = TwilioPricingClient(ACCOUNT_SID, AUTH_TOKEN)
39+
40+
41+
For more advanced options to use with the :class:`TwilioPricingClient`,
42+
including proxy configuration, see the :doc:`/usage/basics` page.
43+
:class:`TwilioPricingClient` accepts the same options as
44+
:class:`TwilioRestClient`.
45+
46+
=============
47+
Voice Pricing
48+
=============
49+
50+
Twilio Voice pricing is available by country and by phone number.
51+
52+
Voice calls are priced per minute and reflect the current Twilio list price
53+
and any discounts available to the requesting account at the time of the
54+
request.
55+
56+
Voice Countries
57+
---------------
58+
59+
To retrieve a list of countries where Twilio Voice services are available:
60+
61+
.. code-block:: python
62+
63+
from twilio.rest import TwilioPricingClient
64+
65+
# To find these visit https://www.twilio.com/user/account
66+
ACCOUNT_SID = "ACXXXXXXXXXXXXXXXXX"
67+
AUTH_TOKEN = "YYYYYYYYYYYYYYYYYY"
68+
69+
client = TwilioPricingClient(ACCOUNT_SID, AUTH_TOKEN)
70+
countries = client.voice.countries.list()
71+
for c in countries:
72+
print c.iso_country
73+
74+
Note that the returned list of countries will not have actual prices populated.
75+
You will need to retrieve the pricing information for each country you are
76+
interested in individually:
77+
78+
.. code-block:: python
79+
80+
from twilio.rest import TwilioPricingClient
81+
82+
# To find these visit https://www.twilio.com/user/account
83+
ACCOUNT_SID = "ACXXXXXXXXXXXXXXXXX"
84+
AUTH_TOKEN = "YYYYYYYYYYYYYYYYYY"
85+
86+
client = TwilioPricingClient(ACCOUNT_SID, AUTH_TOKEN)
87+
country = client.voice.countries.get('GB')
88+
print country.iso_country
89+
print country.price_unit
90+
91+
# A list of price rates for inbound calls to each type of Twilio
92+
# Number available in this country
93+
for p in country.inbound_call_prices:
94+
print p.number_type
95+
print p.call_base_price # Base price per minute
96+
print p.current_base_price # Price per minute after discounts
97+
98+
# A list of price rates for outbound calls, organized by number prefixes.
99+
for p in country.outbound_prefix_prices:
100+
print p.prefixes # List of one or more prefixes this price applies to
101+
print p.call_base_price # Base price per minute
102+
print p.current_base_price # Price per minute after discounts
103+
104+
Voice Numbers
105+
-------------
106+
107+
To retrieve pricing information for Twilio Voice calls to and from a specific
108+
number:
109+
110+
.. code-block:: python
111+
112+
from twilio.rest import TwilioPricingClient
113+
114+
# To find these visit https://www.twilio.com/user/account
115+
ACCOUNT_SID = "ACXXXXXXXXXXXXXXXXX"
116+
AUTH_TOKEN = "YYYYYYYYYYYYYYYYYY"
117+
118+
client = TwilioPricingClient(ACCOUNT_SID, AUTH_TOKEN)
119+
number = client.voice.numbers.get('+15105551234')
120+
121+
print number.iso_country
122+
print number.price_unit
123+
print number.outbound_call_price.call_base_price
124+
print number.inbound_call_price.call_base_price # None if the number is not Twilio-hosted
125+
126+
Phone Number Pricing
127+
====================
128+
129+
To retrieve a list of countries where Twilio phone numbers are available:
130+
131+
.. code-block:: python
132+
133+
from twilio.rest import TwilioPricingClient
134+
135+
# To find these visit https://www.twilio.com/user/account
136+
ACCOUNT_SID = "ACXXXXXXXXXXXXXXXXX"
137+
AUTH_TOKEN = "YYYYYYYYYYYYYYYYYY"
138+
139+
client = TwilioPricingClient(ACCOUNT_SID, AUTH_TOKEN)
140+
countries = client.phone_numbers.countries.list()
141+
for c in countries:
142+
print c.iso_country
143+
144+
Note that the country objects in the returned list will not have pricing
145+
information populated; you will need to retrieve the specific information for
146+
each country you are interested in individually:
147+
148+
.. code-block:: python
149+
150+
from twilio.rest import TwilioPricingClient
151+
152+
# To find these visit https://www.twilio.com/user/account
153+
ACCOUNT_SID = "ACXXXXXXXXXXXXXXXXX"
154+
AUTH_TOKEN = "YYYYYYYYYYYYYYYYYY"
155+
156+
client = TwilioPricingClient(ACCOUNT_SID, AUTH_TOKEN)
157+
country = client.phone_numbers.countries.get('GB')
158+
print country.price_unit
159+
160+
for p in country.phone_number_prices:
161+
print p.type
162+
print p.base_price
163+
print p.current_price
164+

tests/pricing/__init__.py

Whitespace-only changes.

tests/pricing/test_numbers.py

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
import unittest
2+
from nose.tools import assert_equal
3+
4+
from mock import patch
5+
from tests.tools import create_mock_json
6+
7+
from twilio.rest.resources.pricing.phone_numbers import PhoneNumberCountries
8+
9+
10+
AUTH = ("AC123", "token")
11+
BASE_URI = "https://pricing.twilio.com/v1"
12+
13+
14+
class NumbersTest(unittest.TestCase):
15+
16+
@patch('twilio.rest.resources.base.make_twilio_request')
17+
def test_number_countries(self, request):
18+
resp = create_mock_json('tests/resources/pricing/phone_number_country_list.json')
19+
resp.status_code = 200
20+
request.return_value = resp
21+
22+
countries = PhoneNumberCountries(BASE_URI + "/PhoneNumbers", AUTH)
23+
result = countries.list()
24+
25+
assert_equal(result[0].iso_country, "AC")
26+
assert_equal(len(result), 3)
27+
28+
request.assert_called_with(
29+
"GET",
30+
"{}/PhoneNumbers/Countries".format(BASE_URI),
31+
auth=AUTH,
32+
use_json_extension=False,
33+
)
34+
35+
@patch('twilio.rest.re 9E7A sources.base.make_twilio_request')
36+
def test_number_country(self, request):
37+
resp = create_mock_json('tests/resources/pricing/phone_number_country_instance.json')
38+
resp.status_code = 200
39+
request.return_value = resp
40+
41+
countries = PhoneNumberCountries(BASE_URI + "/PhoneNumbers", AUTH)
42+
country = countries.get('EE')
43+
44+
assert_equal(country.country, "Estonia")
45+
assert_equal(
46+
country.phone_number_prices,
47+
[
48+
{
49+
'type': 'mobile',
50+
'base_price': 3.00,
51+
'current_price': 3.00,
52+
},
53+
{
54+
'type': 'national',
55+
'base_price': 1.00,
56+
'current_price': 1.00,
57+
}
58+
],
59+
)
60+
61+
request.assert_called_with(
62+
"GET",
63+
"{}/PhoneNumbers/Countries/EE".format(BASE_URI),
64+
auth=AUTH,
65+
use_json_extension=False,
66+
)

tests/pricing/test_voice.py

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
import unittest
2+
from nose.tools import assert_equal
3+
4+
from mock import patch
5+
from tests.tools import create_mock_json
6+
7+
from twilio.rest.resources.pricing.voice import (
8+
VoiceCountries,
9+
VoiceNumbers,
10+
)
11+
12+
13+
AUTH = ("AC123", "token")
14+
BASE_URI = "https://pricing.twilio.com/v1"
15+
16+
17+
class VoiceTest(unittest.TestCase):
18+
19+
@patch('twilio.rest.resources.base.make_twilio_request')
20+
def test_voice_countries(self, request):
21+
resp = create_mock_json('tests/resources/pricing/voice_countries_list.json')
22+
resp.status_code = 200
23+
request.return_value = resp
24+
25+
countries = VoiceCountries(BASE_URI + "/Voice", AUTH)
26+
result = countries.list()
27+
28+
assert_equal(result[0].iso_country, "AC")
29+
assert_equal(len(result), 3)
30+
31+
request.assert_called_with(
32+
"GET",
33+
"{}/Voice/Countries".format(BASE_URI),
34+
auth=AUTH,
35+
use_json_extension=False,
36+
)
37+
38+
@patch('twilio.rest.resources.base.make_twilio_request')
39+
def test_voice_country(self, request):
40+
resp = create_mock_json('tests/resources/pricing/voice_country_instance.json')
41+
resp.status_code = 200
42+
request.return_value = resp
43+
44+
countries = VoiceCountries(BASE_URI + "/Voice", AUTH)
45+
country = countries.get('EE')
46+
47+
assert_equal(country.country, "Estonia")
48+
assert_equal(
49+
country.inbound_call_prices[0],
50+
{
51+
'number_type': 'mobile',
52+
'call_base_price': 0.0075,
53+
'call_current_price': 0.0070
54+
},
55+
)
56+
57+
request.assert_called_with(
58+
"GET",
59+
"{}/Voice/Countries/EE".format(BASE_URI),
60+
auth=AUTH,
61+
use_json_extension=False,
62+
)
63+
64+
@patch('twilio.rest.resources.base.make_twilio_request')
65+
def test_voice_number(self, request):
66+
resp = create_mock_json('tests/resources/pricing/voice_number_instance.json')
67+
resp.status_code = 200
68+
request.return_value = resp
69+
70+
numbers = VoiceNumbers(BASE_URI + "/Voice", AUTH)
71+
result = numbers.get('+14089673429')
72+
73+
assert_equal(result.number, '+14089673429')
74+
assert_equal(result.price_unit, 'usd')
75+
76+
request.assert_called_with(
77+
"GET",
78+
"{}/Voice/Numbers/+14089673429".format(BASE_URI),
79+
auth=AUTH,
80+
use_json_extension=False,
81+
)
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
"uri": "pricing.twilio.com/v1/PhoneNumbers/Countries/EE",
3+
"country" : "Estonia",
4+
"iso_country": "EE",
5+
"phone_number_prices": [
6+
{
7+
"type": "mobile",
8+
"base_price": 3.00,
9+
"current_price": 3.00
10+
},
11+
{
12+
"type": "national",
13+
"base_price": 1.00,
14+
"current_price": 1.00
15+
}
16+
],
17+
"price_unit": "usd"
18+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
"uri": "pricing.twilio.com/v1/PhoneNumbers/Countries",
3+
"countries": [
4+
{
5+
"country": "Ascension",
6+
"iso_country": "AC",
7+
"uri": "pricing.twilio.com/v1/PhoneNumbers/Countries/AC"
8+
},
9+
{
10+
"country": "Andorra",
11+
"iso_country": "AD",
12+
"uri": "pricing.twilio.com/v1/PhoneNumbers/Countries/AD"
13+
},
14+
{
15+
"country": "United States",
16+
"iso_country": "US",
17+
"uri": "pricing.twilio.com/v1/PhoneNumbers/Countries/US"
18+
}
19+
]
20+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
{
2+
"uri": "pricing.twilio.com/v1/Voice/Countries",
3+
"countries": [
4+
{
5+
"country": "Ascension",
6+
"iso_country": "AC",
7+
"uri": "pricing.twilio.com/v1/Voice/Countries/AC"
8+
},
9+
{
10+
"country": "Andorra",
11+
"iso_country": "AD",
12+
"uri": "pricing.twilio.com/v1/Voice/Countries/AD"
13+
},
14+
{
15+
"country": "United States",
16+
"iso_country": "US",
17+
"uri": "pricing.twilio.com/v1/Voice/Countries/US"
18+
}
19+
]
20+
}
21+

0 commit comments

Comments
 (0)
0