summaryrefslogtreecommitdiff
path: root/ick2/client.py
diff options
context:
space:
mode:
authorLars Wirzenius <liw@liw.fi>2018-03-17 16:59:16 +0200
committerLars Wirzenius <liw@liw.fi>2018-03-30 10:11:32 +0300
commit87001d6a0c5d9d8b48e716ec733e5ba6c0c4afd4 (patch)
treecebdf8da53237de0740fd0911f8bca80b8134ba4 /ick2/client.py
parentb211b8918ba5dcbdfad04a7b84b2c7ba27b4070f (diff)
downloadick2-87001d6a0c5d9d8b48e716ec733e5ba6c0c4afd4.tar.gz
Add: HttpAPI class for using REST-ful HTTP API
Diffstat (limited to 'ick2/client.py')
-rw-r--r--ick2/client.py105
1 files changed, 105 insertions, 0 deletions
diff --git a/ick2/client.py b/ick2/client.py
new file mode 100644
index 0000000..a474987
--- /dev/null
+++ b/ick2/client.py
@@ -0,0 +1,105 @@
+# Copyright (C) 2018 Lars Wirzenius
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+
+import json
+
+
+import requests
+
+
+class HttpError(Exception):
+
+ pass
+
+
+class HttpAPI:
+
+ # Make requests to an HTTP API.
+
+ json_type = 'application/json'
+
+ def __init__(self):
+ self._session = requests.Session()
+ self._token = None
+
+ def set_session(self, session):
+ self._session = session
+
+ def set_token(self, token):
+ self._token = token
+
+ def get_dict(self, url, headers=None):
+ r = self._request(self._session.get, url, headers=headers)
+ ct = r.headers.get('Content-Type')
+ if ct != self.json_type:
+ raise HttpError('Not JSON response')
+ try:
+ return r.json()
+ except json.decoder.JSONDecodeError:
+ raise HttpError('JSON parsing error')
+
+ def get_blob(self, url, headers=None):
+ r = self._request(self._session.get, url, headers=headers)
+ return r.content
+
+ def post(self, url, headers=None, body=None):
+ self._send_request(self._session.post, url, headers=headers, body=body)
+ return None
+
+ def put(self, url, headers=None, body=None):
+ self._send_request(self._session.put, url, headers=headers, body=body)
+ return None
+
+ def _send_request(self, func, url, headers=None, body=None):
+ if headers is None:
+ headers = {}
+ headers = dict(headers)
+ h, body = self._get_content_type_header(body)
+ headers.update(h)
+ self._request(func, url, headers=headers, data=body)
+ return None
+
+ def _get_content_type_header(self, body):
+ if isinstance(body, dict):
+ header = {
+ 'Content-Type': 'application/json',
+ }
+ body = json.dumps(body)
+ return header, body
+ return {}, body
+
+ def _get_authorization_headers(self):
+ return {
+ 'Authorization': 'Bearer {}'.format(self._token),
+ }
+
+ def _request(self, func, url, headers=None, **kwargs):
+ if headers is None:
+ headers = {}
+ headers.update(self._get_authorization_headers())
+
+ logging.debug('request: func=%r', func)
+ logging.debug('request: url=%r', url)
+ for h in headers:
+ logging.debug('request: %s: %s', h, headers[h])
+ logging.debug('request: kwargs=%r', kwargs)
+
+ r = func(url, headers=headers, verify=False, **kwargs)
+ logging.debug('response: status_code=%r', r.status_code)
+ logging.debug('response: content=%r', r.content)
+
+ if not r.ok:
+ raise HttpError(r.status_code)
+ return r