diff options
author | Lars Wirzenius <liw@liw.fi> | 2019-07-20 17:18:23 +0300 |
---|---|---|
committer | Lars Wirzenius <liw@liw.fi> | 2019-08-03 21:06:50 +0300 |
commit | b87027a3c7d3bc88e2674c9e22c8745c9dbf1043 (patch) | |
tree | a0f74e34dde2bb69a38223bec3d71cea7e1d311f /ick2 | |
parent | 066664763f16318076e34d702cce746b2fd4afca (diff) | |
download | ick2-b87027a3c7d3bc88e2674c9e22c8745c9dbf1043.tar.gz |
Add: MuckStore
Diffstat (limited to 'ick2')
-rw-r--r-- | ick2/__init__.py | 2 | ||||
-rw-r--r-- | ick2/apibase.py | 3 | ||||
-rw-r--r-- | ick2/exceptions.py | 6 | ||||
-rw-r--r-- | ick2/store.py | 83 |
4 files changed, 93 insertions, 1 deletions
diff --git a/ick2/__init__.py b/ick2/__init__.py index 2720d61..235ee96 100644 --- a/ick2/__init__.py +++ b/ick2/__init__.py @@ -17,6 +17,7 @@ from .version import __version__, __version_info__ from .logging import setup_logging, log from .store import ( MemoryStore, + MuckStore, ) from .resource import ( Resource, @@ -51,6 +52,7 @@ from .exceptions import ( NotFound, ExistsAlready, Conflict, + StoreError, IckException, MethodNotAllowed, ClientIdMissing, diff --git a/ick2/apibase.py b/ick2/apibase.py index 3827f6e..46c17cf 100644 --- a/ick2/apibase.py +++ b/ick2/apibase.py @@ -23,7 +23,8 @@ class APIbase: def __init__(self, state): assert (state is None or - isinstance(state, ick2.MemoryStore)) + isinstance(state, ick2.MemoryStore) or + isinstance(state, ick2.MuckStore)) self._trans = ick2.TransactionalState(state) def get_routes(self, path): diff --git a/ick2/exceptions.py b/ick2/exceptions.py index bd394af..8467e7a 100644 --- a/ick2/exceptions.py +++ b/ick2/exceptions.py @@ -40,6 +40,12 @@ class Conflict(IckException): rid, expected, got)) +class StoreError(IckException): + + def __init__(self, msg): + super().__init__('Error accessing persistent store: {}'.format(msg)) + + class BadUpdate(IckException): def __init__(self, how): diff --git a/ick2/store.py b/ick2/store.py index 5c01f89..83a008b 100644 --- a/ick2/store.py +++ b/ick2/store.py @@ -15,9 +15,13 @@ import copy +import json import uuid +import requests + + import ick2 @@ -75,3 +79,82 @@ class MemoryStore(StoreInterface): def delete(self, token, rid): del self._objs[rid] + + +class MuckStore(StoreInterface): # pragma: no cover + + def __init__(self, muck_url): + self._url = muck_url + ick2.log.log('info', msg_text='MuckStore created', muck_url=muck_url) + + def _request(self, func, path, token, headers=None, body=None): + url = '{}{}'.format(self._url, path) + if headers is None: + headers = {} + headers['Authorization'] = 'Bearer {}'.format(token) + r = func(url, headers=headers, data=body) + ick2.log.log( + 'trace', msg_text='Accessing Muck', + func=repr(func), url=url, path=path, headers=headers, data=body, + status=r.status_code, text=r.text) + if not r.ok: + raise ick2.StoreError(r.text) + return r + + def search(self, token, cond): + headers = { + 'Content-Type': 'application/json', + } + cond = { + 'cond': [ + { + 'where': 'meta', + 'field': 'id', + 'op': '>=', + 'pattern': '', + } + ], + } + body = json.dumps(cond) + r = self._request( + requests.get, '/search', token, headers=headers, body=body) + obj = r.json() + return obj['resources'] + + def create(self, token, obj): + headers = { + 'Content-Type': 'application/json', + } + body = json.dumps(obj) + r = self._request( + requests.post, '/res', token, headers=headers, body=body) + rid = r.headers['Muck-Id'] + rev = r.headers['Muck-Revision'] + return rid, rev + + def show(self, token, rid): + headers = { + 'Muck-Id': rid, + } + r = self._request(requests.get, '/res', token, headers=headers) + rev = r.headers['Muck-Revision'] + as_dict = r.json() + return as_dict, rev + + def update(self, token, rid, obj, revision): + headers = { + 'Content-Type': 'application/json', + 'Muck-Id': rid, + 'Muck-Revision': revision, + } + body = json.dumps(obj) + r = self._request( + requests.put, '/res', token, headers=headers, body=body) + rev = r.headers['Muck-Revision'] + return rev + + def delete(self, token, rid): + headers = { + 'Muck-Id': rid, + } + self._request(requests.delete, '/res', token, headers=headers) |