[Web-SIG] Proposal: wsgi.url_vars

Ian Bicking 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: 
http://wsgi.org/wsgi/Specifications

And I'm introducing what I think is low-hanging fruit in the 
specification realm: wsgi.url_vars 
http://wsgi.org/wsgi/Specifications/url_vars

The spec is copied below for discussion:




:Title: wsgi.url_vars
:Author: Ian Bicking <ianb at colorstudy.com>
:Discussions-To: Python Web-SIG <web-sig at python.org>
:Status: Draft
:Created: 21-Oct-2006

.. contents::

Abstract
--------

This proposes a new standard environment key 
``environ['wsgi.url_vars']`` to represent the results of more 
complicated URL parsing strategies.

Rationale
---------

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: 
``wsgi.url_vars``.

Specification
-------------

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``).

Example
-------

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.

::

     class RegexDispatch(object):

         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:
                     continue
                 extra_path_info = path_info[match.end():]
                 if extra_path_info and not extra_path_info.startswith('/'):
                     # Not a very good match
                     continue
                 groups = match.groupdict()
                 environ.setdefault('wsgi.url_vars', {}).update(groups)
                 environ['SCRIPT_NAME'] = script_name + 
path_info[:match.end()]
                 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', 
'text/plain')])
             return ['Not found']

     dispatch_app = RegexDispatch([
         (re.compile(r'/archive/(?P<year>\d{4})/$'), archive_app),
         (re.compile(r'/archive/(?P<year>\d{4})/(?P<month>\d{2})/$'),
          archive_app),
 
(re.compile(r'/archive/(?P<year>\d{4})/(?P<month>\d{2})/(?P<article_id>\d+)$'),
          view_article),
         ])



More information about the Web-SIG mailing list