code: def retry_until_valid_or_limit_reached(method, limit, validation_fn, sleep_s=1,
                                         catch_exceptions=()):
    
    assert limit > 0, 'Limit must be greater than 0'
  
    def _execute_method(helper):
      try:
        return method()
      except catch_exceptions:
        if not helper.remaining:
          raise
        return None
  
    helper = RetryHelper(limit - 1)
    result = _execute_method(helper)
    while not validation_fn(result) and helper.retry_if_possible():
      time.sleep(sleep_s)
      result = _execute_method(helper)
    return result
docs: Executes a method until the retry limit or validation_fn returns True.
  
    The method is always called once so the effective lower limit for 'limit' is
    1.  Passing in a number less than 1 will still result it the method being
    called once.
  
    Args:
      method: The method to execute should take no arguments.
      limit: The number of times to try this method.  Must be >0.
      validation_fn: The validation function called on the function result to
          determine whether to keep looping.
      sleep_s: The time to sleep in between invocations.
      catch_exceptions: Tuple of exception types to catch and count as failures.
    Returns:
        Whatever the method last returned, implicit False would indicate the
          method never succeeded.