如何在Twisted Web服务器中定义具有多个段的路径

时间:2018-07-26 11:38:59

标签: python twisted twisted.web

在类似于this example代码的Twisted网络服务器中

from twisted.web.server import Site
from twisted.web.resource import Resource
from twisted.internet import reactor, endpoints
from twisted.web.static import File

root = Resource()
root.putChild(b"foo", File("/tmp"))
root.putChild(b"bar", File("/lost+found"))
root.putChild(b"baz", File("/opt"))

factory = Site(root)
endpoint = endpoints.TCP4ServerEndpoint(reactor, 8880)
endpoint.listen(factory)
reactor.run()

如何为多段路径定义响应,以代替上面的示例,其中

http://example.com/foo 

您希望某个资源可用,例如

http://example.com/europe/france/paris

并且,如果它影响答案,则以下URL不会提供响应

http://example.com/europe/france
http://example.com/europe
http://example.com

我知道doco指的是使用资源树,但是only examples given是单级树,对于我的需求来说不太有用。


解决方案

在@ jean-paul-calderone的帮助下,我编写了以下内容来满足我的要求。

对于这个问题,我已经稍微简化了需求,实际上我想输出文件以外的内容,下面包含的代码反映了这一点。我很确定我在这里写的不是最好的方法,但是它确实提供了我想要的多段网址,因此对于其他有类似需求的人可能很有用。

from twisted.web.server import Site
from twisted.web.resource import Resource
from twisted.internet import reactor, endpoints
from twisted.web.resource import NoResource

import html

class ContinentLevelResource(Resource):
    pass

class CountryLevelResource(Resource):
    pass

class CityLevelResource(Resource):
    def render_GET(self, request):
        return (b"<!DOCTYPE html><html><head><meta charset='utf-8'>"
                b"<title>City Page</title></head><body>"
                b"<p>This is the City page</p></body>")

root = Resource()
continent = ContinentLevelResource()
country = CountryLevelResource()
city = CityLevelResource()
#    
root.putChild(b"europe", continent)
continent.putChild(b"france", country)
country.putChild(b"paris", city)
#
factory = Site(root)
endpoint = endpoints.TCP4ServerEndpoint(reactor, 8880)
endpoint.listen(factory)
reactor.run()

1 个答案:

答案 0 :(得分:1)

您只需应用与问题中相同的API用法即可-递归:

给出:

root = Resource()
tmp = File("/tmp")
root.putChild(b"foo", tmp)
lost_found = File("/lost+found")
root.putChild(b"bar", lost_found)
opt = File("/opt")
root.putChild(b"baz", opt)

您有/foo/bar/baz. If you want some_resource at / foo / quux`,然后:

tmp.putChild(b"quux", some_resource)

添加其他级别也是如此。因此:

root = Resource()
europe = Resource()
france = Resource()
paris = Resource()

root.putChild(b"europe", europe)
europe.putChild(b"france", france)
france.putChild(b"paris", paris)

在HTTP中实际上没有“不返回响应”之类的东西。但是,您可以根据需要使中间资源返回404(未找到)状态。只需将中间的Resource实例替换为您想要的行为(例如,NotFound实例)即可。

您可能还想研究klein,它实现了基于路由的资源层次结构定义API,这在如今的Python中通常更为常见。