code: def retry(ExceptionToCheck, tries=4, delay=3, backoff=2):
      
      def deco_retry(f):
          @wraps(f)
          def f_retry(*args, **kwargs):
              mtries, mdelay = tries, delay
              while mtries > 1:
                  try:
                      return f(*args, **kwargs)
                  except ExceptionToCheck as e:
                      LOG.debug("%(err_mess)s. Retry calling function "
                                "'%(f_name)s' in %(delta)d seconds.",
                                {'err_mess': str(e), 'f_name': f.__name__,
                                 'delta': mdelay})
                      time.sleep(mdelay)
                      mtries -= 1
                      mdelay *= backoff
              LOG.debug("Last retry calling function '%s'.", f.__name__)
              return f(*args, **kwargs)
  
          return f_retry  # true decorator
  
      return deco_retry
docs: Retry calling the decorated function using an exponential backoff.
  
      Reference: http://www.saltycrane.com/blog/2009/11/trying-out-retry
      -decorator-python/
  
      :param ExceptionToCheck: the exception to check. may be a tuple of
          exceptions to check
      :param tries: number of times to try (not retry) before giving up
      :param delay: initial delay between retries in seconds
      :param backoff: backoff multiplier e.g. value of 2 will double the delay
          each retry