2014-02-13 50 views
4

我有以下的Web應用程序:訪問在bottlepy響應對象after_request鉤

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裝飾函數接受輸入響應對象,因此很容易訪問它。我如何在Bottle中做同樣的事情?

有什麼我失蹤了嗎?

回答

4

有沒有辦法在發回響應之前訪問響應主體?

你可以寫一個簡單的插件,這取決於你實際嘗試做什麼與響應可能是你所需要的。

下面是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) 

希望能爲你的目的工作。

+0

插件不能要求不匹配任何路由請求。所以這使得它們不適合創建實例的訪問日誌。 –

1

您可以使用插件的方式,這是我做的

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