diff --git a/README.rst b/README.rst index b8bbada..e104bac 100755 --- a/README.rst +++ b/README.rst @@ -4,8 +4,8 @@ Ubersmith API Client for Python .. image:: https://travis-ci.org/internap/python-ubersmithclient.svg?branch=master :target: https://travis-ci.org/internap/python-ubersmithclient -.. image:: https://img.shields.io/pypi/v/ubersmith_client.svg?style=flat - :target: https://pypi.python.org/pypi/ubersmith_client +.. image:: https://img.shields.io/pypi/v/python-ubersmithclient.svg?style=flat + :target: https://pypi.python.org/pypi/python-ubersmithclient Usage ----- @@ -13,7 +13,7 @@ Usage import ubersmith_client - api = ubersmith_client.api.init('http://ubersmith.com/api/2.0/', 'username', 'password') + api = ubersmith_client.api.init(url='http://ubersmith.com/api/2.0/', user='username', password='password') api.client.count() >>> u'264' api.client.latest_client() @@ -22,7 +22,7 @@ Usage API --------- -**ubersmith_client.api.init(url, user, password, timeout, use_http_post)** +**ubersmith_client.api.init(url, user, password, timeout, use_http_get)** :url: URL of your API @@ -33,7 +33,7 @@ API :timeout: api timeout given to requests *Default:* ``60`` - :use_http_post: - Use `POST` requests instead of `GET` + :use_http_get: + Use `GET` requests instead of `POST` *Default:* ``False`` diff --git a/requirements.txt b/requirements.txt index bbe3b59..c7317e0 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,2 +1 @@ requests<=2.9.1 -six>=1.10.0 diff --git a/test-requirements.txt b/test-requirements.txt index 11f684f..daf105d 100755 --- a/test-requirements.txt +++ b/test-requirements.txt @@ -1,4 +1,3 @@ nose==1.2.1 -requests-mock==0.7.0 pyhamcrest==1.8.1 -flexmock \ No newline at end of file +mock==1.3.0 \ No newline at end of file diff --git a/tests/__init__.py b/tests/__init__.py index 2f12658..a5b5ca9 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -11,10 +11,3 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. -def apply_kwargs(kwargs, default_kwargs): - for k, v in kwargs.items(): - if isinstance(v, dict): - default_kwargs[k] = apply_kwargs(v, default_kwargs[k]) - else: - default_kwargs[k] = v - return default_kwargs diff --git a/tests/api_test.py b/tests/api_test.py index 2442523..5bd2bb9 100644 --- a/tests/api_test.py +++ b/tests/api_test.py @@ -11,275 +11,125 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. -import base64 import unittest -import six.moves.urllib.parse as urllib_parse +from mock import patch, MagicMock -import requests - -from flexmock import flexmock, flexmock_teardown from hamcrest import assert_that, equal_to, raises, calling -import requests_mock -from requests_mock.exceptions import NoMockAddress -import ubersmith_client -from ubersmith_client import api -from ubersmith_client.exceptions import BadRequest, UnknownError, Forbidden, NotFound, Unauthorized + from tests.ubersmith_json.response_data_structure import a_response_data +import ubersmith_client -class UbersmithIWebTest(unittest.TestCase): +class ApiTest(unittest.TestCase): def setUp(self): - self.url = 'http://ubersmith.example.org/' + self.url = 'http://ubersmith.example.com/' self.username = 'admin' self.password = 'test' - def tearDown(self): - flexmock_teardown() + self.auth = (self.username, self.password) + self.timeout = 60 - @requests_mock.mock() - def test_api_method_returns_without_arguments(self, request_mock): - json_data = [ - { - 'client_id': '1', - 'first': 'John', - 'last': 'Snow', - 'company': 'The Night Watch' - } - ] - data = a_response_data(data=json_data) - self.expect_a_ubersmith_call(request_mock, "client.list", data=data) + @patch('ubersmith_client.ubersmith_request_get.requests') + def test_api_get_method_returns_without_arguments(self, requests_mock): + json_data = { + 'company': 'council of ricks' + } + expected_call = self.expect_a_ubersmith_call(requests_mock=requests_mock, + method='client.list', + returning=a_response_data(data=json_data)) - ubersmith_api = api.init(self.url, self.username, self.password) + ubersmith_api = ubersmith_client.api.init(self.url, self.username, self.password, use_http_get=True) response = ubersmith_api.client.list() assert_that(response, equal_to(json_data)) - @requests_mock.mock() - def test_api_method_returns_with_arguments(self, request_mock): + expected_call() + + @patch('ubersmith_client.ubersmith_request_get.requests') + def test_api_get_method_returns_with_arguments(self, request_mock): json_data = { 'group_id': '1', 'client_id': '30001', 'assignment_count': '1' } - data = a_response_data(data=json_data) - self.expect_a_ubersmith_call(request_mock, method="device.ip_group_list", fac_id='1', client_id='30001', - data=data) + expected_call = self.expect_a_ubersmith_call(requests_mock=request_mock, + method='device.ip_group_list', + fac_id=1, + client_id=30001, + returning=a_response_data(data=json_data)) - ubersmith_api = ubersmith_client.api.init(self.url, self.username, self.password) + ubersmith_api = ubersmith_client.api.init(self.url, self.username, self.password, use_http_get=True) response = ubersmith_api.device.ip_group_list(fac_id=1, client_id=30001) assert_that(response, equal_to(json_data)) - @requests_mock.mock() - def test_api_raises_exception_with_if_data_status_is_false(self, request_mock): - data = a_response_data(status=False, error_code=1, error_message="invalid method specified: client.miss", - data=None) - ubersmith_api = ubersmith_client.api.init(self.url, self.username, self.password) - - self.expect_a_ubersmith_call(request_mock, method="client.miss", data=data) - - with self.assertRaises(ubersmith_client.exceptions.UbersmithException) as cm: - ubersmith_api.client.miss() - - catched_exception = cm.exception - assert_that(catched_exception.code, equal_to(1)) - assert_that(catched_exception.message, equal_to('invalid method specified: client.miss')) - - @requests_mock.mock() - def test_api_raises_exception_for_invalid_status_code(self, request_mock): - method = "client.list" - ubersmith_api = ubersmith_client.api.init(self.url, self.username, self.password) - - self.expect_a_ubersmith_call(request_mock, method=method, status_code=400) - - assert_that(calling(ubersmith_api.client.list), raises(BadRequest)) - - self.expect_a_ubersmith_call(request_mock, method=method, status_code=401) - assert_that(calling(ubersmith_api.client.list), raises(Unauthorized)) + expected_call() - self.expect_a_ubersmith_call(request_mock, method=method, status_code=403) - assert_that(calling(ubersmith_api.client.list), raises(Forbidden)) - - self.expect_a_ubersmith_call(request_mock, method=method, status_code=404) - assert_that(calling(ubersmith_api.client.list), raises(NotFound)) - - self.expect_a_ubersmith_call(request_mock, method=method, status_code=500) - assert_that(calling(ubersmith_api.client.list), raises(UnknownError)) - - @requests_mock.mock() - def test_api_with_a_false_identifier(self, request_mock): - method = "client.list" - self.expect_a_ubersmith_call(request_mock, method=method) - ubersmith_api = ubersmith_client.api.init(self.url, 'not_hapi', 'lol') - - with self.assertRaises(NoMockAddress) as ube: - ubersmith_api.client.list() - - assert_that(str(ube.exception), equal_to("No mock address: GET " + self.url + "?method=" + method)) - - @requests_mock.mock() - def test_api_http_get_method(self, request_mock): + @patch('ubersmith_client.ubersmith_request_post.requests') + def test_api_post_method_returns_with_arguments(self, request_mock): json_data = { - 'group_id': '666', - 'client_id': '30666', + 'group_id': '1', + 'client_id': '30001', 'assignment_count': '1' } - data = a_response_data(data=json_data) - self.expect_a_ubersmith_call(request_mock, method="device.ip_group_list", fac_id='666', client_id='30666', - data=data) + expected_call = self.expect_a_ubersmith_call_post(requests_mock=request_mock, + method='device.ip_group_list', + fac_id=1, + client_id=30001, + returning=a_response_data(data=json_data)) - ubersmith_api = ubersmith_client.api.init(self.url, self.username, self.password) - response = ubersmith_api.device.ip_group_list.http_get(fac_id=666, client_id=30666) + ubersmith_api = ubersmith_client.api.init(self.url, self.username, self.password, use_http_get=False) + response = ubersmith_api.device.ip_group_list(fac_id=1, client_id=30001) assert_that(response, equal_to(json_data)) - @requests_mock.mock() - def test_api_http_get_method_default(self, request_mock): - json_data = { - 'group_id': '666', - 'client_id': '30666', - 'assignment_count': '1' - } - data = a_response_data(data=json_data) - self.expect_a_ubersmith_call(request_mock, method="device.ip_group_list", fac_id='666', client_id='30666', - data=data) - - ubersmith_api = ubersmith_client.api.init(self.url, self.username, self.password) - response = ubersmith_api.device.ip_group_list(fac_id=666, client_id=30666) + expected_call() - assert_that(response, equal_to(json_data)) - - @requests_mock.mock() - def test_api_http_post_method_default(self, request_mock): + @patch('ubersmith_client.ubersmith_request_post.requests') + def test_api_post_method_returns_without_arguments(self, requests_mock): json_data = { - 'group_id': '666', - 'client_id': '30666', - 'assignment_count': '1' + 'company': 'schwifty' } - data = a_response_data(data=json_data) - self.expect_a_ubersmith_call_post(request_mock, method='device.ip_group_list', fac_id='666', client_id='30666', - response_body=data) + expected_call = self.expect_a_ubersmith_call_post(requests_mock=requests_mock, + method='client.list', + returning=a_response_data(data=json_data)) - ubersmith_api = ubersmith_client.api.init(self.url, self.username, self.password, use_http_post=True) - response = ubersmith_api.device.ip_group_list(fac_id=666, client_id=30666) + ubersmith_api = ubersmith_client.api.init(self.url, self.username, self.password, use_http_get=False) + response = ubersmith_api.client.list() assert_that(response, equal_to(json_data)) - @requests_mock.mock() - def test_api_http_post_method_result_200(self, request_mock): - json_data = { - 'data': '778', - 'error_code': None, - 'error_message': '', - 'status': True - } - - self.expect_a_ubersmith_call_post( - request_mock, - method='support.ticket_submit', - body='ticket body', - subject='ticket subject', - response_body=json_data, - ) - - ubersmith_api = ubersmith_client.api.init(self.url, self.username, self.password) - response = ubersmith_api.support.ticket_submit.http_post(body='ticket body', subject='ticket subject') - - assert_that(response, equal_to(json_data.get('data'))) - - @requests_mock.mock() - def test_api_http_post_method_raises_on_result_414(self, request_mock): - json_data = { - 'data': '778', - 'error_code': None, - 'error_message': '', - 'status': True - } - - self.expect_a_ubersmith_call_post( - request_mock, - method='support.ticket_submit', - response_body=json_data, - status_code=414 - ) - - ubersmith_api = ubersmith_client.api.init(self.url, self.username, self.password) - - assert_that(calling(ubersmith_api.support.ticket_submit.http_post), raises(UnknownError)) + expected_call() - def test_api_http_timeout(self): - payload = dict(status=True, data="plop") - response = flexmock(status_code=200, json=lambda: payload) - ubersmith_api = ubersmith_client.api.init(self.url, self.username, self.password, 666) + @patch('ubersmith_client.ubersmith_request_post.requests') + def test_api_raises_exception_with_if_data_status_is_false(self, requests_mock): + data = a_response_data(status=False, + error_code=1, + error_message='invalid method specified: client.miss', + data="schwifty") + ubersmith_api = ubersmith_client.api.init(self.url, self.username, self.password, use_http_get=False) - flexmock(requests).should_receive("get").with_args( - url=self.url, auth=(self.username, self.password), timeout=666, params={'method': 'uber.method_list'} - ).and_return(response) + self.expect_a_ubersmith_call_post(requests_mock, method='client.miss', returning=data) + assert_that(calling(ubersmith_api.client.miss), raises(ubersmith_client.exceptions.UbersmithException)) - ubersmith_api.uber.method_list() - - def test_api_http_default_timeout(self): - payload = dict(status=True, data="plop") - response = flexmock(status_code=200, json=lambda: payload) - ubersmith_api = ubersmith_client.api.init(self.url, self.username, self.password) - - flexmock(requests).should_receive("get").with_args( - url=self.url, auth=(self.username, self.password), timeout=60, params={'method': 'uber.method_list'} - ).and_return(response) - - ubersmith_api.uber.method_list() - - @requests_mock.mock() - def test_api_http_post_method_raises_on_result_500(self, request_mock): - json_data = { - 'data': '778', - 'error_code': None, - 'error_message': '', - 'status': False - } - - self.expect_a_ubersmith_call_post( - request_mock, - method='support.ticket_submit', - response_body=json_data, - ) - - ubersmith_api = ubersmith_client.api.init(self.url, self.username, self.password) - - assert_that(calling(ubersmith_api.support.ticket_submit.http_post), - raises(ubersmith_client.exceptions.UbersmithException)) - - def expect_a_ubersmith_call(self, request_mock, method, data=None, status_code=200, **kwargs): - url = self.url + '?' + get_url_params(method, **kwargs) - headers = { - 'Content-Type': 'application/json', - } - request_mock.get(url, json=data, headers=headers, request_headers={ - 'Authorization': self.get_auth_header() - }, status_code=status_code) - - def expect_a_ubersmith_call_post(self, request_mock, method, response_body=None, status_code=200, **kwargs): - headers = { - 'Content-Type': 'application/json', - } - expected_text = get_url_params(method, **kwargs) + def expect_a_ubersmith_call(self, requests_mock, returning=None, **kwargs): + response = MagicMock(status_code=200) + requests_mock.get = MagicMock(return_value=response) + response.json = MagicMock(return_value=returning) - def response_callback(request, context): - expected_params = urllib_parse.parse_qs(expected_text) - parsed_params = urllib_parse.parse_qs(request.text) - assert_that(parsed_params, equal_to(expected_params)) - return response_body + def assert_called_with(): + requests_mock.get.assert_called_with(auth=self.auth, params=kwargs, timeout=self.timeout, url=self.url) + response.json.assert_called_with() - request_mock.post(self.url, json=response_callback, headers=headers, request_headers={ - 'Authorization': self.get_auth_header(), - 'Content-Type': 'application/x-www-form-urlencoded' - }, status_code=status_code) + return assert_called_with - def get_auth_header(self): - auth = base64.b64encode((self.username + ':' + self.password).encode('utf-8')) - return 'Basic ' + auth.decode('utf-8') + def expect_a_ubersmith_call_post(self, requests_mock, returning=None, status_code=200, **kwargs): + response = MagicMock(status_code=status_code) + requests_mock.post = MagicMock(return_value=response) + response.json = MagicMock(return_value=returning) + def assert_called_with(): + requests_mock.post.assert_called_with(auth=self.auth, timeout=self.timeout, url=self.url, data=kwargs) + response.json.assert_called_with() -def get_url_params(method, **kwargs): - kwargs['method'] = method - return urllib_parse.urlencode(kwargs) + return assert_called_with diff --git a/tests/exceptions_test.py b/tests/exceptions_test.py deleted file mode 100644 index affb3f1..0000000 --- a/tests/exceptions_test.py +++ /dev/null @@ -1,9 +0,0 @@ -import unittest -from ubersmith_client.exceptions import UbersmithException - - -class ExceptionTestTest(unittest.TestCase): - - def test_UbersmithException_has_string_representation(self): - ex = UbersmithException(code=42, message='Wubba Lubba Dub Dub') - self.assertEquals("{0}".format(ex), "Error code 42 - message: Wubba Lubba Dub Dub") diff --git a/tests/ubersmith_json/__init__.py b/tests/ubersmith_json/__init__.py index f44d680..a5b5ca9 100644 --- a/tests/ubersmith_json/__init__.py +++ b/tests/ubersmith_json/__init__.py @@ -10,4 +10,4 @@ # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and -# limitations under the License. \ No newline at end of file +# limitations under the License. diff --git a/tests/ubersmith_json/response_data_structure.py b/tests/ubersmith_json/response_data_structure.py index 56ea561..216fe13 100644 --- a/tests/ubersmith_json/response_data_structure.py +++ b/tests/ubersmith_json/response_data_structure.py @@ -11,7 +11,7 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. -from tests import apply_kwargs + def a_response_data(**overrides): return apply_kwargs(overrides, { @@ -20,3 +20,12 @@ def a_response_data(**overrides): "error_message": "", "data": {}, }) + + +def apply_kwargs(kwargs, default_kwargs): + for k, v in kwargs.items(): + if isinstance(v, dict): + default_kwargs[k] = apply_kwargs(v, default_kwargs[k]) + else: + default_kwargs[k] = v + return default_kwargs diff --git a/tests/ubersmith_request_test.py b/tests/ubersmith_request_test.py new file mode 100644 index 0000000..e3bf5a2 --- /dev/null +++ b/tests/ubersmith_request_test.py @@ -0,0 +1,59 @@ +# Copyright 2016 Internap. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +import unittest +from mock import Mock + +from hamcrest import assert_that, raises, calling + +from ubersmith_client.exceptions import UbersmithException, BadRequest, UnknownError, Forbidden, NotFound, Unauthorized +from tests.ubersmith_json.response_data_structure import a_response_data +from ubersmith_client.ubersmith_request import UbersmithRequest + + +class UbersmithRequestTest(unittest.TestCase): + def test_process_ubersmith_response(self): + response = Mock() + response.status_code = 200 + json_data = { + 'client_id': '1', + 'first': 'Rick', + 'last': 'Sanchez', + 'company': 'Wubba lubba dub dub!' + } + + response.json = Mock(return_value=a_response_data(data=json_data)) + + self.assertDictEqual(json_data, UbersmithRequest.process_ubersmith_response(response)) + + def test_process_ubersmith_response_raise_exception(self): + response = Mock() + response.status_code = 400 + assert_that(calling(UbersmithRequest.process_ubersmith_response).with_args(response), raises(BadRequest)) + + response.status_code = 401 + assert_that(calling(UbersmithRequest.process_ubersmith_response).with_args(response), raises(Unauthorized)) + + response.status_code = 403 + assert_that(calling(UbersmithRequest.process_ubersmith_response).with_args(response), raises(Forbidden)) + + response.status_code = 404 + assert_that(calling(UbersmithRequest.process_ubersmith_response).with_args(response), raises(NotFound)) + + response.status_code = 500 + assert_that(calling(UbersmithRequest.process_ubersmith_response).with_args(response), raises(UnknownError)) + + response.status_code = 200 + response.json = Mock(return_value={'status': False, 'error_code': 42, 'error_message': 'come and watch tv'}) + assert_that(calling(UbersmithRequest.process_ubersmith_response).with_args(response), + raises(UbersmithException, "Error code 42 - message: come and watch tv")) diff --git a/ubersmith_client/__init__.py b/ubersmith_client/__init__.py index 6daacf5..5921267 100644 --- a/ubersmith_client/__init__.py +++ b/ubersmith_client/__init__.py @@ -10,6 +10,7 @@ # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and +# limitations under the License. from . import api from . import exceptions diff --git a/ubersmith_client/api.py b/ubersmith_client/api.py index be7c66d..c6c39ba 100644 --- a/ubersmith_client/api.py +++ b/ubersmith_client/api.py @@ -11,84 +11,9 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. -import requests -from ubersmith_client.exceptions import UbersmithException, get_exception_for +from ubersmith_client.ubersmith_api import UbersmithApi -def init(url, user, password, timeout=60, use_http_post=False): - return UbersmithApi(url, user, password, timeout, use_http_post) - - -class UbersmithApi(object): - def __init__(self, url, user, password, timeout, use_http_post): - self.url = url - self.user = user - self.password = password - self.timeout = timeout - self.use_http_post = use_http_post - - def __getattr__(self, module): - return UbersmithRequest(self.url, self.user, self.password, module, self.timeout, self.use_http_post) - - -class UbersmithRequest(object): - def __init__(self, url, user, password, module, timeout, use_http_post): - self.url = url - self.user = user - self.password = password - self.module = module - self.methods = [] - self.http_methods = {'GET': 'get', 'POST': 'post'} - self.timeout = timeout - self.use_http_post = use_http_post - - def __getattr__(self, function): - self.methods.append(function) - return self - - def __call__(self, **kwargs): - if self.use_http_post: - return self.http_post(**kwargs) - else: - return self.http_get(**kwargs) - - def process_request(self, http_method, **kwargs): - callable_http_method = getattr(requests, http_method) - - response = callable_http_method( - self.url, - auth=(self.user, self.password), - timeout=self.timeout, - **kwargs - ) - - if response.status_code < 200 or response.status_code >= 400: - raise get_exception_for(status_code=response.status_code) - - response_json = response.json() - if not response_json['status']: - raise UbersmithException( - response_json['error_code'], - response_json['error_message'] - ) - - return response.json()["data"] - - def http_get(self, **kwargs): - self._build_request_params(kwargs) - - response = self.process_request(self.http_methods.get('GET'), params=kwargs) - - return response - - def http_post(self, **kwargs): - self._build_request_params(kwargs) - - response = self.process_request(self.http_methods.get('POST'), data=kwargs) - - return response - - def _build_request_params(self, kwargs): - _methods = ".".join(self.methods) - kwargs['method'] = "{0}.{1}".format(self.module, _methods) +def init(url, user, password, timeout=60, use_http_get=False): + return UbersmithApi(url, user, password, timeout, use_http_get) diff --git a/ubersmith_client/ubersmith_api.py b/ubersmith_client/ubersmith_api.py new file mode 100644 index 0000000..4731bc5 --- /dev/null +++ b/ubersmith_client/ubersmith_api.py @@ -0,0 +1,26 @@ +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +from ubersmith_client.ubersmith_request_get import UbersmithRequestGet +from ubersmith_client.ubersmith_request_post import UbersmithRequestPost + + +class UbersmithApi(object): + def __init__(self, url, user, password, timeout, use_http_get): + self.url = url + self.user = user + self.password = password + self.timeout = timeout + self.ubersmith_request = UbersmithRequestGet if use_http_get else UbersmithRequestPost + + def __getattr__(self, module): + return self.ubersmith_request(self.url, self.user, self.password, module, self.timeout) diff --git a/ubersmith_client/ubersmith_request.py b/ubersmith_client/ubersmith_request.py new file mode 100644 index 0000000..d02785d --- /dev/null +++ b/ubersmith_client/ubersmith_request.py @@ -0,0 +1,51 @@ +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +from abc import abstractmethod + +from ubersmith_client.exceptions import get_exception_for, UbersmithException + + +class UbersmithRequest(object): + def __init__(self, url, user, password, module, timeout): + self.url = url + self.user = user + self.password = password + self.module = module + self.methods = [] + self.timeout = timeout + + def __getattr__(self, function): + self.methods.append(function) + return self + + @abstractmethod + def __call__(self, **kwargs): + raise + + def _build_request_params(self, kwargs): + _methods = ".".join(self.methods) + kwargs['method'] = "{0}.{1}".format(self.module, _methods) + + @staticmethod + def process_ubersmith_response(response): + if response.status_code < 200 or response.status_code >= 400: + raise get_exception_for(status_code=response.status_code) + + response_json = response.json() + if not response_json['status']: + raise UbersmithException( + response_json['error_code'], + response_json['error_message'] + ) + + return response.json()["data"] diff --git a/ubersmith_client/ubersmith_request_get.py b/ubersmith_client/ubersmith_request_get.py new file mode 100644 index 0000000..c7d48e0 --- /dev/null +++ b/ubersmith_client/ubersmith_request_get.py @@ -0,0 +1,31 @@ +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +import requests + +from ubersmith_client.ubersmith_request import UbersmithRequest + + +class UbersmithRequestGet(UbersmithRequest): + def __getattr__(self, function): + self.methods.append(function) + return self + + def __call__(self, **kwargs): + self._build_request_params(kwargs) + + response = requests.get(url=self.url, + auth=(self.user, self.password), + timeout=self.timeout, + params=kwargs) + + return UbersmithRequest.process_ubersmith_response(response) diff --git a/ubersmith_client/ubersmith_request_post.py b/ubersmith_client/ubersmith_request_post.py new file mode 100644 index 0000000..73ad2a8 --- /dev/null +++ b/ubersmith_client/ubersmith_request_post.py @@ -0,0 +1,27 @@ +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +import requests + +from ubersmith_client.ubersmith_request import UbersmithRequest + + +class UbersmithRequestPost(UbersmithRequest): + def __call__(self, **kwargs): + self._build_request_params(kwargs) + + response = requests.post(url=self.url, + auth=(self.user, self.password), + timeout=self.timeout, + data=kwargs) + + return UbersmithRequest.process_ubersmith_response(response)