Skip to content

Commit a77b7c1

Browse files
authored
Merge pull request #19 from messagebird/add-ci
Add ci
2 parents a933e07 + e93a241 commit a77b7c1

File tree

11 files changed

+266
-29
lines changed

11 files changed

+266
-29
lines changed

.travis.yml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
language: python
2+
python:
3+
- 'pypy2.7'
4+
- 'pypy3.5'
5+
- '2.7'
6+
- '3.3'
7+
- '3.6'
8+
- 'nightly'
9+
install:
10+
- pip install mock==2.0
11+
- pip install requests
12+
script:
13+
- python -m unittest discover -s tests/ -p test_*.py -v
14+
matrix:
15+
allow_failures:
16+
- python: 'nightly'
17+
- python: 'pypy2.7'

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ MessageBird's REST API for Python
22
=================================
33
This repository contains the open source Python client for MessageBird's REST API. Documentation can be found at: https://developers.messagebird.com/.
44

5+
[![Build Status](https://travis-ci.org/messagebird/python-rest-api.svg?branch=master)](https://travis-ci.org/messagebird/python-rest-api)
6+
57
Requirements
68
------------
79
- [Sign up](https://www.messagebird.com/en/signup) for a free MessageBird account

messagebird/client.py

Lines changed: 13 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,11 @@
11
import sys
22
import json
3-
import requests
4-
5-
try:
6-
from urllib.parse import urljoin
7-
except ImportError:
8-
from urlparse import urljoin
93

104
from messagebird.base import Base
115
from messagebird.balance import Balance
126
from messagebird.error import Error
137
from messagebird.hlr import HLR
8+
from messagebird.http_client import HttpClient
149
from messagebird.message import Message
1510
from messagebird.voicemessage import VoiceMessage
1611
from messagebird.lookup import Lookup
@@ -19,6 +14,7 @@
1914
ENDPOINT = 'https://rest.messagebird.com'
2015
CLIENT_VERSION = '1.2.1'
2116
PYTHON_VERSION = '%d.%d.%d' % (sys.version_info[0], sys.version_info[1], sys.version_info[2])
17+
USER_AGENT = 'MessageBird/ApiClient/%s Python/%s' % (CLIENT_VERSION, PYTHON_VERSION)
2218

2319

2420
class ErrorException(Exception):
@@ -29,35 +25,23 @@ def __init__(self, errors):
2925

3026

3127
class Client(object):
32-
def __init__(self, access_key):
28+
def __init__(self, access_key, http_client=None):
3329
self.access_key = access_key
34-
self._supported_status_codes = [200, 201, 204, 401, 404, 405, 422]
35-
36-
def request(self, path, method='GET', params=None):
37-
if params is None: params = {}
38-
url = urljoin(ENDPOINT, path)
3930

40-
headers = {
41-
'Accept' : 'application/json',
42-
'Authorization' : 'AccessKey ' + self.access_key,
43-
'User-Agent' : 'MessageBird/ApiClient/%s Python/%s' % (CLIENT_VERSION, PYTHON_VERSION),
44-
'Content-Type' : 'application/json'
45-
}
46-
47-
if method == 'GET':
48-
response = requests.get(url, verify=True, headers=headers, params=params)
31+
if http_client is None:
32+
self.http_client = HttpClient(ENDPOINT, access_key, USER_AGENT)
4933
else:
50-
response = requests.post(url, verify=True, headers=headers, data=json.dumps(params))
34+
self.http_client = http_client
5135

52-
if response.status_code in self._supported_status_codes:
53-
json_response = response.json()
54-
else:
55-
response.raise_for_status()
36+
def request(self, path, method='GET', params=None):
37+
"""Builds a request, gets a response and decodes it."""
38+
response_text = self.http_client.request(path, method, params)
39+
response_json = json.loads(response_text)
5640

57-
if 'errors' in json_response:
58-
raise(ErrorException([Error().load(e) for e in json_response['errors']]))
41+
if 'errors' in response_json:
42+
raise(ErrorException([Error().load(e) for e in response_json['errors']]))
5943

60-
return json_response
44+
return response_json
6145

6246
def balance(self):
6347
"""Retrieve your balance."""

messagebird/http_client.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import requests
2+
3+
try:
4+
from urllib.parse import urljoin
5+
except ImportError:
6+
from urlparse import urljoin
7+
8+
9+
class HttpClient(object):
10+
"""Used for sending simple HTTP requests."""
11+
12+
def __init__(self, endpoint, access_key, user_agent):
13+
self.__supported_status_codes = [200, 201, 204, 401, 404, 405, 422]
14+
15+
self.endpoint = endpoint
16+
self.access_key = access_key
17+
self.user_agent = user_agent
18+
19+
def request(self, path, method='GET', params=None):
20+
"""Builds a request and gets a response."""
21+
if params is None: params = {}
22+
url = urljoin(self.endpoint, path)
23+
24+
headers = {
25+
'Accept': 'application/json',
26+
'Authorization': 'AccessKey ' + self.access_key,
27+
'User-Agent': self.user_agent,
28+
'Content-Type': 'application/json'
29+
}
30+
31+
if method == 'GET':
32+
response = requests.get(url, verify=True, headers=headers, params=params)
33+
else:
34+
response = requests.post(url, verify=True, headers=headers, data=json.dumps(params))
35+
36+
if response.status_code in self.__supported_status_codes:
37+
response_text = response.text
38+
else:
39+
response.raise_for_status()
40+
41+
return response_text

tests/__init__.py

Whitespace-only changes.

tests/test_balance.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import unittest
2+
from messagebird import Client
3+
4+
try:
5+
from unittest.mock import Mock
6+
except ImportError:
7+
# mock was added to unittest in Python 3.3, but was an external library
8+
# before.
9+
from mock import Mock
10+
11+
12+
class TestBalance(unittest.TestCase):
13+
14+
def test_balance(self):
15+
http_client = Mock()
16+
http_client.request.return_value = '{"payment": "prepaid","type": "credits","amount": 9.2}'
17+
18+
balance = Client('', http_client).balance()
19+
20+
http_client.request.assert_called_once_with('balance', 'GET', None)
21+
22+
self.assertEqual('prepaid', balance.payment)
23+
self.assertEqual('credits', balance.type)

tests/test_hlr.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import unittest
2+
from messagebird import Client
3+
4+
try:
5+
from unittest.mock import Mock
6+
except ImportError:
7+
# mock was added to unittest in Python 3.3, but was an external library
8+
# before.
9+
from mock import Mock
10+
11+
12+
class TestHLR(unittest.TestCase):
13+
14+
def test_hlr(self):
15+
http_client = Mock()
16+
http_client.request.return_value = '{"id":"hlr-id","href":"https://rest.messagebird.com/hlr/hlr-id","msisdn":31612345678,"network":20406,"reference":"MyReference","status": "sent","createdDatetime": "2015-01-04T13:14:08+00:00","statusDatetime": "2015-01-04T13:14:09+00:00"}'
17+
18+
hlr = Client('', http_client).hlr('hlr-id')
19+
20+
http_client.request.assert_called_once_with('hlr/hlr-id', 'GET', None)
21+
22+
self.assertEqual('hlr-id', hlr.id)
23+
24+
def test_hlr_create(self):
25+
http_client = Mock()
26+
http_client.request.return_value = '{}'
27+
28+
Client('', http_client).hlr_create(31612345678, 'MyReference')
29+
30+
http_client.request.assert_called_once_with('hlr', 'POST', {'msisdn': 31612345678, 'reference': 'MyReference'})

tests/test_lookup.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import unittest
2+
from messagebird import Client
3+
4+
try:
5+
from unittest.mock import Mock
6+
except ImportError:
7+
# mock was added to unittest in Python 3.3, but was an external library
8+
# before.
9+
from mock import Mock
10+
11+
12+
class TestLookup(unittest.TestCase):
13+
14+
def test_lookup(self):
15+
http_client = Mock()
16+
http_client.request.return_value = '{"href": "https://rest.messagebird.com/lookup/31612345678","countryCode": "NL","countryPrefix": 31,"phoneNumber": 31612345678,"type": "mobile","formats": {"e164": "+31612345678","international": "+31 6 12345678","national": "06 12345678","rfc3966": "tel:+31-6-12345678"},"hlr": {"id": "hlr-id","network": 20416,"reference": "reference2000","status": "active","createdDatetime": "2015-12-15T08:19:24+00:00","statusDatetime": "2015-12-15T08:19:25+00:00"}}'
17+
18+
lookup = Client('', http_client).lookup('0612345678', {'countryCode': 'NL'})
19+
20+
http_client.request.assert_called_once_with('lookup/0612345678', 'GET', {'countryCode': 'NL'})
21+
22+
self.assertEqual('mobile', lookup.type)
23+
24+
def test_lookup_hlr(self):
25+
http_client = Mock()
26+
http_client.request.return_value = '{"id": "hlr-id","network": 20416,"reference": "reference2000","status": "active","createdDatetime": "2015-12-15T08:19:24+00:00","statusDatetime": "2015-12-15T08:19:25+00:00"}'
27+
28+
lookup_hlr = Client('', http_client).lookup_hlr(31612345678, {'reference': 'reference2000'})
29+
30+
http_client.request.assert_called_once_with('lookup/31612345678/hlr', 'GET', {'reference': 'reference2000'})
31+
32+
self.assertEqual(lookup_hlr.status, 'active')
33+
34+
def test_lookup_hlr_create(self):
35+
http_client = Mock()
36+
http_client.request.return_value = '{}'
37+
38+
Client('', http_client).lookup_hlr_create(31612345678, {'reference': 'MyReference'})
39+
40+
http_client.request.assert_called_once_with('lookup/31612345678/hlr', 'POST', {'reference': 'MyReference'})

tests/test_message.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import unittest
2+
from messagebird import Client
3+
4+
try:
5+
from unittest.mock import Mock
6+
except ImportError:
7+
# mock was added to unittest in Python 3.3, but was an external library
8+
# before.
9+
from mock import Mock
10+
11+
12+
class TestMessage(unittest.TestCase):
13+
14+
def test_message(self):
15+
http_client = Mock()
16+
http_client.request.return_value = '{"body": "Hello World","createdDatetime": "2015-01-05T10:02:59+00:00","datacoding": "plain","direction": "mt","gateway": 239,"href": "https://rest.messagebird.com/messages/message-id","id": "message-id","mclass": 1,"originator": "TestName","recipients": {"items": [{"recipient": 31612345678,"status": "sent","statusDatetime": "2015-01-05T10:02:59+00:00"}],"totalCount": 1,"totalDeliveredCount": 0,"totalDeliveryFailedCount": 0,"totalSentCount": 1},"reference": null,"scheduledDatetime": null,"type": "sms","typeDetails": {},"validity": null}'
17+
18+
message = Client('', http_client).message('message-id')
19+
20+
http_client.request.assert_called_once_with('messages/message-id', 'GET', None)
21+
22+
self.assertEqual('mt', message.direction)
23+
24+
def test_message_create(self):
25+
http_client = Mock()
26+
http_client.request.return_value = '{}'
27+
28+
Client('', http_client).message_create('MessageBird', ['31612345678', '31687654321'], 'Hello World', {'datacoding': 'unicode'})
29+
30+
http_client.request.assert_called_once_with('messages', 'POST', {'datacoding': 'unicode', 'originator': 'MessageBird', 'body': 'Hello World', 'recipients': '31612345678,31687654321' })

tests/test_verify.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import unittest
2+
from messagebird import Client
3+
4+
try:
5+
from unittest.mock import Mock
6+
except ImportError:
7+
# mock was added to unittest in Python 3.3, but was an external library
8+
# before.
9+
from mock import Mock
10+
11+
12+
class TestVerify(unittest.TestCase):
13+
14+
def test_verify(self):
15+
http_client = Mock()
16+
http_client.request.return_value = '{"id": "verify-id","href": "https://rest.messagebird.com/verify/verify-id","recipient": 31612345678,"reference": "MyReference","messages": {"href": "https://rest.messagebird.com/messages/message-id"},"status": "verified","createdDatetime": "2017-05-30T12:39:50+00:00","validUntilDatetime": "2017-05-30T12:40:20+00:00"}'
17+
18+
verify = Client('', http_client).verify('verify-id')
19+
20+
http_client.request.assert_called_once_with('verify/verify-id', 'GET', None)
21+
22+
self.assertEqual('verify-id', verify.id)
23+
24+
def test_verify_create(self):
25+
http_client = Mock()
26+
http_client.request.return_value = '{}'
27+
28+
Client('', http_client).verify_create('31612345678', {})
29+
30+
http_client.request.assert_called_once_with('verify', 'POST', {'recipient': '31612345678'})
31+
32+
def test_verify_verify(self):
33+
http_client = Mock()
34+
http_client.request.return_value = '{"id": "verify-id","href": "https://rest.messagebird.com/verify/verify-id","recipient": 31612345678,"reference": "MyReference","messages": {"href": "https://rest.messagebird.com/messages/63b168423592d681641eb07b76226648"},"status": "verified","createdDatetime": "2017-05-30T12:39:50+00:00","validUntilDatetime": "2017-05-30T12:40:20+00:00"}'
35+
36+
verify = Client('', http_client).verify_verify('verify-id', 'secret')
37+
38+
http_client.request.assert_called_once_with('verify/verify-id', 'GET', {'token': 'secret'})
39+
40+
self.assertEqual('verified', verify.status)

0 commit comments

Comments
 (0)