1. 程式人生 > >使用 twisted 的 txrestapi 模組提供基本的非同步 API 服務。

使用 twisted 的 txrestapi 模組提供基本的非同步 API 服務。

twisted 是python的一個非同步網路框架,txrestapi 是基於 twisted 的一個 RESTFUL API 服務的包,使用 txrestapi 的程式碼基本如下:

from twisted.internet import reactor
from twisted.web import server
from txrestapi.resource import APIResource
from txrestapi.methods import GET, POST, PUT, ALL


class MyResource(APIResource):

    @GET("/path1")
    def path1(self, request):
        return "path1"

    @POST("/path2")
    def path2(self, request):
        return "path2"

    @ALL("/")
    def default(self, request):
        return "default route"


if __name__ == "__main__":
    site = server.Site(MyResource())
    reactor.listenTCP(8080, site)
    reactor.run()

當我們把程式執行起來後,可以在瀏覽器中訪問 http://127.0.0.1:8080/path1 得到 path1, 訪問其他可以得到 default route.

從程式碼來看,這個路由請求的回撥函式是比較快的執行結束了。但是存在一個問題,如果某一個路由請求需要執行一段時間後才能得到最終的結果,如何才能將正確的資料返回給請求者呢? 這裡就需要用到 twisted.web.server.NOT_DONE_YET 這個屬性。這樣把 NOT_DONE_YET 返回給 reactor 的時候,它不會立即構造 response 返回給請求者,一直會得到 request.finish() 的呼叫,或者超時!

因此,我們修改程式碼如下:

class MyResource(APIResource):
    def __init__(self):
        APIResource.__init__(self)
        pass

    @GET("/path1")
    def path1(self, request):
        def make_response(req):
            req.write("end path1 request")
            req.finish()
        d = Deferred()
        d.addCallback(make_response)
        reactor.callLater(5, d.callback, request)
        return server.NOT_DONE_YET

    @POST("/path2")
    def path2(self, request):
        return "path2"

    @ALL("/")
    def default(self, request):
        return "default route"

執行程式碼,在瀏覽器訪問 http://127.0.0.1:8080/path1, 每次都會延遲 5s, 在這 5s 內,繼續請求其他路徑,不會被阻塞,立刻得到響應!

如此,當路徑請求 path1 處於等待狀態的時候,reactor 會繼續接收其他的路徑請求!