Use Cornice for REST API viws
still very experimental at this point
This commit is contained in:
parent
31ae5eacd5
commit
ad35481234
|
@ -28,9 +28,12 @@ from __future__ import unicode_literals, absolute_import
|
|||
|
||||
from rattail.db import model
|
||||
|
||||
from cornice.resource import resource
|
||||
|
||||
from tailbone.api import APIMasterView
|
||||
|
||||
|
||||
@resource(collection_path='/api/customers', path='/api/customer/{uuid}')
|
||||
class CustomerView(APIMasterView):
|
||||
|
||||
model_class = model.Customer
|
||||
|
@ -43,4 +46,4 @@ class CustomerView(APIMasterView):
|
|||
|
||||
|
||||
def includeme(config):
|
||||
CustomerView.defaults(config)
|
||||
config.scan(__name__)
|
||||
|
|
|
@ -33,6 +33,15 @@ from tailbone.db import Session
|
|||
|
||||
|
||||
class APIMasterView(APIView):
|
||||
"""
|
||||
Base class for data model REST API views.
|
||||
"""
|
||||
allow_get = True
|
||||
allow_collection_get = True
|
||||
|
||||
@property
|
||||
def Session(self):
|
||||
return Session
|
||||
|
||||
@classmethod
|
||||
def get_model_class(cls):
|
||||
|
@ -41,48 +50,34 @@ class APIMasterView(APIView):
|
|||
raise NotImplementedError("must set `model_class` for {}".format(cls.__name__))
|
||||
|
||||
@classmethod
|
||||
def get_model_key(cls):
|
||||
if hasattr(cls, 'model_key'):
|
||||
return cls.model_name
|
||||
def get_normalized_model_name(cls):
|
||||
if hasattr(cls, 'normalized_model_name'):
|
||||
return cls.normalized_model_name
|
||||
return cls.get_model_class().__name__.lower()
|
||||
|
||||
@classmethod
|
||||
def get_model_key_plural(cls):
|
||||
if hasattr(cls, 'model_key_plural'):
|
||||
return cls.model_key_plural
|
||||
return '{}s'.format(cls.get_model_key())
|
||||
def get_object_key(cls):
|
||||
if hasattr(cls, 'object_key'):
|
||||
return cls.object_key
|
||||
return cls.get_normalized_model_name()
|
||||
# raise NotImplementedError("must set `object_key` for {}".format(cls.__name__))
|
||||
|
||||
@classmethod
|
||||
def get_route_prefix(cls):
|
||||
if hasattr(cls, 'route_prefix'):
|
||||
return cls.route_prefix
|
||||
return 'api.{}'.format(cls.get_model_key_plural())
|
||||
def get_collection_key(cls):
|
||||
if hasattr(cls, 'collection_key'):
|
||||
return cls.collection_key
|
||||
return '{}s'.format(cls.get_object_key())
|
||||
# raise NotImplementedError("must set `collection_key` for {}".format(cls.__name__))
|
||||
|
||||
@classmethod
|
||||
def get_permission_prefix(cls):
|
||||
if hasattr(cls, 'permission_prefix'):
|
||||
return cls.permission_prefix
|
||||
return cls.get_model_key_plural()
|
||||
|
||||
@classmethod
|
||||
def get_url_prefix(cls):
|
||||
if hasattr(cls, 'url_prefix'):
|
||||
return cls.url_prefix
|
||||
return '/api/{}'.format(cls.get_model_key_plural())
|
||||
|
||||
@property
|
||||
def Session(self):
|
||||
return Session
|
||||
|
||||
@api
|
||||
def index(self):
|
||||
objects = self.Session.query(self.model_class)
|
||||
def collection_get(self):
|
||||
cls = self.get_model_class()
|
||||
objects = self.Session.query(cls)
|
||||
|
||||
sort = self.request.params.get('sort')
|
||||
if sort:
|
||||
# TODO: this is fragile, but what to do if bad params?
|
||||
sortkey, sortdir = sort.split('|')
|
||||
sortkey = getattr(self.model_class, sortkey)
|
||||
sortkey = getattr(cls, sortkey)
|
||||
objects = objects.order_by(getattr(sortkey, sortdir)())
|
||||
|
||||
# NOTE: we only page results if sorting is in effect, otherwise
|
||||
|
@ -94,19 +89,12 @@ class APIMasterView(APIView):
|
|||
per_page = int(per_page)
|
||||
objects = SqlalchemyOrmPage(objects, items_per_page=per_page, page=page)
|
||||
|
||||
data = [self.normalize(obj) for obj in objects]
|
||||
return data
|
||||
objects = [self.normalize(obj) for obj in objects]
|
||||
return {self.get_collection_key(): objects}
|
||||
|
||||
def normalize(self, obj):
|
||||
raise NotImplementedError("must implement `normalize()` method for: {}".format(self.__class__.__name__))
|
||||
|
||||
@classmethod
|
||||
def defaults(cls, config):
|
||||
route_prefix = cls.get_route_prefix()
|
||||
url_prefix = cls.get_url_prefix()
|
||||
permission_prefix = cls.get_permission_prefix()
|
||||
|
||||
# index
|
||||
config.add_route(route_prefix, '{}/'.format(url_prefix), request_method='GET')
|
||||
config.add_view(cls, attr='index', route_name=route_prefix,
|
||||
renderer='json', permission='{}.list'.format(permission_prefix))
|
||||
def get(self):
|
||||
uuid = self.request.matchdict['uuid']
|
||||
obj = self.Session.query(self.get_model_class()).get(uuid)
|
||||
if not obj:
|
||||
raise self.notfound()
|
||||
return {self.get_object_key(): self.normalize(obj)}
|
||||
|
|
|
@ -30,11 +30,16 @@ import six
|
|||
|
||||
from rattail.db import model
|
||||
|
||||
from cornice.resource import resource
|
||||
|
||||
from tailbone.api import APIMasterView
|
||||
|
||||
|
||||
class UpgradeView(APIMasterView):
|
||||
|
||||
@resource(collection_path='/api/upgrades', path='/api/upgrades/{uuid}')
|
||||
class UpgradeAPIView(APIMasterView):
|
||||
"""
|
||||
REST API views for Upgrade model.
|
||||
"""
|
||||
model_class = model.Upgrade
|
||||
|
||||
def normalize(self, upgrade):
|
||||
|
@ -54,4 +59,4 @@ class UpgradeView(APIMasterView):
|
|||
|
||||
|
||||
def includeme(config):
|
||||
UpgradeView.defaults(config)
|
||||
config.scan(__name__)
|
||||
|
|
|
@ -30,9 +30,12 @@ import six
|
|||
|
||||
from rattail.db import model
|
||||
|
||||
from cornice.resource import resource
|
||||
|
||||
from tailbone.api import APIMasterView
|
||||
|
||||
|
||||
@resource(collection_path='/api/users', path='/api/users/{uuid}')
|
||||
class UserView(APIMasterView):
|
||||
|
||||
model_class = model.User
|
||||
|
@ -45,4 +48,4 @@ class UserView(APIMasterView):
|
|||
|
||||
|
||||
def includeme(config):
|
||||
UserView.defaults(config)
|
||||
config.scan(__name__)
|
||||
|
|
|
@ -46,7 +46,7 @@ class View(object):
|
|||
Base class for all class-based views.
|
||||
"""
|
||||
|
||||
def __init__(self, request):
|
||||
def __init__(self, request, context=None):
|
||||
self.request = request
|
||||
|
||||
# if user becomes inactive while logged in, log them out
|
||||
|
|
Loading…
Reference in a new issue