Skip to main content
Help us improve Python packaging – donate today!

Delayed iteration for polling and retries.

Project Description

Does Python need yet another retry / poll library? It needs at least one that isn’t coupled to decorators and functions. Decorators prevent the caller from customizing delay options. And even organizing the code around functions prevents custom handling of failures.

Waiter is built around iteration instead, because the foundation of retrying / polling is a slowly executing loop. The resulting interface is both easier to use and more flexible, decoupling the delay algorithms from the application logic.


Supply a number of seconds to repeat endlessly, or any iterable of seconds.

from waiter import wait

wait(1)              # 1, 1, 1, 1, ...
wait([1] * 3)        # 1, 1, 1
wait([0.5, 0.5, 60]) # circuit breaker

So any delay algorithm is easily created, but constructors for common algorithms are also provided.

wait(1) + 1       # incremental backoff 1, 2, 3, 4, ...
w = wait(1) * 2   # exponential backoff 1, 2, 4, 8, ...
w[:3]             # limit attempt count 1, 2, 4
w <= 5            # set maximum delay   1, 2, 4, 5, 5, 5, ...
w.random(-1, 1)   # add random jitter

Then simply use the wait object like any iterable, yielding the amount of elapsed time. Timeouts also supported of course.

from waiter import wait, suppress, first

for elapsed in wait(delays):           # first iteration is immediate
   with suppress(exception):           # then each subsequent iteration sleeps as necessary

for _ in wait(delays, timeout):        # standard convention for ignoring a loop variable
   ...                                 # won't sleep past the timeout
   if ...:

results = (... for _ in wait(delays))  # expressions are even easier
first(predicate, results[, default])   # filter for first true item
assert any(results)                    # perfect for tests too

Yes, functional versions are provided too, because now they’re trivial to implement.

wait(...).throttle(iterable)                      # generate items from iterable
wait(...).repeat(func, *args, **kwargs)           # generate results
wait(...).retry(exception, func, *args, **kwargs) # return first success or re-raise exception
wait(...).poll(predicate, func, *args, **kwargs)  # return first success or raise StopIteration

The decorator variants are simply partial applications of the corresponding methods. Note decorator syntax doesn’t support arbitrary expressions, hence the name assignment.

backoff = wait(0.1) * 2

But in the real world:

  • the function may not exist or be succinctly written as a lambda
  • the predicate may not exist or be succinctly written as a lambda
  • logging may be required
  • there may be complex handling of different exceptions or results

So consider the block form, just as decorators don’t render with blocks superfluous. Also note wait objects are re-iterable provided their original delays were.

In Python 3.6 or higher, waiters also support async iteration. throttle optionally accepts an async iterable. repeat, retry, and poll optionally accept coroutine functions.


$ pip install waiter


  • Python 2.7, 3.4+


100% branch coverage.

$ pytest [--cov]



  • Asynchronous iteration


  • Decorators support methods
  • Iterables can be throttled


  • Waiters behave as iterables instead of iterators
  • Support for function decorators


  • suppress context manager for exception handling
  • repeat method for decoupled iteration
  • first function for convenient filtering

Release history Release notifications

This version
History Node


History Node


History Node


History Node


History Node


History Node


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Filename, size & hash SHA256 hash help File type Python version Upload date
waiter-0.5-py2.py3-none-any.whl (8.1 kB) Copy SHA256 hash SHA256 Wheel py2.py3 Sep 17, 2017
waiter-0.5.tar.gz (6.3 kB) Copy SHA256 hash SHA256 Source None Sep 17, 2017

Supported by

Elastic Elastic Search Pingdom Pingdom Monitoring Google Google BigQuery Sentry Sentry Error logging CloudAMQP CloudAMQP RabbitMQ AWS AWS Cloud computing Fastly Fastly CDN DigiCert DigiCert EV certificate StatusPage StatusPage Status page