python模塊介紹-Tornado:Tornado中文文檔-概述

快速連接

快速入門

import tornado.ioloop
import tornado.web

class MainHandler(tornado.web.RequestHandler):
    def get(self):
        self.write("Hello, world\n")

application = tornado.web.Application([(r"/", MainHandler),])

if __name__ == "__main__":
    application.listen(8888)
    tornado.ioloop.IOLoop.instance().start()

用瀏覽器或者curl等訪問http://localhost:8888/,會返回"Hello, world"。瀏覽器

# 服務器端執行
$ python test.py 
WARNING:tornado.access:404 GET /favicon.ico (127.0.0.1) 0.81ms
WARNING:tornado.access:404 GET /favicon.ico (127.0.0.1) 0.81ms
# 客戶端執行
$ curl  
Hello, world

這個例子沒有用到Tornado的異步功能,異步的實例參見chatdemo.py服務器

Introduction-to-Tornado中介紹的實例稍微複雜點:網絡

import tornado.httpserver
import tornado.ioloop
import tornado.options
import tornado.web
from tornado.options import define, options
define("port", default=8888, help="run on the given port", type=int)
class IndexHandler(tornado.web.RequestHandler):
    def get(self):
        greeting = self.get_argument('greeting', 'Hello')
        self.write(greeting + ', friendly user!')
if __name__ == "__main__":
    tornado.options.parse_command_line()
    app = tornado.web.Application(handlers=[(r"/", IndexHandler)])
    http_server = tornado.httpserver.HTTPServer(app)
    http_server.listen(options.port)
    tornado.ioloop.IOLoop.instance().start()

執行結果:

# 服務器端執行
$ python hello.py --port=8000
[I 150525 08:41:53 web:1825] 200 GET / (127.0.0.1) 0.85ms
[I 150525 08:42:26 web:1825] 200 GET /?greeting=Salutations (127.0.0.1) 0.68ms
# 客戶端執行
$ curl http://localhost:8000/
Hello, friendly user!
$ curl http://localhost:8000/?greeting=Salutations
Salutations, friendly user!

這裏增長了tornado.options.parse_command_line()用於解析http參數。上例中用application.listen(8888)直接啓動http服務,這裏改成用tornado.httpserver.HTTPServer啓動。

Introduction-to-Tornado中字符串實例以下:

import textwrap

import tornado.httpserver
import tornado.ioloop
import tornado.options
import tornado.web
            
from tornado.options import define, options
define("port", default=8888, help="run on the given port", type=int)

    class ReverseHandler(tornado.web.RequestHandler):
    def get(self, input):
        self.write(input[::-1] + '\n')class WrapHandler(tornado.web.RequestHandler):
    def post(self):
        text = self.get_argument('text')
        width = self.get_argument('width', 40)
        self.write(textwrap.fill(text, int(width)) + '\n')

if __name__ == "__main__":
    tornado.options.parse_command_line()
    app = tornado.web.Application(handlers=[
        (r"/reverse/(\w+)", ReverseHandler),
        (r"/wrap", WrapHandler)
    ])
    http_server = tornado.httpserver.HTTPServer(app)
    http_server.listen(options.port)
    tornado.ioloop.IOLoop.instance().start()

執行結果:

# 服務器端執行
$ python string_service.py --port=8000
[I 150525 09:01:18 web:1825] 200 GET /reverse/stressed (127.0.0.1) 0.56ms
[I 150525 09:01:24 web:1825] 200 GET /reverse/slipup (127.0.0.1) 0.65ms
[I 150525 09:01:59 web:1825] 200 POST /wrap (127.0.0.1) 1.89ms
[I 150525 09:02:14 web:1825] 200 POST /wrap (127.0.0.1) 0.97ms

# 客戶端執行
$ curl http://localhost:8000/reverse/stressed
desserts
$ curl http://localhost:8000/reverse/slipup
pupils
$ curl http://localhost:8000/wrap -d text=Lorem+ipsum+dolor+sit+amet,+consectetuer+adipiscing+elit.Lorem ipsum dolor sit amet, consectetuer
adipiscing elit.
$ curl http://localhost:8000/wrap -d text=hello
hello

在上面的代碼中,Application類在"handlers"參數中實例化了兩個RequestHandler類對象。

"/reverse/(\w+)"中,正則表達式告訴Tornado匹配任何以字符串/reverse/開始並緊跟着一個或多個字母的路徑。括號的含義是 讓Tornado保存匹配括號裏面表達式的字符串,並將其做爲請求方法的一個參數傳遞給RequestHandler類。「get(self, input):」中有一個額外的參數input。這個參數將包含匹配處理函數正則表達式第一個括號裏的字符串, 若是正則表達式中有一系列額外的括號,匹配的字符串將被按照在正則表達式中出現的順序做爲額外的參數傳遞進來。

WrapHandler類處理匹配路徑爲/wrap的請求。這個處理函數定義了一個post方法,也就是說它接收HTTP的POST方法的請求。Tornado能夠解析URLencoded和multipart結構的POST請求。

常見的讀寫數據庫能夠結合post和get實現,好比(非實際可執行的例子):

