code: def rate_limited(self, key_function=None):
          
          if key_function is None:
              def key_function(*args, **kwargs):
                  data = pickle.dumps((args, sorted(kwargs.items())))
                  return hashlib.md5(data).hexdigest()
  
          def decorator(fn):
              @wraps(fn)
              def inner(*args, **kwargs):
                  key = key_function(*args, **kwargs)
                  if self.limit(key):
                      raise RateLimitException(
                          'Call to %s exceeded %s events in %s seconds.' % (
                              fn.__name__, self._limit, self._per))
                  return fn(*args, **kwargs)
              return inner
          return decorator
docs: Function or method decorator that will prevent calls to the decorated
          function when the number of events has been exceeded for the given
          time period.
  
          It is probably important that you take care to choose an appropiate
          key function. For instance, if rate-limiting a web-page you might use
          the requesting user's IP as the key.
  
          If the number of allowed events has been exceedd, a
          ``RateLimitException`` will be raised.
  
          :param key_function: Function that accepts the params of the decorated
              function and returns a string key. If not provided, a hash of the
              args and kwargs will be used.
          :returns: If the call is not rate-limited, then the return value will
              be that of the decorated function.
          :raises: ``RateLimitException``.