[Python-Dev] [Web-SIG] Adding wsgiref to stdlib

Ian Bicking ianb at colorstudy.com
Fri Apr 28 22:03:18 CEST 2006


Guido van Rossum wrote:
>> I think another useful addition would be some prefix-based dispatcher,
>> similar to paste.urlmap (but probably a bit simpler):
>> http://svn.pythonpaste.org/Paste/trunk/paste/urlmap.py
> 
> 
> IMO this is getting into framework design. Perhaps something like this
> could be added in 2.6?

I don't think it's frameworky.  It could be used to build a very 
primitive framework, but even then it's not a particularly useful 
starting point.

In Paste this would generally be used below any framework (or above I 
guess, depending on which side is "up").  You'd pass /blog to a blog 
app, /cms to a cms app, etc.  WSGI already is very specific about what 
needs to be done when doing this dispatching (adjusting SCRIPT_NAME and 
PATH_INFO), and that's all that the dispatching needs to do.

The applications themselves are written in some framework with internal 
notions of URL dispatching, but this doesn't infringe upon those. 
(Unless the framework doesn't respect SCRIPT_NAME and PATH_INFO; but 
that's their problem, as the dispatcher is just using what's already 
allowed for in the WSGI spec.)  It also doesn't overlap with frameworks, 
as prefix-based dispatching isn't really that useful in a framework.

The basic implementation is:

class PrefixDispatch(object):
     def __init__(self):
         self.applications = {}
     def add_application(self, prefix, app):
         self.applications[prefix] = app
     def __call__(self, environ, start_response):
         apps = sorted(self.applications.items(),
                       key=lambda x: -len(x[0]))
         path_info = environ.get('PATH_INFO', '')
         for prefix, app in apps:
             if not path_info.startswith(prefix):
                 continue
             environ['SCRIPT_NAME'] = environ.get('SCRIPT_NAME', '')+prefix
             environ['PATH_INFO'] = environ.get('PATH_INFO', 
'')[len(prefix):]
             return app(environ, start_response)
         start_response('404 Not Found', [('Content-type', 'text/html')])
         return ['<html><body><h1>Not Found</h1></body></html>']


There's a bunch of checks that should take place (most related to /'s), 
and the not found response should be configurable (probably as an 
application that can be passed in as an argument).  But that's most of 
what it should do.


-- 
Ian Bicking  /  ianb at colorstudy.com  /  http://blog.ianbicking.org


More information about the Python-Dev mailing list