diff --git a/CHANGES b/CHANGES index fcba796..bfd7652 100644 --- a/CHANGES +++ b/CHANGES @@ -43,3 +43,10 @@ 2.3.5 === - Add request timeout argument + +2.3.6 +=== +- Fix Python 3 bytes/str incompatibility: use response.text instead of response.content so simplejson (required dependency) receives a str +- Fix receive_verify_post to use the dict returned by get_body() directly instead of calling json.loads on it again +- Fix get_signature_string returning bytes instead of str; encoding moved to get_signature_hash where hashlib requires it +- Sync version string across __init__.py, sailthru_http.py User-Agent, and setup.py diff --git a/sailthru/__init__.py b/sailthru/__init__.py index 0ba3866..cf30b8a 100644 --- a/sailthru/__init__.py +++ b/sailthru/__init__.py @@ -6,4 +6,4 @@ __doc__ = 'Python binding for Sailthru API based on Requests' __copyright__ = 'Copyright 2012-2015, Sailthru Inc.' __license__ = 'MIT' -__version__ = '2.3.1' +__version__ = '2.3.6' diff --git a/sailthru/sailthru_client.py b/sailthru/sailthru_client.py index 3180b36..32cc016 100644 --- a/sailthru/sailthru_client.py +++ b/sailthru/sailthru_client.py @@ -31,7 +31,7 @@ def get_signature_string(params, secret): """ str_list = [str(item) for item in extract_params(params)] str_list.sort() - return (secret + ''.join(str_list)).encode('utf-8') + return secret + ''.join(str_list) def get_signature_hash(params, secret): """ @@ -39,7 +39,7 @@ def get_signature_hash(params, secret): @param params: dictionary values to generate signature hash @param sercret: secret string """ - return hashlib.md5(get_signature_string(params, secret)).hexdigest() + return hashlib.md5(get_signature_string(params, secret).encode('utf-8')).hexdigest() class SailthruClient(object): @@ -589,14 +589,10 @@ def receive_verify_post(self, post_params): send_response = self.get_send(post_params['send_id']) - try: - send_body = send_response.get_body() - send_json = json.loads(send_body) - if 'email' not in send_body: - return False - if send_json['email'] != post_params['email']: - return False - except ValueError: + send_json = send_response.get_body() + if not isinstance(send_json, dict): + return False + if send_json.get('email') != post_params['email']: return False return True diff --git a/sailthru/sailthru_http.py b/sailthru/sailthru_http.py index 76e5a2d..15504cc 100644 --- a/sailthru/sailthru_http.py +++ b/sailthru/sailthru_http.py @@ -34,7 +34,7 @@ def sailthru_http_request(url, data, method, file_data=None, headers=None, reque data = flatten_nested_hash(data) method = method.upper() params, data = (None, data) if method == 'POST' else (data, None) - sailthru_headers = {'User-Agent': 'Sailthru API Python Client %s; Python Version: %s' % ('2.3.5', platform.python_version())} + sailthru_headers = {'User-Agent': 'Sailthru API Python Client %s; Python Version: %s' % ('2.3.6', platform.python_version())} if headers and isinstance(headers, dict): for key, value in sailthru_headers.items(): headers[key] = value diff --git a/sailthru/sailthru_response.py b/sailthru/sailthru_response.py index c838bb8..16813d7 100644 --- a/sailthru/sailthru_response.py +++ b/sailthru/sailthru_response.py @@ -11,8 +11,8 @@ def __init__(self, response): self.json_error = None try: - self.json = json.loads(response.content) - except ValueError as e: + self.json = json.loads(response.text) + except (ValueError, TypeError) as e: self.json = None self.json_error = str(e) diff --git a/setup.py b/setup.py index 04b0fc9..ebdff8e 100644 --- a/setup.py +++ b/setup.py @@ -1,7 +1,7 @@ from setuptools import setup, find_packages setup(name='sailthru-client', - version='2.3.5', + version='2.3.6', packages=find_packages(), description='Python client for Sailthru API', long_description=open('README.md').read(), diff --git a/test/test_sailthru_client.py b/test/test_sailthru_client.py index b6275dd..164ed88 100644 --- a/test/test_sailthru_client.py +++ b/test/test_sailthru_client.py @@ -64,7 +64,7 @@ def test_check_for_valid_actions(self): def test_receive_verify_post(self): mock_http_request = MagicMock() - mock_http_request.return_value.get_body.return_value = '{"email":"menglander@sailthru.com"}' + mock_http_request.return_value.get_body.return_value = {"email": "menglander@sailthru.com"} self.client._http_request = mock_http_request @@ -126,7 +126,7 @@ def test_hardbounce_blast_invalid_json(self): def test_hardbounce_valid_json(self): mock_http_request = MagicMock() - mock_http_request.return_value.get_body.return_value = '{"email": "menglander@sailthru.com"}' + mock_http_request.return_value.get_body.return_value = {"email": "menglander@sailthru.com"} self.client._http_request = mock_http_request