Introduce a new decoratore wsme.protocol.expose, which replaces the clumsy former pexpose

This commit is contained in:
Christophe de Vienne 2012-10-31 11:44:30 +01:00
parent 4747aa82f1
commit 21b5ccc632
2 changed files with 46 additions and 0 deletions

View File

@ -11,6 +11,26 @@ __all__ = [
registered_protocols = {}
def _cfg(f):
cfg = getattr(f, '_cfg', None)
if cfg is None:
f._cfg = cfg = {}
return cfg
class expose(object):
def __init__(self, path, content_type):
self.path = path
self.content_type = content_type
def __call__(self, func):
func.exposed = True
cfg = _cfg(func)
cfg['content-type'] = self.content_type
cfg['path'] = self.path
return func
class CallContext(object):
def __init__(self, request):
self._request = weakref.ref(request)
@ -30,6 +50,12 @@ class Protocol(object):
dataformat = None
content_types = []
def iter_routes(self):
for attrname in dir(self):
attr = getattr(self, attrname)
if getattr(attr, 'exposed', False):
yield _cfg(attr)['path'], attr
def accept(self, request):
if request.path.endswith('.' + self.dataformat):
return True

View File

@ -199,10 +199,30 @@ class WSRoot(object):
request.server_errorcount += 1
return protocol.encode_error(context, infos)
def find_route(self, path):
for p in self.protocols:
for routepath, func in p.iter_routes():
if path.startswith(routepath):
return routepath, func
return None, None
def _handle_request(self, request):
res = webob.Response()
res_content_type = None
path = request.path
if path.startswith(self._webpath):
path = path[len(self._webpath):]
routepath, func = self.find_route(path)
if routepath:
content = func()
if isinstance(content, six.text_type):
res.text = content
elif isinstance(content, six.binary_type):
res.body = content
res.content_type = func._cfg['content-type']
return res
if request.path == self._webpath + '/api.spore':
res.body = spore.getdesc(self, request.host_url)
res.content_type = 'application/json'