Latest Version: 0.9.6.2
/Users/bbangert/Programming/Python/routes/routes/__init__.py
0001"""Provides common classes and functions most users will want access to."""
0002import threadinglocal, sys
0003
0004class _RequestConfig(object):
0005    """
0006    RequestConfig thread-local singleton
0007    
0008    The Routes RequestConfig object is a thread-local singleton that should be initialized by
0009    the web framework that is utilizing Routes.
0010    """
0011    __shared_state = threadinglocal.local()
0012
0013    def __getattr__(self, name):
0014        return getattr(self.__shared_state, name)
0015
0016    def __setattr__(self, name, value):
0017        """
0018        If the name is environ, load the wsgi envion with load_wsgi_environ
0019        and set the environ
0020        """
0021        if name == 'environ':
0022            self.load_wsgi_environ(value)
0023            return self.__shared_state.__setattr__(name, value)
0024        return self.__shared_state.__setattr__(name, value)
0025
0026    def __delattr__(self, name):
0027        delattr(self.__shared_state, name)
0028
0029    def load_wsgi_environ(self, environ):
0030        """
0031        Load the protocol/server info from the environ and store it.
0032        Also, match the incoming URL if there's already a mapper, and
0033        store the resulting match dict in mapper_dict.
0034        """
0035        if environ.get('HTTPS') or environ.get('wsgi.url_scheme') == 'https':
0036            self.__shared_state.protocol = 'https'
0037        else:
0038            self.__shared_state.protocol = 'http'
0039        if hasattr(self, 'mapper'):
0040            self.mapper.environ = environ
0041        if 'PATH_INFO' in environ and hasattr(self, 'mapper'):
0042            mapper = self.mapper
0043            path = environ['PATH_INFO']
0044            result = mapper.routematch(path)
0045            if result is not None:
0046                self.__shared_state.mapper_dict = result[0]
0047                self.__shared_state.route = result[1]
0048            else:
0049                self.__shared_state.mapper_dict = None
0050                self.__shared_state.route = None
0051
0052        if environ.get('HTTP_HOST'):
0053            self.__shared_state.host = environ['HTTP_HOST']
0054        else:
0055            self.__shared_state.host = environ['SERVER_NAME']
0056            if environ['wsgi.url_scheme'] == 'https':
0057                if environ['SERVER_PORT'] != '443':
0058                    self.__shared_state.host += ':' + environ['SERVER_PORT']
0059            else:
0060                if environ['SERVER_PORT'] != '80':
0061                    self.__shared_state.host += ':' + environ['SERVER_PORT']
0062
0063def request_config(original=False):
0064    """
0065    Returns the Routes RequestConfig object.
0066    
0067    To get the Routes RequestConfig:
0068    
0069    >>> from routes import *
0070    >>> config = request_config()
0071    
0072    The following attributes must be set on the config object every request:
0073    
0074    mapper
0075        mapper should be a Mapper instance thats ready for use
0076    host
0077        host is the hostname of the webapp
0078    protocol
0079        protocol is the protocol of the current request
0080    mapper_dict
0081        mapper_dict should be the dict returned by mapper.match()
0082    redirect
0083        redirect should be a function that issues a redirect, 
0084        and takes a url as the sole argument
0085    prefix (optional)
0086        Set if the application is moved under a URL prefix. Prefix
0087        will be stripped before matching, and prepended on generation
0088    environ (optional)
0089        Set to the WSGI environ for automatic prefix support if the
0090        webapp is underneath a 'SCRIPT_NAME'
0091        
0092        Setting the environ will use information in environ to try and
0093        populate the host/protocol/mapper_dict options if you've already
0094        set a mapper.
0095    
0096    **Using your own requst local**
0097    
0098    If you have your own request local object that you'd like to use instead of the default
0099    thread local provided by Routes, you can configure Routes to use it::
0100        
0101        from routes import request_config()
0102        config = request_config()
0103        if hasattr(config, 'using_request_local'):
0104            config.request_local = YourLocalCallable
0105            config = request_config()
0106    
0107    Once you have configured request_config, its advisable you retrieve it again to get the
0108    object you wanted. The variable you assign to request_local is assumed to be a callable
0109    that will get the local config object you wish.
0110    
0111    This example tests for the presence of the 'using_request_local' attribute which will be
0112    present if you haven't assigned it yet. This way you can avoid repeat assignments of the
0113    request specific callable.
0114    
0115    Should you want the original object, perhaps to change the callable its using or stop
0116    this behavior, call request_config(original=True).
0117    """
0118    obj = _RequestConfig()
0119    if hasattr(obj, 'request_local') and original is False:
0120        return getattr(obj, 'request_local')()
0121    else:
0122        obj.using_request_local = False
0123    return _RequestConfig()
0124
0125from base import Mapper
0126from util import url_for, redirect_to
0127__all__=['Mapper', 'url_for', 'redirect_to', 'request_config']

Top