Object publishing is a very simple concept: making code objects accessible over some medium. The medium most often discussed, due to the prevalence of web applications is HTTP/S. For our purposes, the published objects we will discuss are instantiations of python classes written to provide resources over the network.
In the python community, the most famous example of object publishing is the Zope application server. Zope exposes object written in python or with various Zope scripts/products/etc. In an old Zope 2 Book, Zope's object publishing is broken down very simply:
- The client sends a request to the server
- The server locates the object using the request URL as a map
- The server calls the published object with arguments from the request.
- The server interprets and returns the results to the client
With such a simple definition of "object publishing", we can begin seeing "object publishing" pretty much anywhere python is used to deliver content or other resources on the web. For instance, Django qualifies as having an object publisher by means of the configuration mechanism whereby one can use regular expressions to map URLs to its "view" objects. We'll come back to Django in a bit.
Twisted's web "framework" Nevow has a object-publishing capabilities that, due to it being controlled by python classes is limited only by the python code you can write. There are four primary mechanisms by which one can publish objects in Nevow:
- child attributes on a resource
- child methods on a resource, or
- dynamic children using the childFactory() method
- manipulating the traversal of objects via locateChild() method
from twisted.application import serviceGive than this file was saved as site.tac (and that there was a sibling file named stuff.py with the resource SiteRoot defined), you would enter twistd -noy site.tac at the system prompt to run this. This would start a server listening on port 8080. But what is SiteRoot? It is a resource we are making available at the root of our application, "publishing" it at http://localhost:8080/. And what would it look like, you ask? Well, a silly example of stuff.py that define SiteRoot might be something like the following:
from twisted.application import strports
from nevow import appserver
import stuff
# instantiate the application
application = service.Application('Site')
# set up the main resource
root = mystuff.SiteRoot()
site = appserver.NevowSite(root)
# setup the web server
server = strports.service('tcp:8080', site)
server.setServiceParent(application)
from nevow import rendOne reason that this is a silly example is that it does nothing other than declare that the published resource will be an XHTML file with a Nevow namespace, providing no methods (and little content). Additionally, it uses the XML "string" loader, instead of using stan or the XML file loader (for using templates from disk). Regardless, if we add a child attribute that points to another class, we can start to see the object publishing behavior of Nevow:
from nevow import loaders
class SiteRoot(rend.Page):
docFactory = loaders.xmlstr('''<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0
Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"
xmlns:nevow="http://nevow.com/ns/nevow/0.1">
</html>''')
from nevow import rendStarting up our application with these changes will allow us to access the root and child object via the following URLs, respectively:
from nevow import loaders
class MyStuffResource(rend.Page):
docFactory = loaders.xmlstr('''<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0
Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"
xmlns:nevow="http://nevow.com/ns/nevow/0.1">
<h1>My Stuff</h1>
</html>''')
class SiteRoot(rend.Page):
docFactory = loaders.xmlstr('''<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0
Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"
xmlns:nevow="http://nevow.com/ns/nevow/0.1">
</html>''')
child_mystuff = MyStuffResource()
- http://localhost:8080/
- http://localhost:8080/mystuff
This has been a brief run-down on how you can use child_*() methods and child_ attributes to publish objects. In the next installment, I will show how to customize URL traversal for accessing these resources via the locateChild() method. In particular, I will show how to duplicate the Django URL conf functionality in Nevow.