Here's simplified version of my plugin:
class MyPlugin(object):
''' My plugin.
'''
api = 2
def __init__(self):
self.time = datetime.now()
def apply(self, callback, route):
request.my_attr = self.time
@wraps(callback)
def wrapper(*args, **kwargs):
cb_response = callback(*args, **kwargs)
return cb_response
# Forget any cached values.
route.reset()
# Replace the route callback with the wrapped one.
return wrapper
my_plugin = MyPlugin()
@route('/my_route', method=['GET', 'POST'], apply=[my_plugin])
def my_route():
""" Http Handler.
"""
response.content_type = 'text/txt;'
time = request.my_attr
print(time)
run(host=HOST, port=PORT, debug=DEBUG, quiet=QUIET)
It works with the first request, but fails with all subsequent requests:
# ./my_app.py
Bottle v0.12.9 server starting up (using WSGIRefServer())...
Listening on http://0.0.0.0:8888/
Hit Ctrl-C to quit.
2016-10-25 14:51:29.975600
46.101.xx.yy - - [25/Oct/2016 14:51:33] "POST /my_route HTTP/1.1" 200 1569
Traceback (most recent call last):
File "/usr/local/lib/python3.4/dist-packages/bottle.py", line 1391, in __getattr__
var = self.environ['bottle.request.ext.%s'%name]
KeyError: 'bottle.request.ext.my_attr'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/usr/local/lib/python3.4/dist-packages/bottle.py", line 862, in _handle
return route.call(**args)
File "/usr/local/lib/python3.4/dist-packages/bottle.py", line 1732, in wrapper
rv = callback(*a, **ka)
File "./my_app.py", line 245, in wrapper
cb_response = callback(*args, **kwargs)
File "./my_app.py", line 264, in my_route
time = request.my_attr
File "/usr/local/lib/python3.4/dist-packages/bottle.py", line 1394, in __getattr__
raise AttributeError('Attribute %r not defined.' % name)
AttributeError: Attribute 'my_attr' not defined.
46.101.xx.yy - - [25/Oct/2016 14:51:37] "POST /my_route HTTP/1.1" 500 760
How do I reset request.my_attr
on each request?
It's not clear what your end goal is, or what you mean precisely by "reset request.my_attr on each request" (since elsewhere you mention "cached values," which implies that you do intend to do some caching). But it does seem clear that this line
request.my_attr = self.time
is in the wrong place. You probably want to move that into your wrapper
function, because (presumably) then intention is for that line to run on each request:
@wraps(callback)
def wrapper(*args, **kwargs):
request.my_attr = self.time
cb_response = callback(*args, **kwargs)
return cb_response
I'm not sure that makes sense to me, but I don't know what your goal is so maybe it is indeed what you intend. In any case, moving the line into wrapper
corrects the HTTP 500. Hope that helps! If not, please add a line or two describing what you're trying to accomplish and I'll try to help.