Bottle源碼閱讀筆記(一):WSGI,bottlewsgi

來源:互聯網
上載者:User

Bottle源碼閱讀筆記(一):WSGI,bottlewsgi
前言

Bottle是一個Python Web架構。整個架構只有一個檔案,不到4k行的代碼,沒有Python標準庫以外的依賴,卻包含了路由、模板和外掛程式等Web架構常用功能。通過閱讀Bottle源碼來瞭解什麼是Web架構和Web架構是怎麼工作是再合適不過了。由於Bottle是一個支援WSGI的架構,在閱讀源碼之前,我們先來瞭解什麼是WSGI。

注意:文中使用的Bottle版本為0.12.13。

WSGI

一般的Web伺服器只能處理靜態頁面。如果涉及到動態內容,伺服器就需要與Java/Python/Ruby等伺服器語言進行互動,將內容交給它們處理。由於大多數的Web伺服器都是用C寫,它們不能直接執行伺服器語言,所以兩者之間需要一座橋(在實際應用中,通常會在Web伺服器和WSGI應用中間添加一個應用伺服器來支援WSGI)。而在Python中,WSGI就是這麼一座橋。WSGI的實現分兩個部分,一是伺服器,二是應用程式。下面來看一看它們各自是什麼樣子的,以及兩者之間是如何協作的。

 1 class Server: 2  3     def __init__(self, server_address): 4         self.server_address = server_address 5  6     def set_app(self, application): 7         self.app = application 8  9     def serve_forever(self):10         while True:11             # socket.accept()12             if request_comein():13                 self.handle_request()14 15     def handle_request(self):16         request_data = self.get_request()17         self.parse_request(request_data)18         environ = self.get_environ()19         result = self.application(environ, self.start_response)20         self.send_response(result)21 22     def start_response(self, status, headers, exc_info):23         pass24 25     def get_environ(self):26         pass27 28     def get_request(self):29         pass30 31     def parse_request(self, text):32         pass33 34     def send_response(self, message):35         pass36 37 38 def make_server(host, port, app, server=Server):39     server = server((host, port))40     server.set_app(app)41     return server42 43 def simple_app(environ, start_response):44     status = '200 OK'45     response_headers = [('Content-type', 'text/plain')]46     start_response(status, response_headers)47     return 'Hello World!'48 49 if __name__ == '__main__':50     server = make_server('localhost', 8080, simple_app)51     server.serve_forever()

限於篇幅,這個伺服器模型省略了很多細節,如果你想要一個簡單又能啟動並執行WSGI伺服器,可以參考這裡Let's Build A Web Server.Part 2.。

伺服器在接收到請求後,對請求報文的資訊進行解析,結果儲存在一個名為environ的字典中。隨後以environ與處理頭資訊的start_response函數作為參數,調用應用程式 application(environ, start_response) 。最後將應用的結果組成新的響應,發送回用戶端。

在應用程式方面,WSGI應用是一個可調用的對象。它可以是一個函數,方法,類,或者是一個帶有__call__方法的執行個體。上面的應用就是一個函數。

當各種伺服器和應用程式/架構都按照WSGI的標準進行開發時,我們可以根據需求自由地組合不同的伺服器和架構。

Bottle最簡應用

在簡單瞭解完WSGI後,我們回到Bottle,來觀察一個Bottle應用是什麼樣子的,如何運行,跟我們的模型有什麼區別。

1 from bottle import Bottle, run2 3 app = Bottle()4 5 @app.route('/hello')6 def hello():7     return 'Hello World!'8 9 run(app, host='localhost', port=8080, server='wsgiref')

現在運行這個程式,用瀏覽器訪問地址'localhost:8080/hello'就會看到'Hello World!'。

1. 與上面的應用不同,Bottle應用是一個執行個體。按照WSGI規定,Bottle對象要實現__call__方法:

1 def __call__(self, environ, start_response):2     ''' Each instance of :class:'Bottle' is a WSGI application. '''3     return self.wsgi(environ, start_response)

所以這個Bottle.wsgi方法就是伺服器調用Bottle應用的入口,同時也是我們閱讀源碼的入口。

2. @app.route()這個裝飾器將一個函數綁定到一個URL上。當我們訪問'localhost:8080/hello'時,hello函數就會被調用。

3. Bottle預設的伺服器是wsgiref(Python標準庫裡的一個WSGI簡單實現)。當然Bottle還為許多伺服器編寫了適配器(Adapter),只需要改變server的值,run()函數會根據伺服器的名字尋找相應的適配器。無需編寫額外的代碼。

run函數和適配器部分代碼:

 1 def run(app=None, server='wsgiref', host='127.0.0.1', port=8080, 2         interval=1, reloader=False, quiet=False, plugins=None, 3         debug=None, **kargs): 4     if server in server_names: 5         server = server_names.get(server) 6     if isinstance(server, basestring): 7         server = load(server) 8     if isinstance(server, type): 9         server = server(host=host, port=port, **kargs)10     if not isinstance(server, ServerAdapter):11         raise ValueError("Unknown or unsupported server: %r" % server)12     ...13     server.run(app)14 15 class MeinheldServer(ServerAdapter):16     def run(self, handler):17         from meinheld import server18         server.listen((self.host, self.port))19         server.run(handler)
最後

在本文中,我們簡單介紹了在WSGI標準下伺服器和應用如何進行互動。下一篇,我們繼續圍繞這個最簡應用,講講與@app.route()有關的路由功能。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.