Introduce a new decoratore wsme.protocol.expose, which replaces the clumsy former pexpose
This commit is contained in:
parent
4747aa82f1
commit
21b5ccc632
@ -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
|
||||
|
20
wsme/root.py
20
wsme/root.py
@ -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'
|
||||
|
Loading…
x
Reference in New Issue
Block a user