[Web-SIG] Proposal: wsgi.url_vars
ianb at colorstudy.com
Sat Oct 21 19:49:06 CEST 2006
I think there's room for some more standards building on WSGI (that
aren't actually extensions of the WSGI spec itself).
I put a page up on the wsgi.org site for this:
And I'm introducing what I think is low-hanging fruit in the
specification realm: wsgi.url_vars
The spec is copied below for discussion:
:Author: Ian Bicking <ianb at colorstudy.com>
:Discussions-To: Python Web-SIG <web-sig at python.org>
This proposes a new standard environment key
``environ['wsgi.url_vars']`` to represent the results of more
complicated URL parsing strategies.
WSGI currently specifies the meaning of ``SCRIPT_NAME`` and
``PATH_INFO``, which allows generic prefix-based dispatchers to be
created. These dispatchers can work with any WSGI application that
respects the meaning of these two variables. The basic meaning of
``SCRIPT_NAME`` is *the portion of the path that has been consumed* and
``PATH_INFO`` is *the portion of the path left to the application*.
Using these two variables more complex dispatchers cannot represent the
information they pull out of the request path. This specification
simply defines a place where such dispatchers can put their information:
This specification defines a new key that can go in the WSGI
environment, ``wsgi.url_vars``. This key is optional.
If a dispatcher (like `routes <http://routes.groovie.org/>`_ or
`selector <http://lukearno.com/projects/selector/>`_) pulls named
information out of the portion of the request path it parses, it can put
that information into a dictionary in ``environ['wsgi.url_vars']``.
Portions of the path that have been parsed should still be moved to
``SCRIPT_NAME`` (and removed from ``PATH_INFO``).
This example is a dispatcher that is given regular expressions and
matching applications. It checks each regular expression in turn, and
when one matches it moves the named groups into ``wsgi.url_vars`` and
dispatches to the associated application.
def __init__(self, patterns):
self.patterns = patters
def __call__(self, environ, start_response):
script_name = environ.get('SCRIPT_NAME', '')
path_info = environ.get('PATH_INFO', '')
for regex, application in self.patterns:
match = regex.match(path_info)
if not match:
extra_path_info = path_info[match.end():]
if extra_path_info and not extra_path_info.startswith('/'):
# Not a very good match
groups = match.groupdict()
environ['SCRIPT_NAME'] = script_name +
environ['PATH_INFO'] = extra_path_info
return application(environ, start_response)
return self.not_found(environ, start_response)
def not_found(self, environ, start_response):
start_response('404 Not Found', [('Content-type',
return ['Not found']
dispatch_app = RegexDispatch([
More information about the Web-SIG