Twisted開發Web應用筆記

來源:互聯網
上載者:User

(最近忙,發點舊文湊數-_-|||,這是三月份試用Twisted時記的一點筆記)

Twisted是一個功能極為強大的非同步網路應用開發庫——當然是Python的。印象中大概也就只有ACE有這麼強悍,但Twisted在易用性方面要好很多——這其中當然少不了Python的功勞(ACE是用C++的)。

但Python也有其缺點,其中之一就是因為GIL的存在使得用Python寫多線程應用的意義不大,那麼對於像Twisted這樣基於Reactor模式實現的單一Event Loop的應用開發環境來說,就有一點局限:整個應用(或者說整個進程)都必須圍繞著reactor來。這樣的話做一些純後端的應用是沒什麼問題,比如像網頁爬蟲(Scrapy就是基於Twsited的)一類的應用。但這顯然不夠,很多應用還是需要有前端介面的——比如像BT、電驢這樣的下載工具。MLDonkey採用的方法就是提供一個WEB的管理介面來與使用者互動——當然,MLDonkey並不是用Python開發的。

這是一個很好的思路。所以Twisted提供了一套WEB開發環境以實現這樣的目的。

關於twisted.web部分的開發,官方的文檔

顯得太過於簡單了,特別是連基本的request對象的參考文檔都沒有。還好gashero整理了一部分在《Twisted的WEB開發

》,引用一下(有補充):

channel :包含上級的HTTP協議對象。

transport :通訊對象。

method :HTTP方法,如GET和POST。

uri :全部請求的URI。

path :具體的請求路徑,不含參數。

args :請求參數,包括URL參數和POST參數。格式如 {’key’:[’val1′,’val2′],} 。

received_headers :請求報文的頭欄位。

received_cookies :請求報文的cookie。

content :請求報文的實體主體,檔案對象。

clientproto :發出請求的用戶端的HTTP版本。

client :請求的用戶端地址對象,包括type、host和port屬性,分別記錄協議(這裡固定為TCP)、IP和連接埠號碼

host :本機接收請求的地址對象

getHeader(key) :擷取請求的頭欄位。

getCookie(key) :擷取請求的cookie。

getAllHeaders() :所有請求的頭欄位字典,就是返回received_headers。

getRequestHostname() :請求的host欄位,不含連接埠號碼。

getHost() :原始請求的通訊地址,返回host。

getClientIP() :擷取用戶端IP。

getUser() :擷取basic驗證中的使用者名稱。

getPassword() :擷取basic驗證中的密碼。

getClient() :擷取用戶端地址對象

一個最基本的Web應用如下:

from twisted.web import server, resource<br />from twisted.internet import reactor<br />class Simple(resource.Resource):<br /> isLeaf=True<br /> def render_GET(self, request):<br /> return "Hello, world!"<br />reactor.listenTCP(8080, server.Site(Simple()))<br />reactor.run()

然後運行起來就可以通過URL:http://localhost:8080 訪問這個程式的頁面了。

注意其中的的isLeaf是必須的。不過也還有另一種方法可以實現同樣的功能:

from twisted.web import server, resource<br />from twisted.internet import reactor<br />class Simple(resource.Resource):<br /> def __init__(self):<br /> resource.Resource.__init__(self)<br /> self.putChild("", self)<br /> def render_GET(self, request):<br /> return "Hello, world!"<br />reactor.listenTCP(8080, server.Site(Simple()))<br />reactor.run()

這個方法好理解,就是把這個對象掛到請求連結的根目錄上。以此類推就可以實現帶子目錄請求的頁面:

from twisted.web import server, resource<br />from twisted.internet import reactor<br />class ChildSimple(resource.Resource):<br /> isLeaf=True<br /> def render_GET(self, request):<br /> return "Hello, child!"<br />class Simple(resource.Resource):<br /> def __init__(self):<br /> resource.Resource.__init__(self)<br /> self.putChild("", self)<br /> self.putChild("child", ChildSimple())<br /> def render_GET(self, request):<br /> return "Hello, world!"<br />reactor.listenTCP(8080, server.Site(Simple()))<br />reactor.run()

現在可以通過URL:http://localhost:8080/child 訪問這個子頁面了。不過產生子頁面還有一個動態辦法:

from twisted.web import server, resource<br />from twisted.internet import reactor<br />class ChildSimple(resource.Resource):<br /> isLeaf=True<br /> def __init__(self, id):<br /> resource.Resource.__init__(self)<br /> self.id=id<br /> def render_GET(self, request):<br /> return "Hello, No. %s visitor!" % self.id<br />class Simple(resource.Resource):<br /> def __init__(self):<br /> resource.Resource.__init__(self)<br /> self.putChild("", self)<br /> def render_GET(self, request):<br /> return "Hello, world!"<br /> def getChild(self, path, request):<br /> return ChildSimple(path)<br />reactor.listenTCP(8080, server.Site(Simple()))<br />reactor.run()

現在可以試試URL:http://localhost:8080/1234 訪問了。其中1234可以換成任何數字(實際上上面的程式對此未作限制,即使輸入任何字元也是可以的)。

接下來是靜態內容的使用:

from twisted.web import server, resource, static<br />from twisted.internet import reactor<br />class Simple(resource.Resource):<br /> def __init__(self):<br /> resource.Resource.__init__(self)<br /> self.putChild("", self)<br /> self.putChild("static", static.File("/var/www/htdocs"))<br /> def render_GET(self, request):<br /> return "Hello, world!"<br />reactor.listenTCP(8080, server.Site(Simple()))<br />reactor.run()

訪問一下URL:http://localhost:8080/static 試試就知道了。

這些對於Web開發都是些基本的功能,稍微複雜一點的網頁要做起來還是很痛苦的。但是Python是很靈活的東西,資源也很豐富,所以實際上問題也不大。比如在getChild方法裡加上routing的實現,再加一個mako一類的模板,功能立即強大很多(貌似搞得像Pylons了)——只是資料庫操作還是需要謹慎一些,簡單地加上SQLAlchemy之類的ORM也不是不行,但是它對資料庫的訪問是阻塞式的,可能導致Twisted應用的效能下降很大。

所幸的是一般來說為Twisted應用增加Web互動介面很少還有需要操作資料庫的,即使必須要有,Twisted也提供了非同步資料庫提供者——雖然功能不可能像SQLAlchemy那麼強大,對於簡單的應用應該也足夠了。

雖然WEB介面已經很方便了,但也許還會有人想要用互動式GUI,這也沒問題。Twisted的Web庫提供了對XMLRPC和SOAP的支援。以簡單一些的XMLRPC為例:

from twisted.web import server, resource, xmlrpc<br />from twisted.internet import reactor<br />class XREcho(xmlrpc.XMLRPC):<br /> def xmlrpc_echo(self, bar):<br /> return bar<br />reactor.listenTCP(8080, server.Site(XREcho()))<br />reactor.run()

用戶端的調用方式是:

import xmlrpclib<br />s = xmlrpclib.Server("http://localhost:8080/")<br />s.echo("Hello!")

上面的代碼執行後將回顯。

實際上XMLRPC對象也是一種Resource,所以也可以簡單地用putChild放到子目錄下去。或者如果需要對xmlrpc的request進行控制——比如增加authentication或者其它的用戶端調用限制,可以在_cbRender方法裡實現,具體可參考web.xmlrpc的源碼。

關於用Twisted進行Web開發的更多內容請參考官方文檔和源碼。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.