[Twisted-Python] Twisted Resources / PathArgs

Clark C. Evans cce at clarkevans.com
Wed Feb 26 04:38:59 EST 2003


On Tue, Feb 25, 2003 at 01:20:34PM -0600, Ian Bicking wrote:
| > flexible.  I say this beacuse I was able to do path variables 
| > out-of-the-box (2 hours) with this tool; in Webware I've been 
| > maintaining a patch for over a year, and this patch isn't ideal.
| 
| Can you give a pointer to that?  I'm interesting in changing how paths
| are parsed in Webware, but I've never felt confident 

The Twisted model has the notion of a resource.   Let's start with
a simple working example:

    from twisted.web.resource import Resource
    from twisted.internet import reactor
    from twisted.web.server import Site
    from twisted.web.static import File
    
    class DynamicRequest(Resource):
        def isLeaf(self): return true
        def render(self, req):
            req.content_type = 'text/plain'
            return "uri: %s" % req.uri
    
    def run():
        root = Resource()
        root.putChild("dynamic", DynamicRequest())
        root.putChild("static",File("."))
        site = Site(root)
        reactor.listenTCP(8081,site)
        reactor.run()

The interface of resource is a collection, and has a
   getChild( pathsegment )
method is called for every segment in the path.  So,
   /foo/bar/baz
is somewhat equivalent to the following:
  site.resource.getChild('foo').getChild('bar').getChild('baz')

Twisted accomplishes this magic in a "private" function called
getChildForRequest which iterates over each path segment.  For
the current resource it first checks a mapping to see if any
static configured children (putChild) exist, and if a static
child isn't found, it calls getChild() to find the next child
in order.   Of course, the iteration stops when isLeaf() is true.

Twisted comes with many built in Resources, including a 
really nice one for doing redirects (Redirect) and dynamically
serving up a file system (File).  It also seems to have ones
for handling virtual hosts, and sessions.   Very cool.

For more detail...

http://www.twistedmatrix.com/documents/TwistedDocs/current/api/
       public/twisted.web.resource.Resource.html

On Tue, Feb 25, 2003 at 08:18:25PM +0100, Paul Jongsma wrote:
| Last night I was playing with Twisted to get some insight into it,
| one of the things which I tried to figure out was how to do
| path variables.
|
| Would you mind sharing your solution with me? The docs on
| Twisted are sparse and I haven't been able to figure it out
| yet..

Assume that your path is something like...

      /key:val/another:val/<servlet>

At any point in the tree, you should be able to add
the following "resource" which will eat all items
in the path having a colon.

class PathArgs(Resource):
    def getChild(self,path,request):
        if not(hasattr(request,'pathargs')):
            request.pathargs = {}
        pair = path.split(':')
        if 2 == len(pair):
            request.pathargs[pair[0]] = pair[1]
            return self
        return Resource.getChild(self,path,request)

To try it out, replace "root = Resource()" with "root = PathArgs()"
in the code above.   Note, you should be able to use this resource
anywhere in the tree...

I'm completely astonished with the power/simplicity of this
mechanism.  Serious Kudos to the brain who discovered it... that
such a small amount of code can add a "pathargs" attribute to
each request in a way that is completely pluggable is just
spectacular!  Clark




More information about the Twisted-Python mailing list