aboutsummaryrefslogtreecommitdiff
path: root/pyaggr3g470r/views/api/common.py
diff options
context:
space:
mode:
Diffstat (limited to 'pyaggr3g470r/views/api/common.py')
-rw-r--r--pyaggr3g470r/views/api/common.py122
1 files changed, 102 insertions, 20 deletions
diff --git a/pyaggr3g470r/views/api/common.py b/pyaggr3g470r/views/api/common.py
index edf560da..c0759c03 100644
--- a/pyaggr3g470r/views/api/common.py
+++ b/pyaggr3g470r/views/api/common.py
@@ -1,6 +1,8 @@
+import json
+import types
from functools import wraps
-from flask import request, g, session, Response, jsonify
-from flask.ext.restful import Resource
+from flask import request, g, session, Response
+from flask.ext.restful import Resource, reqparse
from pyaggr3g470r.models import User
from pyaggr3g470r.lib.exceptions import PyAggError
@@ -35,42 +37,122 @@ def authenticate(func):
return wrapper
+def default_handler(obj):
+ """JSON handler for default query formatting"""
+ if hasattr(obj, 'isoformat'):
+ return obj.isoformat()
+ if hasattr(obj, 'dump'):
+ return obj.dump()
+ if isinstance(obj, (set, frozenset, types.GeneratorType)):
+ return list(obj)
+ raise TypeError("Object of type %s with value of %r "
+ "is not JSON serializable" % (type(obj), obj))
+
+
def to_response(func):
def wrapper(*args, **kwargs):
try:
- res = func(*args, **kwargs)
- except PyAggError, error:
- response = jsonify(**error.message)
+ result = func(*args, **kwargs)
+ except PyAggError as error:
+ response = Response(json.dumps(result[0], default=default_handler))
response.status_code = error.status_code
return response
- if isinstance(res, tuple):
- response = jsonify(**res[0])
- if len(res) > 1:
- response.status_code = res[1]
- return response
- return res
+ status_code = 200
+ if isinstance(result, tuple):
+ result, status_code = result
+ response = Response(json.dumps(result, default=default_handler),
+ status=status_code)
+ return response
return wrapper
-class PyAggResource(Resource):
+class PyAggAbstractResource(Resource):
method_decorators = [authenticate, to_response]
- controller_cls = None
- editable_attrs = []
def __init__(self, *args, **kwargs):
self.controller = self.controller_cls(g.user.id)
- super(PyAggResource, self).__init__(*args, **kwargs)
+ super(PyAggAbstractResource, self).__init__(*args, **kwargs)
+
+ def reqparse_args(self, strict=False, default=True):
+ """
+ strict: bool
+ if True will throw 400 error if args are defined and not in request
+ default: bool
+ if True, won't return defaults
+
+ """
+ parser = reqparse.RequestParser()
+ for attr_name, attrs in self.attrs.items():
+ if not default and attr_name not in request.args:
+ continue
+ parser.add_argument(attr_name, location='json', **attrs)
+ return parser.parse_args(strict=strict)
+
+
+class PyAggResourceNew(PyAggAbstractResource):
+
+ def post(self):
+ return self.controller.create(**self.reqparse_args()), 201
+
+
+class PyAggResourceExisting(PyAggAbstractResource):
def get(self, obj_id=None):
- return {'result': [self.controller.get(id=obj_id).dump()]}
+ return self.controller.get(id=obj_id).dump()
def put(self, obj_id=None):
- args = self.reqparse.parse_args()
+ args = self.reqparse_args()
new_values = {key: args[key] for key in
- set(args).intersection(self.editable_attrs)}
+ set(args).intersection(self.attrs)}
self.controller.update(obj_id, **new_values)
- return {"message": "ok"}
def delete(self, obj_id=None):
self.controller.delete(obj_id)
- return {"message": "ok"}, 204
+ return None, 204
+
+
+class PyAggResourceMulti(PyAggAbstractResource):
+
+ def get(self):
+ filters = self.reqparse_args(default=False)
+ return [res.dump() for res in self.controller.read(**filters).all()]
+
+ def post(self):
+ status = 201
+ results = []
+ args = [] # FIXME
+ for arg in args:
+ try:
+ results.append(self.controller.create(**arg).id)
+ except Exception as error:
+ status = 206
+ results.append(error)
+ return results, status
+
+ def put(self):
+ status = 200
+ results = []
+ args = {} # FIXME
+ for obj_id, attrs in args.items():
+ try:
+ new_values = {key: args[key] for key in
+ set(attrs).intersection(self.editable_attrs)}
+ self.controller.update(obj_id, **new_values)
+ results.append('ok')
+ except Exception as error:
+ status = 206
+ results.append(error)
+ return results, status
+
+ def delete(self):
+ status = 204
+ results = []
+ obj_ids = [] # FIXME extract some real ids
+ for obj_id in obj_ids:
+ try:
+ self.controller.delete(obj_id)
+ results.append('ok')
+ except Exception as error:
+ status = 206
+ results.append(error)
+ return results, status
bgstack15