Delayed iteration for polling and retries.

Overview

image image image image image image image image image

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 organizing the code around functions hinders any 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.

Usage

creation

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

Iterable delays can express any waiting strategy, and constructors for common algorithms are also provided.

wait.count(1)           # incremental backoff 1, 2, 3, 4, 5, ...
wait(1) + 1             # alternate syntax 1, 2, 3, 4, 5, ...
wait.fibonacci(1)       # 1, 1, 2, 3, 5, ...
wait.polynomial(2)      # 0, 1, 4, 9, 16, ...

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

iteration

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
        ...
        break

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

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

functions

Yes, functional versions are provided, as well as being trivial to implement.

wait(...).throttle(iterable)                      # generate items from iterable
wait(...).repeat(func, *args, **kwargs)           # generate successive 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.

backoff = wait(0.1) * 2
@backoff.repeating
@backoff.retrying(exception)
@backoff.polling(predicate)

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.

async

Waiters also support async iteration. throttle optionally accepts an async iterable. repeat, retry, and poll optionally accept coroutine functions.

statistics

Waiter objects have a stats attribute for aggregating statistics about the calls made. The base implementation provides total and failure counts. The interface of the stats object itself is considered provisional for now, but can be extended by overriding the Stats class attribute. This also allows customization of the iterable values; elapsed time is the default.

Installation

% pip install waiter

Dependencies

  • multimethod

Tests

100% branch coverage.

% pytest [--cov]

Changes

dev

  • Python >=3.7 required

1.2

  • Python >=3.6 required

1.1

  • Stream from sized groups

1.0

  • Map a function across an iterable in batches

0.6

  • Extensible iterable values and statistics
  • Additional constructors: fibonacci, polynomial, accumulate

0.5

  • Asynchronous iteration

0.4

  • Decorators support methods
  • Iterables can be throttled

0.3

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

0.2

  • suppress context manager for exception handling
  • repeat method for decoupled iteration
  • first function for convenient filtering
Unfinished Python library based on ndspy, for Zelda: Phantom Hourglass and Spirit Tracks.

zed An unfinished library and toolset by me, for viewing and editing files from The Legend of Zelda: Phantom Hourglass and The Legend of Zelda: Spirit

4 Oct 13, 2022
Unofficial Valorant documentation and tools for third party developers

Valorant Third Party Toolkit This repository contains unofficial Valorant documentation and tools for third party developers. Our goal is to centraliz

Noah Kim 20 Dec 21, 2022
Script to quickly get the metrics from Github repos to analyze.

commit-prefix-analysis Script to quickly get the metrics from Github repos to analyze. Setup Install the Github CLI. You'll know its working when runn

David Carpenter 1 Dec 17, 2022
πŸŽ…πŸ» Helping santa understand ✨ python ✨

β˜ƒοΈ Advent of code 2021 β˜ƒοΈ Helping santa understand ✨ python ✨

Fluffy 2 Dec 25, 2021
Viewflow is an Airflow-based framework that allows data scientists to create data models without writing Airflow code.

Viewflow Viewflow is a framework built on the top of Airflow that enables data scientists to create materialized views. It allows data scientists to f

DataCamp 114 Oct 12, 2022
Jannik Ramrath 1 Feb 05, 2022
Data Poisoning based on Adversarial Attacks using Non-Robust Features

Data Poisoning based on Adversarial Attacks using Non-Robust Features Usage python main.py [-h] [--gpu | -g GPU] [--eps |-e EPSILON] [--pert | -p PER

Jonathan E. 1 Nov 02, 2021
monster hunter world randomizer project

mhw_randomizer monster hunter world randomizer project Settings are in rando_config.py Current script for attack randomization is n mytest.py There ar

2 Jan 24, 2022
BridgeWalk is a partially-observed reinforcement learning environment with dynamics of varying stochasticity.

BridgeWalk is a partially-observed reinforcement learning environment with dynamics of varying stochasticity. The player needs to walk along a bridge to reach a goal location. When the player walks o

Danijar Hafner 6 Jun 13, 2022
Tie together `drf-spectacular` and `djangorestframework-dataclasses` for easy-to-use apis and openapi schemas.

Speccify Tie together drf-spectacular and djangorestframework-dataclasses for easy-to-use apis and openapi schemas. Usage @dataclass class MyQ

Lyst 4 Sep 26, 2022
Files for QMC Workshop 2021

QMC Workshop 2021 This repository contains the presented slides and example files for the Quantum Monte Carlo (QMC) Workshop 5 October - 23 November,

QMCPACK 39 Nov 04, 2022
A web-based chat application that enables multiple users to interact with one another

A web-based chat application that enables multiple users to interact with one another, in the same chat room or different ones according to their choosing.

3 Apr 22, 2022
Library for RadiaCode-101

RadiaCode Π‘ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° для Ρ€Π°Π±ΠΎΡ‚Ρ‹ с Π΄ΠΎΠ·ΠΈΠΌΠ΅Ρ‚Ρ€ΠΎΠΌ RadiaCode-101, находится Π² Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠ΅ - API Π½Π΅ стабилСн ΠΈ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½Ρ‹ измСнСния. ΠŸΡ€ΠΈΠΌΠ΅Ρ€ использования (backe

Maxim Andreev 56 Nov 29, 2022
Would upload anything I do with/related to brainfuck

My Brainfu*k Repo Basically wanted to create something with Brainfu*k but realized that with the smol brain I have, I need to see the cell values real

Rafeed 1 Mar 22, 2022
a really simple bot that send you memes from reddit to whatsapp

a really simple bot that send you memes from reddit to whatsapp want to use use it? install the dependencies with pip3 install -r requirements.txt the

pai 10 Nov 28, 2021
Buggy script to play with GPOs

GPOwned /!\ This is a buggy PoC I made just to play with GPOs in my lab. Don't use it in production! /!\ The script uses impacket and ldap3 to update

45 Dec 15, 2022
A simple wrapper to analyse and visualise reinforcement learning agents' behaviour in the environment.

Visrl Visrl (pronounced "visceral") is a simple wrapper to analyse and visualise reinforcement learning agents' behaviour in the environment. Reinforc

Jet New 14 Jun 27, 2022
Purge your likes and wall comments from VKontakte. Set yourself free from your digital footprint.

vk_liberator Regain liberty in the cruel social media world. This program assists you with purging your metadata from Russian social network VKontakte

20 Jun 11, 2021
In this repo, I will put all the code related to data science using python libraries like Numpy, Pandas, Matplotlib, Seaborn and many more.

Python-for-DS In this repo, I will put all the code related to data science using python libraries like Numpy, Pandas, Matplotlib, Seaborn and many mo

1 Jan 10, 2022
Beancount Importers for DKB (Deutsche Kredit Bank) CSV Exports

Beancount DKB Importer beancount-dkb provides an Importer for converting CSV exports of DKB (Deutsche Kreditbank) account summaries to the Beancount f

Siddhant Goel 24 Aug 06, 2022