diff --git a/.travis.yml b/.travis.yml index 861c52c..16ca240 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,6 +2,7 @@ language: python python: - '2.6' - '2.7' +- '3.4' install: - pip install -r requirements.txt script: diff --git a/lob/api_requestor.py b/lob/api_requestor.py index c05b94b..ed8c64d 100644 --- a/lob/api_requestor.py +++ b/lob/api_requestor.py @@ -1,9 +1,11 @@ +from __future__ import unicode_literals + import requests + import lob -import json -import resource from lob import error -from version import VERSION +from lob.version import VERSION + def _is_file_like(obj): """ @@ -20,7 +22,7 @@ def __init__(self, key=None): self.api_key = key or lob.api_key def parse_response(self, resp): - payload = json.loads(resp.content) + payload = resp.json() if resp.status_code == 200: return payload elif resp.status_code == 401: @@ -54,22 +56,22 @@ def request(self, method, url, params=None): files = params.pop('files', {}) explodedParams = {} - for k,v in params.iteritems(): - if isinstance(v, dict) and not isinstance(v, resource.LobObject): - for k2,v2 in v.iteritems(): + for k,v in params.items(): + if isinstance(v, dict) and not isinstance(v, lob.resource.LobObject): + for k2,v2 in v.items(): explodedParams[k + '[' + k2 + ']'] = v2 else: explodedParams[k] = v - for k,v in explodedParams.iteritems(): + for k,v in explodedParams.items(): if _is_file_like(v): files[k] = v else: - if isinstance(v, resource.LobObject): + if isinstance(v, lob.resource.LobObject): data[k] = v.id else: if isinstance(v, dict): - for k2, v2 in v.iteritems(): + for k2, v2 in v.items(): data[k + '[' + k2 + ']'] = v2 else: data[k] = v @@ -77,4 +79,3 @@ def request(self, method, url, params=None): return self.parse_response( requests.post(lob.api_base + url, auth=(self.api_key, ''), data=data, files=files, headers=headers) ) - diff --git a/lob/compat.py b/lob/compat.py new file mode 100644 index 0000000..8de5ba9 --- /dev/null +++ b/lob/compat.py @@ -0,0 +1,9 @@ +import sys + + +if sys.version_info[0] == 3: # pragma: no cover + string_type = str + from io import BytesIO +else: # pragma: no cover + string_type = basestring + from StringIO import StringIO as BytesIO diff --git a/lob/error.py b/lob/error.py index 334f8a0..966f23f 100644 --- a/lob/error.py +++ b/lob/error.py @@ -1,3 +1,6 @@ +from __future__ import unicode_literals + + class LobError(Exception): def __init__(self, message=None, http_body=None, http_status=None, diff --git a/lob/resource.py b/lob/resource.py index 9309fb1..380a424 100644 --- a/lob/resource.py +++ b/lob/resource.py @@ -1,6 +1,11 @@ +from __future__ import unicode_literals + +import json + from lob import api_requestor from lob import error -import json +from lob.compat import string_type + def lob_format(resp): types = { @@ -30,7 +35,7 @@ def lob_format(resp): return LobObject.construct_from(resp) if isinstance(resp, dict) and not isinstance(resp, LobObject): resp = resp.copy() - if 'object' in resp and isinstance(resp['object'], basestring): + if 'object' in resp and isinstance(resp['object'], string_type): klass = types.get(resp['object'], LobObject) else: klass = LobObject @@ -53,14 +58,14 @@ def __init__(self, id=None, **params): @classmethod def construct_from(cls, values): instance = cls(values.get('id')) - for k, v in values.iteritems(): + for k, v in values.items(): instance[k] = lob_format(v) return instance def __getattr__(self, k): try: return self[k] - except KeyError, err: + except KeyError: raise AttributeError(k) #pragma: no cover def __setattr__(self, k, v): @@ -69,10 +74,10 @@ def __setattr__(self, k, v): def __repr__(self): ident_parts = [type(self).__name__] - if isinstance(self.get('object'), basestring): + if isinstance(self.get('object'), string_type): ident_parts.append(self.get('object')) - if isinstance(self.get('id'), basestring): + if isinstance(self.get('id'), string_type): ident_parts.append('id=%s' % (self.get('id'),)) unicode_repr = '<%s at %s> JSON: %s' % ( diff --git a/lob/version.py b/lob/version.py index 2380056..6c55623 100644 --- a/lob/version.py +++ b/lob/version.py @@ -1 +1,3 @@ +from __future__ import unicode_literals + VERSION = '2.16' diff --git a/tests/test_object.py b/tests/test_object.py index 2a8a083..00a5dce 100644 --- a/tests/test_object.py +++ b/tests/test_object.py @@ -1,9 +1,11 @@ -from StringIO import StringIO import unittest + import lob +from lob.compat import BytesIO # Setting the API key lob.api_key = 'test_0dc8d51e0acffcb1880e0f19c79b2f5b0cc' + class ObjectFunctions(unittest.TestCase): def setUp(self): lob.api_key = 'test_0dc8d51e0acffcb1880e0f19c79b2f5b0cc' @@ -34,13 +36,13 @@ def test_create_object_remote(self): def test_create_object_stringio(self): object = lob.Object.create( - description = 'Test Object StringIO', - file = StringIO(open('tests/pc.pdf', 'rb').read()), + description = 'Test Object BytesIO', + file = BytesIO(open('tests/pc.pdf', 'rb').read()), setting = 201 ) self.assertTrue(isinstance(object, lob.Object)) - self.assertEqual(object.description, 'Test Object StringIO') + self.assertEqual(object.description, 'Test Object BytesIO') def test_create_object_local(self): object = lob.Object.create( diff --git a/tests/test_packaging.py b/tests/test_packaging.py index 25861cf..a3c1229 100644 --- a/tests/test_packaging.py +++ b/tests/test_packaging.py @@ -1,3 +1,5 @@ +from __future__ import print_function + import unittest import lob # Setting the API key @@ -8,5 +10,5 @@ def setUp(self): lob.api_key = 'test_0dc8d51e0acffcb1880e0f19c79b2f5b0cc' def test_packaging_list(self): - print lob.Packaging.list() + print(lob.Packaging.list()) diff --git a/tests/test_route.py b/tests/test_route.py index f2d06c3..805ef49 100644 --- a/tests/test_route.py +++ b/tests/test_route.py @@ -1,3 +1,5 @@ +from __future__ import print_function + import unittest import lob # Setting the API key @@ -8,4 +10,4 @@ def setUp(self): lob.api_key = 'test_0dc8d51e0acffcb1880e0f19c79b2f5b0cc' def test_route_find(self): - print lob.Route.list(zip_codes=[94158,60031]) + print(lob.Route.list(zip_codes=[94158,60031]))