pinard@iro.umontreal.ca (François Pinard) writes:
Your example (quoted in full below, for reference) has been both useful and instructive. I have a question, though. What is the purpose of `isLeaf'? It does not seem to be called ever, when I run your example.
...
class ReportRequest(twisted.web.resource.Resource): def isLeaf(self): return true
Oops. 'isLeaf' is a boolean attribute, not a function. It is usually set at the class level, and overrides t.w.r.Resource's default of '0'. So this class should really be written as follows: class ReportRequest(twisted.web.resource.Resource): isLeaf = 1 (the ReportRequest example worked because a bound method happens to be "true" when evaluated in a conditional. However, it would never have been able to return "false"). 'isLeaf' is a flag tells the server to stop walking through the URL path. Each slash-delimited component of the URL is put into a list, and the resource tree is walked (the Site is asked for a child indexed by the first component, that child is asked for one indexed by the second, etc). If a child is returned with the .isLeaf flag set, the walk is terminated, and that child is responsible for dealing with the rest of the path on its own. The request.postpath array contains the remaining components of the URL. This is useful when you want to change the resource lookup behavior below some sub-node of the URL tree. Above the child that sets .isLeaf=1, the usual Resource.getChild() scheme is used to find a Resource. Below that, the child can do whatever it wants. For example, let's pretend that we have a web server which serves users' ~/public_html/ directories, but each user is in a department, and the URL is always supposed to look like http://foo.com/Department/User/Dir/Subdir/File . The top two levels of the tree (department and user) must do some kind of lookup to find out who is in which department and where their home directory is. The child that is returned by the User lookup would set .isLeaf=1, and then get the actual file based upon the directory path contained in the remaining part of the URL. We're basically breaking the URL into two pieces: [http://foo.com/Department/User], and [Dir/Subdir/File]. The resource tree is walked with the first part, but the second part is given all at once (as a list) to the results of the lookup on the first part. class MySite(Resource): def getChild(self, path, request): dept = self.findDepartment(path) # returns a DepartmentResource if dept == None: return error.NoResource("No such department '%s'" % path) return dept class DepartmentResource(Resource): def getChild(self, path, request): user = self.findUser(path) # returns a UserResource if user == None: return error.NoResource("No such user '%s'" % path) return user class UserResource(Resource): isLeaf = 1 # don't call our .getChild(), just do render() def render(self, request): # rest of URL is in request.postpath for p in request.postpath: if p == "..": return error.NoResource("naughty naughty") filename = os.path.join(self.homedir(), "public_html", request.postpath) file = File(filename) return file.render(request) I'm sure there are better examples of isLeaf out there.. this is what comes to my mind when I see that flag. cheers, -Brian