python bottle 簡介

   bottle 是一個輕量級的python web框架, 能夠適配各類 web服務器,包括python自帶的wsgiref(默認),gevent, cherrypy,gunicorn等等。bottle是單文件形式發佈,源碼在 這裏能夠下載,代碼量很少,能夠用來學習web框架。 這裏也有官方文檔的中文翻譯。
 
  首先咱們來運行一下bottle的hello world
from bottle import run
 
if __name__ == '__main__':
    def application(environ, start_response):
        start_response('200 OK', [('Content-Type', 'text/html')])
        return ['<h1>Hello world!</h1>']
 
    run(host='localhost', port=8080, app=application)
  上面的代碼看起來也很是符合wsgi的接口規範。啓動改代碼,能夠看到輸出
        Bottle v0.13-dev server starting up (using  WSGIRefServer())...
        Listening on http://localhost:8080/
        Hit Ctrl-C to quit.
  
  輸出中加粗部分代表使用的web服務器是 python自帶的wsgiref。也可使用其餘web server,好比gevent,前提是須要安裝gevent,修改後的代碼以下:
from bottle import run
import gevent.monkey
gevent.monkey.patch_all()
 
if __name__ == '__main__':
    def application(environ, start_response):
        start_response('200 OK', [('Content-Type', 'text/html')])
        return ['<h1>Hello world!</h1>']
 
    run(host='localhost', port=8080, app=application, server = 'gevent')

經過server關鍵字指定web服務器爲‘gevent’,輸出的第一行變成了:html

    Bottle v0.13-dev server starting up (using  GeventServer())...
 
無論bottle用什麼web服務器啓動,在瀏覽器輸入127.0.0.1:8080,均可以看到
    
 
 
 
下面介紹bottle中部分類和接口
bottle.Bottle
    表明一個獨立的wsgi應用,由一下部分組成:routes, callbacks, plugins, resources and configuration。
    __call__: Bottle定義了__call__函數, 使得Bottle的實例能成爲一個 callable。在 前文提到,web框架(或Application)須要提供一個callbale對象給web服務器,bottle提供的就是Bottle實例
    def __call__(self, environ, start_response):
      """ Each instance of :class:'Bottle' is a WSGI application. """
       return self.wsgi(environ, start_response)        
    下面是Bottle.wsgi函數的核心代碼,主要調用兩個比較重要的函數:_handle, _cast
    def wsgi(self, environ, start_response):
        """ The bottle WSGI-interface. """
        try:
            out = self._cast(self._handle(environ))
            # rfc2616 section 4.3
            if response._status_code in (100, 101, 204, 304)\
            or environ['REQUEST_METHOD'] == 'HEAD':
                if hasattr(out, 'close'): out.close()
                out = []
            start_response(response._status_line, response.headerlist)
            return out

  _handle:處理請求,最終調用到application ,簡化後的代碼以下:python

1   def _handle(self, environ):
2         self.trigger_hook('before_request')
3         route, args = self.router.match(environ)
4         out = route.call(**args)
5         self.trigger_hook('after_request')
6         return out
  
  _cast: 
       標準的wsgi接口對Application的返回值要求嚴格,必須迭代返回字符串。bottle作了一些擴展,能夠容許App返回更加豐富的類型,好比dict,File等。 _cast函數對_handle函數返回值進行處理,使之符合wsgi規範
 
bottle.Route
    封裝了路由規則與對應的回調
 
bottle.Router
    A Router is an ordered collection of route->target pairs. It is used to  efficiently match WSGI requests against a number of routes and return the first target that satisfies the request.
 
ServerAdapter
    全部bottle適配的web服務器的基類,子類只要實現run方法就能夠了,bottle裏面有大量的Web服務器的適配。下表來自官網,介紹了bottle支持的各類web服務器,以及各自的特性。
    
Name Homepage Description
cgi
 
Run as CGI script
flup flup Run as FastCGI process
gae gae Helper for Google App Engine deployments
wsgiref wsgiref Single-threaded default server
cherrypy cherrypy Multi-threaded and very stable
paste paste Multi-threaded, stable, tried and tested
rocket rocket Multi-threaded
waitress waitress Multi-threaded, poweres Pyramid
gunicorn gunicorn Pre-forked, partly written in C
eventlet eventlet Asynchronous framework with WSGI support.
gevent gevent Asynchronous (greenlets)
diesel diesel Asynchronous (greenlets)
fapws3 fapws3 Asynchronous (network side only), written in C
tornado tornado Asynchronous, powers some parts of Facebook
twisted twisted Asynchronous, well tested but... twisted
meinheld meinheld Asynchronous, partly written in C
bjoern bjoern Asynchronous, very fast and written in C
auto
 
Automatically selects an available server adapter

    能夠看到,bottle適配的web服務器很豐富。工做模式也很全面,有多線程的(如paste)、有多進程模式的(如gunicorn)、也有基於協程的(如gevent)。具體選擇哪一種web服務器取決於應用的特性,好比是CPU bound仍是IO bound
 
bottle.run
    啓動wsgi服務器。幾個比較重要的參數
    app: wsgi application,便可以是bottle.Bottle 也開始是任何知足wsgi 接口的函數
    server: wsgi http server,字符串
    host:port: 監聽端口
    
    核心邏輯:
    ServerAdapter.run(app)。
 
最後,bottle源碼中有一些使用descriptor的例子,實現很巧妙,值得一讀, 前文也有介紹。
 
references;
相關文章
相關標籤/搜索