Production-grade retries for Python
This release adds two handy classes for the cases when you just want to retry a single function/method call:
def do_something_with_url(url, some_kw):
resp = httpx.get(url)
resp.raise_for_status()
...
rc = stamina.RetryingCaller(attempts=5)
rc(httpx.HTTPError, do_something_with_url, f"https://httpbin.org/status/404", some_kw=42)
# You can also create a caller with a pre-bound exception type:
bound_rc = rc.on(httpx.HTTPError)
bound_rc(do_something_with_url, f"https://httpbin.org/status/404", some_kw=42)
Both rc
and bound_rc
run:
do_something_with_url(f"https://httpbin.org/status/404", some_kw=42)
Unfortunately, it's not possible to implement this behavior transparently for async, so you have to use AsyncRetryingCaller
for async callables.
Full changelog below!
This release would not be possible without my generous sponsors! Thank you to all of you making sustainable maintenance possible! If you would like to join them, go to https://github.com/sponsors/hynek and check out the sweet perks!
Variomedia AG (@variomedia), Tidelift (@tidelift), FilePreviews (@filepreviews), Daniel Fortunov (@asqui), Kevin P. Fleming (@kpfleming), and Sören Weber (@SoerenWeber).
Adam Hill (@adamghill), Dan Groshev (@si14), Magnus Watn (@magnuswatn), David Cramer (@dcramer), Moving Content AG (@moving-content), ProteinQure (@ProteinQure), Jesse Snyder (@jessesnyder), Rivo Laks (@rivol), Ionel Cristian Mărieș (@ionelmc), The Westervelt Company (@westerveltco), Philippe Galvan (@PhilippeGalvan), Birk Jernström (@birkjernstrom), Tim Schilling (@tim-schilling), Chris Withers (@cjw296), Christopher Dignam (@chdsbd), Stefan Hagen (@sthagen), Sławomir Ehlert (@slafs), Mostafa Khalil (@khadrawy), Filip Mularczyk (@mukiblejlok), Mike Fiedler (@miketheman), and Michel Vittória (@michelvittoria).
Not to forget 5 more amazing humans who chose to be generous but anonymous!
stamina.RetryingCaller
and stamina.AsyncRetryingCaller
that allow even easier retries of single callables: stamina.RetryingCaller(attempts=5).on(ValueError)(do_something, "foo", bar=42)
and stamina.RetryingCaller(attempts=5)(ValueError, do_something, "foo", bar=42)
will call do_something("foo", bar=42)
and retry on ValueError
up to 5 times.
stamina.RetryingCaller
and stamina.AsyncRetryingCaller
take the same arguments as stamina.retry()
, except for on
that can be bound separately.
This release only fixes one fun bug caused by one missing return statement. If you ever wondered why you successful blocks got retried when you deactivated stamina – wonder no longer.
This release would not be possible without my generous sponsors! Thank you to all of you making sustainable maintenance possible! If you would like to join them, go to https://github.com/sponsors/hynek and check out the sweet perks!
Variomedia AG (@variomedia), Tidelift (@tidelift), FilePreviews (@filepreviews), Daniel Fortunov (@asqui), and Kevin P. Fleming (@kpfleming).
Adam Hill (@adamghill), Dan Groshev (@si14), Magnus Watn (@magnuswatn), David Cramer (@dcramer), Moving Content AG (@moving-content), ProteinQure (@ProteinQure), Jesse Snyder (@jessesnyder), Rivo Laks (@rivol), Ionel Cristian Mărieș (@ionelmc), The Westervelt Company (@westerveltco), Philippe Galvan (@PhilippeGalvan), Birk Jernström (@birkjernstrom), Tim Schilling (@tim-schilling), Chris Withers (@cjw296), Christopher Dignam (@chdsbd), Stefan Hagen (@sthagen), Sławomir Ehlert (@slafs), Mostafa Khalil (@khadrawy), Filip Mularczyk (@mukiblejlok), and Mike Fiedler (@miketheman).
Not to forget 6 more amazing humans who chose to be generous but anonymous!
Support for the Trio async framework!
This release would not be possible without my generous sponsors! Thank you to all of you making sustainable maintenance possible! If you would like to join them, go to https://github.com/sponsors/hynek and check out the sweet perks!
Variomedia AG (@variomedia), Tidelift (@tidelift), FilePreviews (@filepreviews), Daniel Fortunov (@asqui), and Kevin P. Fleming (@kpfleming).
Adam Hill (@adamghill), Dan Groshev (@si14), Magnus Watn (@magnuswatn), David Cramer (@dcramer), Moving Content AG (@moving-content), ProteinQure (@ProteinQure), Jesse Snyder (@jessesnyder), Rivo Laks (@rivol), Ionel Cristian Mărieș (@ionelmc), The Westervelt Company (@westerveltco), Philippe Galvan (@PhilippeGalvan), Birk Jernström (@birkjernstrom), Tim Schilling (@tim-schilling), Chris Withers (@cjw296), Christopher Dignam (@chdsbd), Stefan Hagen (@sthagen), Sławomir Ehlert (@slafs), Mostafa Khalil (@khadrawy), and Filip Mularczyk (@mukiblejlok).
Not to forget 5 more amazing humans who chose to be generous but anonymous!
The highlight of this release are without question configurable retry hooks! You can now freely configure functions that are run whenever a retry is scheduled.
Can't wait to see what kind of third-party integrations y'all come up with – please show and tell us!
As a bonus, stamina now also comes with standard library's logging
instrumentation out of the box.
If you have praise, comments, or concerns (that aren't outright bugs), head over to the release discussion!
This release would not be possible without my generous sponsors! Thank you to all of you making sustainable maintenance possible! If you would like to join them, go to https://github.com/sponsors/hynek and check out the sweet perks!
Variomedia AG (@variomedia), Tidelift (@tidelift), HiredScore (@HiredScore), FilePreviews (@filepreviews), Daniel Fortunov (@asqui), and Kevin P. Fleming (@kpfleming).
Adam Hill (@adamghill), Dan Groshev (@si14), Magnus Watn (@magnuswatn), David Cramer (@dcramer), Moving Content AG (@moving-content), ProteinQure (@ProteinQure), Jesse Snyder (@jessesnyder), Rivo Laks (@rivol), Ionel Cristian Mărieș (@ionelmc), The Westervelt Company (@westerveltco), Philippe Galvan (@PhilippeGalvan), Birk Jernström (@birkjernstrom), Tim Schilling (@tim-schilling), Chris Withers (@cjw296), Christopher Dignam (@chdsbd), and Sławomir Ehlert (@slafs).
Not to forget 5 more amazing humans who chose to be generous but anonymous!
Instrumentation is now pluggable! You can define your own hooks that are run with retry details whenever a retry is scheduled. The documentation now has a whole chapter on instrumentation. #37
If structlog is not installed, the scheduled retry is now logged using the standard library logging
module by default. #35
Tenacity's internal AttemptManager
object is no longer exposed to the user. This was an oversight and never documented. stamina.retry_context()
now yields instances of stamina.Attempt
. #22
Initialization of instrumentation is now delayed. This means that if there's no retries, there's no startup overhead from importing structlog and prometheus-client. #34
Some key names in structlog log messages have been renamed to better reflect their meaning (slept
→ waited_so_far
, attempt
→ retry_num
, and error
→ caused_by
). You can rename them back using structlog's structlog.processors.EventRenamer
. #35
With this release, stamina graduates to becoming a "real" project. It now has proper documentation and a backwards-compatibility policy.
The other highlights are certainly transparent support for async and retrying of arbitrary code blocks!
Full changelog can be found below.
This release would not be possible without my generous sponsors! Thank you to all of you making sustainable maintenance possible! If you would like to join them, go to https://github.com/sponsors/hynek and check out the sweet perks!
Variomedia AG (@variomedia), Tidelift (@tidelift), Sentry (@getsentry), HiredScore (@HiredScore), FilePreviews (@filepreviews), and Daniel Fortunov (@asqui).
Adam Hill (@adamghill), Dan Groshev (@si14), Magnus Watn (@magnuswatn), David Cramer (@dcramer), Moving Content AG (@moving-content), Stein Magnus Jodal (@jodal), ProteinQure (@ProteinQure), Jesse Snyder (@jessesnyder), Rivo Laks (@rivol), Tom Ballinger (@thomasballinger), Ionel Cristian Mărieș (@ionelmc), The Westervelt Company (@westerveltco), Philippe Galvan (@PhilippeGalvan), Birk Jernström (@birkjernstrom), Tim Schilling (@tim-schilling), Chris Withers (@cjw296), Christopher Dignam (@chdsbd), Stefan Hagen (@sthagen), and zorazen (@ZoraZen).
Not to forget 3 more amazing humans who chose to be generous but anonymous!
for
loops and context managers. #12
datetime.timedelta
.Instrumentation!
stamina_retries_total
.
If structlog is installed, they are logged using a structlog logger at warning level.
These two instrumentations are independent from each other.First release!