1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
|
import web
class inputmethod(object):
"""
A descriptor passing web.input() as first argument to the
inner function.
"""
def __init__(self, func):
self._func = func
def __get__(self, obj, objcls):
return self._func.__get__(web.input())
def identity(func):
"A do nothing decorator"
return func
class Register(object):
"""
Each instance is a decorator associated to a web.py application.
Each application adds a RESTful resource.
"""
def __init__(self, dec=identity):
self.dec = dec
self.app = web.application([]) # self.app.mapping is the empty list
self.mapping = {}
def __call__(self, path):
def dec(func):
chunks = func.__name__.split('_')
name = '_'.join(chunks[:-1])
meth = chunks[-1]
assert meth in ('GET', 'POST', 'PUT', 'DELETE'), meth
func = self.dec(func) # decorate the original function
self._addcls(path, name, meth, inputmethod(func))
return func
return dec
def _addcls(self, path, name, method, meth):
if path not in self.mapping:
cls = type(name, (), dict(path=path))
self.mapping[path] = cls
self.app.mapping.extend([path, cls])
else:
cls = self.mapping[path]
setattr(cls, method, meth)
if __name__ == '__main__':
resource = Register()
@resource('/b')
def book_GET():
pass
@resource('/c')
def book_POST():
pass
@resource('/d')
def book_PUT():
pass
@resource('/e')
def book_DELETE():
pass
print resource.app.mapping, resource.mapping
|