Latest Version: 0.9.6.2
/Users/bbangert/Programming/Python/pylons/pylons/decorators/cache.py
0001"""Caching decorators"""
0002import inspect
0003import logging
0004
0005from decorator import decorator
0006from paste.deploy.converters import asbool
0007
0008import pylons
0009
0010log = logging.getLogger(__name__)
0011
0012def beaker_cache(key="cache_default", expire="never", type="dbm",
0013    query_args=False, **b_kwargs):
0014    """Cache decorator utilizing Beaker. Caches action or other function that
0015    returns a pickle-able object as a result.
0016
0017    Optional arguments:
0018
0019    key
0020        None - No variable key, uses function name as key
0021        "cache_default" - Uses all function arguments as the key
0022        string - Use kwargs[key] as key
0023        list - Joins the arguments in the list
0024    expire
0025        Time in seconds before cache expires, defaults to never
0026    type
0027        Type of cache to use: dbm, memory, file, memcached
0028    query_args
0029        Uses the query arguments as the key, defaults to False
0030
0031    If cache_enabled is set to False in the .ini file, then cache is disabled
0032    globally.
0033    """
0034    def wrapper(func, *args, **kwargs):
0035        """Decorator wrapper"""
0036        log.debug("Wrapped with key: %s, expire: %s, type: %s, query_args: %s",
0037                  key, expire, type, query_args)
0038        enabled = pylons.config.get("cache_enabled", "True")
0039        if not asbool(enabled):
0040            log.debug("Caching disabled, skipping cache lookup")
0041            return func(*args, **kwargs)
0042
0043        my_cache = pylons.cache.get_cache('%s.%s' % (func.__module__,
0044                                                     func.__name__))
0045        cache_key = _make_key(func, key, args, kwargs, query_args)
0046
0047        if expire == "never":
0048            cache_expire = None
0049        else:
0050            cache_expire = expire
0051
0052
0053        def create_func():
0054            log.debug("Creating new cache copy with key: %s, type: %s",
0055                      cache_key, type)
0056            result = func(*args, **kwargs)
0057            glob_response = pylons.response._current_obj()
0058            full_response = dict(headers=glob_response.headers,
0059                                 status=glob_response.status_code,
0060                                 cookies=glob_response.cookies,
0061                                 content=result)
0062            return full_response
0063
0064        response = my_cache.get_value(cache_key, createfunc=create_func,
0065                                     type=type, expiretime=cache_expire,
0066                                     **b_kwargs)
0067        glob_response = pylons.response._current_obj()
0068        glob_response.headers = response['headers']
0069        glob_response.status_code = response['status']
0070        glob_response.cookies = response['cookies']
0071        return response['content']
0072    return decorator(wrapper)
0073
0074def _make_key(func, key, args, kwargs, query_args):
0075    """Helps make unique key from largs, kwargs and request.GET"""
0076    if key == "cache_default":
0077        if query_args:
0078            cache_key = repr(dict(pylons.request.GET))
0079        else:
0080            cache_key = repr(kwargs.items())
0081            largs_keys = _make_dict_from_args(func, args)
0082            cache_key += repr(largs_keys.items())
0083    elif not key:
0084        cache_key = func.__name__
0085    else:
0086        if query_args:
0087            dic = pylons.request.GET
0088        else:
0089            largs_keys = _make_dict_from_args(func, args)
0090            dic = kwargs.copy()
0091            dic.update(largs_keys)
0092        if isinstance(key, list):
0093            cache_key = " ".join(["%s=%s" % (k, dic[k]) for k in key])
0094        else:
0095            cache_key = "%s=%s" % (key, dic[key])
0096    return cache_key
0097
0098def _make_dict_from_args(func, args):
0099    """Inspects function for name of args"""
0100    args_keys = {}
0101    for i, arg in enumerate(inspect.getargspec(func)[0]):
0102        if arg != "self":
0103            args_keys[arg] = args[i]
0104    return args_keys

Top