code: def get_cache_key(cache_key, alternative_cache_key, *func_args, **func_kwargs):
      
      if not cache_key:
          key = hashlib.sha1('%s.%s.%s' % (alternative_cache_key, func_args, func_kwargs)).hexdigest() #alternative_cache_key + str(func_args) + str(func_kwargs)
      elif isinstance(cache_key, (str, unicode)):
          key = hashlib.sha1(cache_key % locals()).hexdigest()
      elif callable(cache_key):
          key = hashlib.sha1(cache_key(*func_args, **func_kwargs)).hexdigest()
      return key
docs: Not a decorator, but a helper function to retrieve the cache
      key for a cached function with its arguments or keyword arguments.
      Also used to create the cache key in the first place (cache_func decorator).
      Args:
          - cache_key: if there was a specific cache key used to cache the
          function, it should be provided here. If not this should be None
          - alternative_cache_key: a cache key with the following syntax
          full_module_name.decorated_function_name (for example 'goscale.utils.get_language_from_path)
          NOTE: This is done since a decorated function call always return the 
          do_cache function from the decorator, but never itself
          - *func_args: original arguments of the decorated function
          NOTE: strings as args/kwargs might be unicode and instead of passing
          'string' to the function u'string' need to be passed to
          - **func_kwargs: keyword arguments of the decorated function