code: def wait_for(
          predicate,
          timeout_seconds=120,
          sleep_seconds=1,
          ignore_exceptions=True,
          inverse_predicate=False,
          noisy=False,
          required_consecutive_success_count=1):
      
      count = 0
      start_time = time_module.time()
      timeout = Deadline.create_deadline(timeout_seconds)
      while True:
          try:
              result = predicate()
          except Exception as e:
              if ignore_exceptions:
                  if noisy:
                      logger.exception("Ignoring error during wait.")
              else:
                  count = 0
                  raise  # preserve original stack
          else:
              if (not inverse_predicate and result) or (inverse_predicate and not result):
                  count = count + 1
              if count >= required_consecutive_success_count:
                  return result
  
          if timeout.is_expired():
              funname = __stringify_predicate(predicate)
              raise TimeoutExpired(timeout_seconds, funname)
          if noisy:
              header = '{}[{}/{}]'.format(
                  shakedown.cli.helpers.fchr('>>'),
                  pretty_duration(time_module.time() - start_time),
                  pretty_duration(timeout_seconds)
              )
              if required_consecutive_success_count > 1:
                  header = '{} [{} of {} times]'.format(
                      header,
                      count,
                      required_consecutive_success_count)
              print('{} spinning...'.format(header))
          time_module.sleep(sleep_seconds)
docs: waits or spins for a predicate, returning the result.
          Predicate is a function that returns a truthy or falsy value.
          An exception in the function will be returned.
          A timeout will throw a TimeoutExpired Exception.