The Multiple responder implements a hybrid website. It is a meta-responder: it enables you to tie together multiple responders into a coherent website, using the filesystem for hierarchical organization. It also gives you site-wide in- and outbound hooks via a "framework" abstraction. The Multiple responder is the most complicated part of httpy to explain in reference, but almost everything is optional, and it is fundamentally intuitive.
Multiple translates URI paths literally to the filesystem, rooting them in root. For example, if root is:
Then Multiple would translate a request for:
To the path:
When Multiple is instantiated, it searches the tree under root for
responders. If a directory contains a file named responder.py, then
Multiple tries to import a responder from that file, and uses that
responder to serve all requests for resources at or below that directory. If
responder.py defines a class named Responder, then that is used
as the responder. Otherwise Multiple uses the module itself. In either
case, the responder must provide the IResponder
interface, at least implicitly.
So if you define a responder in:
Then Multiple would route requests for all of the following to that responder:
http://localhost:8080/foo http://localhost:8080/foo/ http://localhost:8080/foo/bar
There must be at least one responder, associated with the root of the site. If none is defined, then Multiple uses the Static responder.
Furthermore, Multiple adds exactly one path to sys.path for each responder it finds. First it looks for a subdirectory named site-packages, then one named lib. The first one found is used.
If a directory contains a subdirectory named __ (double-underscore, referred to as a magic directory), then Multiple will use any responder defined there to serve requests for the parent directory, and the sys.path addition logic uses the magic directory as its base. If both a magic directory and its parent define a responder, then the parent's wins. If the responder comes from the parent, then any magic directory is considered for inclusion in sys.path, after site-packages and lib.
Multiple adds the following data attributes to each responder as it is discovered. Existing attributes are not overriden. For class responders, these are added before instantiation, so they are available during construction.
||the filesystem path of the responder's magic directory, or None if it does not exist [that's two underscores]|
||the path added to sys.path for this responder|
||the responder's filesystem path|
||the filesystem path of the magic directory in the publishing root, or None if it does not exist [that's three underscores]|
||the filesystem path of the publishing root|
||the URI path below which requests will go to this responder|
Responders are mini Python applications scattered about your site hierarchy. In order to unify these responders into a coherent website, Multiple provides a framework abstraction. Multiple looks for a file named framework.py in root and in root's magic directory, in that order. The first found is used. Frameworks have no required API, but they may hook into the HTTP transaction process by defining some or all of the following callables. These are listed in the order they are called.
500 Internal Server Errorotherwise. If the client is requesting a resource in __ or pkg, then get_responder raises
|response, responder, request)|
500 Internal Server Error. request is the same Request object. This method is not implemented by default.
Note that because request is passed to each hook, and then discarded following the transaction, you can safely store state there between hooks.
As with responders, Multiple adds the following data attributes to your framework if they are not already present. If your framework is a class, these are added immediately before instantiation.
||the filesystem path of the site's magic directory [that's two underscores]|
||the filesystem path of the site's publishing root|