diff --git a/.travis.yml b/.travis.yml index 786447e..35252f6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,5 @@ language: python python: - - "2.6" - "2.7" - "3.2" - "3.3" diff --git a/Makefile b/Makefile index d012744..399e57d 100644 --- a/Makefile +++ b/Makefile @@ -20,6 +20,9 @@ init: clean setup test setup: distribute pip install -r requirements.txt -t $(target) -b $(source) +console: + $(pypath) python + clean: rm -rf $(source) $(target) .ropeproject .coverage junit-report.xml find . -type f -name "*.pyc" -exec rm -v {} \; diff --git a/maxcdn/maxcdn.py b/maxcdn/maxcdn.py index bb43278..08e129e 100644 --- a/maxcdn/maxcdn.py +++ b/maxcdn/maxcdn.py @@ -1,8 +1,9 @@ from requests_oauthlib import OAuth1Session as OAuth1 +# handle python 3.x try: import urlparse -except ImportError: # handly python 3.x +except ImportError: from urllib import parse as urlparse @@ -19,26 +20,33 @@ def _get_headers(self, json=True): def _get_url(self, end_point): if not end_point.startswith("/"): - return "%s/%s" % (self.url, end_point) + return "{0}/{1}".format(self.url, end_point) else: return self.url + end_point + def _parse_json(self, response): + try: + return response.json() + except ValueError as e: + raise self.ServerError(response, str(e)) + def _data_request(self, method, end_point, data, **kwargs): if data is None and "params" in kwargs: params = kwargs.pop("params") if type(params) is str: params = urlparse.parse_qs(params) data = params - action = getattr(self.client, method) - return action(self._get_url(end_point), data=data, - headers=self._get_headers(json=True), **kwargs).json() + response = action(self._get_url(end_point), data=data, + headers=self._get_headers(json=True), **kwargs) + + if (response.status_code > 299): + raise self.ServerError(response) + + return self._parse_json(response) def get(self, end_point, data=None, **kwargs): return self._data_request("post", end_point, data=data, **kwargs) - #return self.client.get(self._get_url(end_point), data, - #headers=self._get_headers(json=False), - #**kwargs).json() def patch(self, end_point, data=None, **kwargs): return self._data_request("post", end_point, data=data, **kwargs) @@ -57,3 +65,26 @@ def purge(self, zoneid, file_or_files=None, **kwargs): if file_or_files is not None: return self.delete(path, data={"files": file_or_files}, **kwargs) return self.delete(path, **kwargs) + + class ServerError(Exception): + def __init__(self, response, message=None): + try: + resp = response.json() + if message is None: + message = "{0}:: {1}".format(resp['error']['type'], + resp['error']['message']) + self.reason = resp['error']['type'] + except ValueError: + if message is None: + message = "{0} {1} from {2}".format(response.status_code, + response.reason, + response.url) + + self.reason = response.reason + + self.headers = response.headers + self.code = response.status_code + self.body = response._content + self.url = response.url + + super(Exception, self).__init__(message) diff --git a/test/test.py b/test/test.py index 8a400db..7b4275a 100644 --- a/test/test.py +++ b/test/test.py @@ -12,18 +12,38 @@ def mock_request(method, url, *args, **kwargs): class Response(object): def __init__(self, method, code=200, data={"foo": "bar"}): self._json = {"code": code, "method": method, "data": data} + self.status_code = code + self.reason = "Success" + self.headers = "" + self.url = "http://www.example.com/foo/bar" def json(self): return self._json +class ErrorResponse(object): + def __init__(self, code=200, badcontent="Some bad content."): + self._content = badcontent + self.status_code = code + self.reason = "Error Response" + self.headers = "" + self.url = "http://www.example.com/foo/bar" + + def json(self): + raise ValueError("No JSON object could be decoded") + + def response(method, **kwargs): return Response(method, **kwargs) +def error_response(**kwargs): + return ErrorResponse(**kwargs) + # ############################################################################### + class MaxCDNTests(unittest.TestCase): def setUp(self): @@ -56,6 +76,11 @@ def test_data_request(self): expected = {"code": 200, "method": meth, "data": {"foo": "bar"}} self.assertEqual(rsp, expected) + requests.Session.request = mock.create_autospec(mock_request, + return_value=error_response()) + with self.assertRaises(MaxCDN.ServerError, None): + self.maxcdn._data_request(meth, meth+".json", data={"foo":"bar"}) + def test_get(self): requests.Session.request = mock.create_autospec(mock_request, return_value=response("get")) @@ -63,6 +88,11 @@ def test_get(self): expected = {"code": 200, "method": "get", "data": {"foo": "bar"}} self.assertEqual(self.maxcdn.get("/get.json"), expected) + requests.Session.request = mock.create_autospec(mock_request, + return_value=error_response()) + with self.assertRaises(MaxCDN.ServerError, None): + self.maxcdn.get("/get.json") + def test_post(self): requests.Session.request = mock.create_autospec(mock_request, return_value=response("post"))