Access the response object in a bottlepy after_request hook

只谈情不闲聊 提交于 2019-12-30 20:38:57

问题


I have the following web app:

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')

Is there a way to access the response body before sending the response back?

If I start the app and I query /ping, I can see in the console that the ping() and the after() function run in the right sequence

$ 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

but when in after() I try to access response.body, I don't have anything.

In Flask the after_request decorated functions take in input the response object so it's easy to access it. How can I do the same in Bottle?

Is there something I'm missing?


回答1:


Is there a way to access the response body before sending the response back?

You could write a simple plugin, which (depending on what you're actually trying to do with the response) might be all you need.

Here's an example from the Bottle plugin docs, which sets a request header. It could just as easily manipulate 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)

Hope that works for your purposes.




回答2:


You can use plugin approach, this is what i did

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


来源:https://stackoverflow.com/questions/21767029/access-the-response-object-in-a-bottlepy-after-request-hook

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!