简体   繁体   中英

How to reset custom request attribute on each request in Bottle?

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM