summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKristofer Hallin <kristofer@sunet.se>2021-10-14 09:48:17 +0200
committerKristofer Hallin <kristofer@sunet.se>2021-10-14 09:48:17 +0200
commit583542443adb2d66208dacb71581bc2936c59201 (patch)
tree30d6cd714e1ae5058303c46fef901054d8d5334a
parentc3330191348b19be264eabf5e0acd5fb97f0568d (diff)
Find, now with pagination! Use limit and skip to get the results you want.
-rw-r--r--README.md4
-rwxr-xr-xsrc/db.py19
-rwxr-xr-xsrc/wsgi.py45
3 files changed, 47 insertions, 21 deletions
diff --git a/README.md b/README.md
index 4348660..8ef8971 100644
--- a/README.md
+++ b/README.md
@@ -97,3 +97,7 @@ We might also filter the data:
Believe it or not, but we can also get a single observation by looking up its key:
curl -s -u user1:pw1 http://localhost:80/sc/v0/get/1633633714355 | json_pp -json_opt utf8,pretty
+
+We can also limit the number of results and skip N results forward with the parameters limit and skip:
+
+ curl -s -u user1:pw1 http://localhost:80/sc/v0/get?limit=5&skip=2 | json_pp -json_opt utf8,pretty
diff --git a/src/db.py b/src/db.py
index f9d0da1..8ab98e7 100755
--- a/src/db.py
+++ b/src/db.py
@@ -76,24 +76,35 @@ class DictDB():
def slice(self, key_from=None, key_to=None):
pass
- def search(self, **kwargs):
+ def search(self, limit=25, skip=0, **kwargs):
"""
- Execute a Mango query, ideally we should have an index matching the,
+ Execute a Mango query, ideally we should have an index matching
the query otherwise things will be slow.
"""
data = list()
selector = dict()
+ try:
+ limit = int(limit)
+ skip = int(skip)
+ except ValueError:
+ limit = 25
+ skip = 0
+
if kwargs:
- selector = {"selector": {}}
+ selector = {
+ "limit": limit,
+ "skip": skip,
+ "selector": {}
+ }
for key in kwargs:
if kwargs[key].isnumeric():
kwargs[key] = int(kwargs[key])
selector['selector'][key] = {'$eq': kwargs[key]}
- for doc in self.couchdb.find(selector):
+ for doc in self.couchdb.find(selector, wrapper=None, limit=5):
data.append(doc)
return data
diff --git a/src/wsgi.py b/src/wsgi.py
index 62db3c9..b547ffa 100755
--- a/src/wsgi.py
+++ b/src/wsgi.py
@@ -33,9 +33,11 @@ class CollectorResource():
def user_auth(self, auth_header, authfun):
if not auth_header:
return None, None # Fail.
+
BAlit, b64 = auth_header.split()
if BAlit != "Basic":
return None, None # Fail
+
userbytes, pwbytes = b64decode(b64).split(b':')
try:
user = userbytes.decode('utf-8')
@@ -50,14 +52,19 @@ class EPGet(CollectorResource):
out = list()
selectors = dict()
+ limit = 25
+ skip = 0
+
resp.status = falcon.HTTP_200
resp.content_type = falcon.MEDIA_JSON
orgs = self.user_auth(req.auth, self._users.read_perms)
if not orgs:
resp.status = falcon.HTTP_401
- resp.text = json.dumps(
- {'status': 'error', 'message': 'Invalid username or password\n'})
+ resp.text = json.dumps({
+ 'status': 'error',
+ 'message': 'Invalid username or password\n'
+ })
return
if key:
@@ -66,6 +73,10 @@ class EPGet(CollectorResource):
return
for param in req.params:
+ if param == 'limit':
+ limit = req.params['limit']
+ elif param == 'skip':
+ skip = req.params['skip']
for i in index.indexes:
for j in i['index']['fields']:
if j == param:
@@ -73,7 +84,7 @@ class EPGet(CollectorResource):
for org in orgs:
selectors['domain'] = org
- data = self._db.search(**selectors)
+ data = self._db.search(**selectors, limit=limit, skip=skip)
if data:
out += data
@@ -103,6 +114,7 @@ class EPAdd(CollectorResource):
# NOTE: Reading the whole body in one go instead of streaming
# it nicely.
rawin = req.bounded_stream.read()
+
try:
decodedin = rawin.decode('UTF-8')
except Exception:
@@ -134,25 +146,24 @@ class EPAdd(CollectorResource):
def main(port=8000, wsgi_helper=False):
db = DictDB(database, hostname, username, password)
users = authn.UserDB('wsgi_demo_users.yaml')
- resources_map = [
- ('/sc/v0/add', EPAdd(db, users)),
- ('/sc/v0/get', EPGet(db, users)),
- ('/sc/v0/get/{key}', EPGet(db, users))
- ]
- app = falcon.App(cors_enable=True)
- for url, res in resources_map:
- app.add_route(url, res)
+ app = falcon.App(cors_enable=True)
+ app.add_route('/sc/v0/add', EPAdd(db, users))
+ app.add_route('/sc/v0/get', EPGet(db, users))
+ app.add_route('/sc/v0/get/{key}', EPGet(db, users))
- if not wsgi_helper:
- print('Serving on port 8000...')
- httpd = make_server('', port, app)
- httpd.serve_forever()
+ if wsgi_helper:
+ return app
- return app
+ print('Serving on port 8000...')
+ httpd = make_server('', port, app)
+ httpd.serve_forever()
if __name__ == '__main__':
- sys.exit(main())
+ try:
+ sys.exit(main())
+ except KeyboardInterrupt:
+ print('\nBye!')
else:
app = main(port=8000, wsgi_helper=True)