在bottlepy after_request挂钩中访问响应对象

时间:2014-02-13 22:35:07

标签: python bottle

我有以下网络应用程序:

import bottle
app = bottle.Bottle()

@app.route('/ping')
def ping():
    print 'pong'
    return 'pong'

@app.hook('after_request')
def after():
    print 'foo'
    print bottle.response.body

if __name__ == "__main__":
    app.run(host='0.0.0.0', port='9999', server='cherrypy')

在发送回复之前有没有办法访问响应正文?

如果我启动应用并查询/ping,我可以在控制台中看到ping()after()功能以正确的顺序运行

$ python bottle_after_request.py 
Bottle v0.11.6 server starting up (using CherryPyServer())...
Listening on http://0.0.0.0:9999/
Hit Ctrl-C to quit.

pong
foo

但是当我在after()时尝试访问response.body时,我什么都没有。

在Flask中,after_request修饰函数接收输入响应对象,因此很容易访问它。我怎样才能在瓶子里做同样的事情?

我有什么遗失的吗?

2 个答案:

答案 0 :(得分:5)

  

在发送回复之前有没有办法访问响应正文?

您可以编写一个简单的插件,这可能就是您所需要的(取决于您实际尝试使用的响应)。

以下是来自Bottle plugin docs的示例,它设置了请求标头。它可以轻松操纵body

from bottle import response, install
import time

def stopwatch(callback):
    def wrapper(*args, **kwargs):
        start = time.time()
        body = callback(*args, **kwargs)
        end = time.time()
        response.headers['X-Exec-Time'] = str(end - start)
        return body
    return wrapper

install(stopwatch)

希望这适用于您的目的。

答案 1 :(得分:2)

你可以使用插件方法,这就是我所做的

from bottle import response


class BottlePlugin(object):

    name = 'my_custom_plugin'
    api = 2

    def __init__(self, debug=False):
        self.debug = debug
        self.app = None

    def setup(self, app):
        """Handle plugin install"""
        self.app = app

    def apply(self, callback):
        """Handle route callbacks"""
        def wrapper(*a, **ka):
            """Encapsulate the result in the expected api structure"""
            # Check if the client wants a different format

            # output depends what you are returning from view
            # in my case its dict with keys ("data")
            output = callback(*a, **ka)
            data = output["data"]
            paging = output.get("paging", {})

            response_data = {
                data: data,
                paging: paging
            }
            # in case if you want to update response
            # e.g response code
            response.status = 200

            return response_data

        return wrapper