Polling Utility

0.3.2 · maintenance · verified Sat Apr 11

The `polling` library provides a simple yet powerful utility to repeatedly call a function until a desired condition is met or a timeout occurs. It is useful for waiting on external resources, API responses, or file system changes. The latest version is 0.3.2, released in May 2021. While functional, it is considered to be in maintenance mode, with a more actively developed and recommended fork, `polling2`, available.

Warnings

Install

Imports

Quickstart

This quickstart demonstrates how to use `polling.poll` to wait for a simulated asynchronous task to complete. It shows how to define a success condition using `check_success`, set polling intervals with `step`, and handle timeouts with `TimeoutException`. An additional example illustrates how to `ignore_exceptions` during polling.

import time
from polling import poll, TimeoutException

def my_task_status(task_id):
    # Simulate an external task that eventually completes
    # In a real scenario, this would check a database, API, etc.
    statuses = {123: ['pending', 'processing', 'completed']}
    current_status_index = getattr(my_task_status, 'counter', 0)
    status_list = statuses.get(task_id, ['failed'])
    status = status_list[current_status_index % len(status_list)]
    my_task_status.counter = current_status_index + 1
    print(f"Task {task_id}: current status is '{status}'")
    return status

my_task_status.counter = 0 # Initialize counter

try:
    # Poll until the task status is 'completed' or timeout after 5 seconds
    result = poll(
        lambda: my_task_status(123),
        check_success=lambda status: status == 'completed',
        step=1, # Check every 1 second
        timeout=5 # Stop after 5 seconds
    )
    print(f"Task completed with status: {result}")
except TimeoutException as te:
    print(f"Polling timed out after {te.timeout} seconds.")
    print(f"Last value before timeout: {te.values.get_nowait()}")

# Reset counter for another run (optional)
my_task_status.counter = 0

try:
    # Example with ignoring exceptions (e.g., during initial setup)
    # This dummy function will raise an error initially, then succeed
    def flaky_check():
        if getattr(flaky_check, 'fail_count', 0) < 2:
            flaky_check.fail_count = getattr(flaky_check, 'fail_count', 0) + 1
            raise ValueError("Still setting up...")
        return "Success!"
    flaky_check.fail_count = 0

    result_ignored = poll(
        flaky_check,
        ignore_exceptions=(ValueError,),
        step=0.5,
        timeout=3
    )
    print(f"Flaky check succeeded: {result_ignored}")
except TimeoutException:
    print("Flaky check timed out.")

view raw JSON →