# matched with (r"/widget/(\d+)", WidgetHandler)class WidgetHandler(tornado.web.RequestHandler):
    def get(self, widget_id):
        widget = retrieve_from_db(widget_id)
        self.write(widget.serialize())

    def post(self, widget_id):
        widget = retrieve_from_db(widget_id)
        widget['foo'] = self.get_argument('foo')
        save_to_db(widget)

HTTP請求(GET、POST、PUT、DELETE、HEAD、OPTIONS)能夠很是容易地定義,只須要在RequestHandler類中使用 同名的方法。下面是另外一個想象的例子,在這個例子中針對特定frob ID的HEAD請求只根據frob是否存在給出信息,而GET方法返回整個對象:

# matched with (r"/frob/(\d+)", FrobHandler)class FrobHandler(tornado.web.RequestHandler):
    def head(self, frob_id):
        frob = retrieve_from_db(frob_id)
        if frob is not None:
            self.set_status(200)
        else:
            self.set_status(404)

    def get(self, frob_id):
        frob = retrieve_from_db(frob_id)
        self.write(frob.serialize())

使用RequestHandler類的set_status()方法顯式地設置HTTP狀態碼。然而,你須要記住在某些狀況下,Tornado會自動地設置HTTP狀態碼。下面是一個經常使用狀況的綱要:

  • 404 Not Found: Tornado會在HTTP請求的路徑沒法匹配任何RequestHandler類相對應的模式時返回404(Not Found)響應碼。

  • 400 Bad Request: 若是你調用了一個沒有默認值的get_argument函數,而且沒有發現給定名稱的參數,Tornado將自動返回一個400(Bad Request)響應碼

  • 405 Method Not Allowed: 若是傳入的請求使用了RequestHandler中沒有定義的HTTP方法(好比,一個POST請求,可是處理函數中只有定義了get方 法),Tornado將返回一個405(Methos Not Allowed)響應碼。

  • 500 Internal Server Error: 當程序遇到任何不能讓其退出的錯誤時,Tornado將返回500(Internal Server Error)響應碼。你代碼中任何沒有捕獲的異常也會致使500響應碼。

  • 200 OK: 若是響應成功,而且沒有其餘返回碼被設置,Tornado將默認返回一個200(OK)響應碼。

錯誤發生時Tornado將默認向客戶端發送一個包含狀態碼和錯誤信息的簡短片斷。 能夠在你的RequestHandler重載write_error方法自定義錯誤信息,好比:

import tornado.httpserver
import tornado.ioloop
import tornado.options
import tornado.web

from tornado.options import define, options
define("port", default=8888, help="run on the given port", type=int)

class IndexHandler(tornado.web.RequestHandler):
    def get(self):
        greeting = self.get_argument('greeting', 'Hello')
        self.write(greeting + ', friendly user!')
        
    def write_error(self, status_code, **kwargs):
        self.write("Gosh darnit, user! You caused a {0} error.\n".format(
            status_code))

if __name__ == "__main__":
    tornado.options.parse_command_line()
    app = tornado.web.Application(handlers=[(r"/", IndexHandler)])
    http_server = tornado.httpserver.HTTPServer(app)
    http_server.listen(options.port)
    tornado.ioloop.IOLoop.instance().start()

執行結果:

# 服務器端執行
$ python hello-error.py --port=8000
[W 150525 09:58:29 web:1825] 405 POST / (127.0.0.1) 1.39ms

# 客戶端執行
$ curl -d foo=bar http://localhost:8000/
Gosh darnit, user! You caused a 405 error.

安裝

自動安裝:

# pip install tornado

PyPI中包含Tornado,能夠經過pip或easy_install來安裝。這種方式沒有包含源代碼中的demo程序,下載的源碼包能夠解決該問題。

手動安裝:

# wget https://pypi.python.org/packages/source/t/tornado/tornado-4.1.tar.gz
# tar xvzf tornado-4.1.tar.gz
# cd tornado-4.1
# python setup.py build
# sudo python setup.py install

預置條件:Tornado支持Python2.六、2.七、3.二、3.3和3.4。依賴certifi,Python 2還依賴backports.ssl_match_hostname,pip或easy_install自動安裝依賴。有些Tornado特性可能依賴如下庫:

  • unittest2: 在Python2.6執行test suite須要。

  • concurrent.futures: Tornado推薦的線程池,容許使用ThreadedResolver。Python 2須要,Python3中標準庫已經包含該功能。

  • pycurl:tornado.curl_httpclient中選擇是否使用。要求用7.18.2或更高版本,建議7.21.1或更高版本。

  • twisted: tornado.platform.twisted類可能用到。

  • pycares: 當線程是不適合時用做非阻塞DNS解析器。

  • Monotime: 增長單調時鐘,在時鐘調整頻繁環境中提升可靠性。在Python 3.3再也不須要。

平臺:Tornado運行在類unix平臺,最佳的性能和擴展性體如今Linux(epoll)和BSD(kqueue)(儘管Mac OS X上源於BSD且支持的kqueue,它的網絡性能較差,所以只建議用於開發)。Tornado也可在Windows上運行,但不是官方支持和建議僅供開 發使用。

受權:Tornado是Facebook開源的一部分,基於Apache License 2.0。文檔基於Creative Commons 3.0。


參考資料

相關文章
相關標籤/搜索