Skip to content

Commit 2c5dd2d

Browse files
committed
Refactor Client for easier mocking
1 parent a933e07 commit 2c5dd2d

2 files changed

Lines changed: 54 additions & 29 deletions

File tree

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

0 commit comments

Comments
 (0)