Skip to content

docs: explain Custom Callbacks better #492

@Young-Lord

Description

@Young-Lord

Currently, the Custom Callbacks section is a bit brief. For example, user might want to know when will before and after be invoked, and will they be invoked before or after before_sleep.
So, I would propose adding a flow chart displaying the sequence of the functions, or add example results to help readers better understanding.
For example, here is a code snippet showing when will the function be invoked and what effect will their return values will have.

Details
from typing import Callable
from tenacity import (
    retry,
    retry_if_exception_type,
    stop_after_attempt,
)


def construct_function(name: str, *, ret=None, base_function=None) -> Callable:
    # log funciton invoking
    def func(*args, **kwargs):
        print(name.ljust(10), str(args).ljust(10), str(kwargs).ljust(10))
        if base_function is not None:
            return base_function(*args, **kwargs)
        else:
            return ret

    return func


counter = 0


wrapper = retry(
    sleep=construct_function("sleep"),
    stop=construct_function("stop", base_function=stop_after_attempt(3)),
    wait=construct_function("wait", ret=2.34),
    # retry=construct_function("retry", ),
    retry=retry_if_exception_type(),
    before=construct_function("before"),
    after=construct_function("after"),
    before_sleep=construct_function("before_sleep"),
    retry_error_callback=construct_function("retry_error_callback"),
)


@wrapper
def success():
    global counter
    print(f"* main, {counter=}")
    if counter < 2:
        # success after 2 failed attempts
        counter += 1
        raise RuntimeError


@wrapper
def fail():
    raise ValueError


success()
print("\n=======\n")
fail()

Output:

before     (<RetryCallState 2756784329936: attempt #1; slept for 0.0; last result: none yet>,) {}
* main, counter=0
after      (<RetryCallState 2756784329936: attempt #1; slept for 0.0; last result: failed (RuntimeError )>,) {}
stop       (<RetryCallState 2756784329936: attempt #1; slept for 0.0; last result: failed (RuntimeError )>,) {}
wait       (<RetryCallState 2756784329936: attempt #1; slept for 0.0; last result: failed (RuntimeError )>,) {}
before_sleep (<RetryCallState 2756784329936: attempt #1; slept for 2.34; last result: failed (RuntimeError )>,) {}
sleep      (2.34,)    {}
before     (<RetryCallState 2756784329936: attempt #2; slept for 2.34; last result: none yet>,) {}
* main, counter=1
after      (<RetryCallState 2756784329936: attempt #2; slept for 2.34; last result: failed (RuntimeError )>,) {}
stop       (<RetryCallState 2756784329936: attempt #2; slept for 2.34; last result: failed (RuntimeError )>,) {}
wait       (<RetryCallState 2756784329936: attempt #2; slept for 2.34; last result: failed (RuntimeError )>,) {}
before_sleep (<RetryCallState 2756784329936: attempt #2; slept for 4.68; last result: failed (RuntimeError )>,) {}
sleep      (2.34,)    {}
before     (<RetryCallState 2756784329936: attempt #3; slept for 4.68; last result: none yet>,) {}
* main, counter=2

=======

before     (<RetryCallState 2756777974416: attempt #1; slept for 0.0; last result: none yet>,) {}
after      (<RetryCallState 2756777974416: attempt #1; slept for 0.0; last result: failed (ValueError )>,) {}
stop       (<RetryCallState 2756777974416: attempt #1; slept for 0.0; last result: failed (ValueError )>,) {}
wait       (<RetryCallState 2756777974416: attempt #1; slept for 0.0; last result: failed (ValueError )>,) {}
before_sleep (<RetryCallState 2756777974416: attempt #1; slept for 2.34; last result: failed (ValueError )>,) {}
sleep      (2.34,)    {}
before     (<RetryCallState 2756777974416: attempt #2; slept for 2.34; last result: none yet>,) {}
after      (<RetryCallState 2756777974416: attempt #2; slept for 2.34; last result: failed (ValueError )>,) {}
stop       (<RetryCallState 2756777974416: attempt #2; slept for 2.34; last result: failed (ValueError )>,) {}
wait       (<RetryCallState 2756777974416: attempt #2; slept for 2.34; last result: failed (ValueError )>,) {}
before_sleep (<RetryCallState 2756777974416: attempt #2; slept for 4.68; last result: failed (ValueError )>,) {}
sleep      (2.34,)    {}
before     (<RetryCallState 2756777974416: attempt #3; slept for 4.68; last result: none yet>,) {}
after      (<RetryCallState 2756777974416: attempt #3; slept for 4.68; last result: failed (ValueError )>,) {}
stop       (<RetryCallState 2756777974416: attempt #3; slept for 4.68; last result: failed (ValueError )>,) {}
retry_error_callback (<RetryCallState 2756777974416: attempt #3; slept for 4.68; last result: failed (ValueError )>,) {}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions