{"id":3791,"library":"retry2","title":"Easy-to-Use Retry Decorator","description":"retry2 is a Python library that provides an easy-to-use decorator for retrying functions. It is a fork of the unmaintained `invl/retry` library, offering similar functionality with a focus on being pure standard library Python, though it can optionally preserve function signatures with an additional `decorator` dependency. The current version is 0.9.5.","status":"active","version":"0.9.5","language":"en","source_language":"en","source_url":"https://github.com/eSAMTrade/retry","tags":["retry","decorator","resilience","fault-tolerance"],"install":[{"cmd":"pip install retry2","lang":"bash","label":"Install `retry2`"},{"cmd":"pip install retry2 decorator","lang":"bash","label":"Install `retry2` with optional signature preservation"}],"dependencies":[{"reason":"Preserves function signatures when using the decorator; optional.","package":"decorator","optional":true}],"imports":[{"symbol":"retry","correct":"from retry import retry"},{"note":"For dynamically adjusting retry arguments, `retry_call` takes a function and its arguments.","symbol":"retry_call","correct":"from retry import retry_call"}],"quickstart":{"code":"from retry import retry\nimport time\n\ncall_count = 0\n\n@retry(exceptions=IOError, tries=3, delay=1, backoff=2)\ndef might_fail_api_call():\n    global call_count\n    call_count += 1\n    print(f\"Attempt {call_count}: Calling API...\")\n    if call_count < 3:\n        raise IOError(\"Temporary network issue\")\n    print(\"API call successful!\")\n    return \"Data\"\n\ntry:\n    result = might_fail_api_call()\n    print(f\"Final result: {result}\")\nexcept IOError as e:\n    print(f\"Failed after multiple retries: {e}\")","lang":"python","description":"This example demonstrates using the `@retry` decorator to automatically retry a function that raises an `IOError`. It will attempt 3 times, with an initial 1-second delay that doubles (backoff=2) between attempts."},"warnings":[{"fix":"Always explicitly set a finite `tries` parameter (e.g., `tries=3`) or `max_delay` to limit retry attempts, especially for operations that are not guaranteed to succeed.","message":"By default, the `@retry` decorator sets `tries=-1`, leading to infinite retries if no `tries` or `max_delay` is specified. This can cause indefinite blocking or resource exhaustion in production systems.","severity":"gotcha","affected_versions":"0.1.0 - 0.9.5"},{"fix":"Use `delay` with a positive value and `backoff` (e.g., `backoff=2` for exponential backoff) to introduce increasing delays between retries, giving the downstream service time to recover. Consider adding `jitter` for random variation.","message":"The default `delay=0` and `backoff=1` can lead to 'retry storms' where failed operations are immediately retried without a pause. This can overwhelm an already struggling service or cause cascading failures.","severity":"gotcha","affected_versions":"0.1.0 - 0.9.5"},{"fix":"If preserving function signatures is critical for your application or tooling, ensure `pip install decorator` is included in your project's dependencies alongside `retry2`.","message":"The library explicitly states that preserving function signatures (e.g., for introspection or other decorators) is optional and requires installing the `decorator` package. Without it, `inspect.signature` or other tools might report incorrect signatures.","severity":"gotcha","affected_versions":"0.1.0 - 0.9.5"},{"fix":"Specify the `exceptions` parameter to catch only known transient exceptions (e.g., `(requests.exceptions.ConnectionError, requests.exceptions.Timeout)`). Avoid retrying on generic `Exception` unless absolutely sure.","message":"Retries should only be applied to transient failures (e.g., network hiccups, temporary service unavailability). Retrying on permanent failures (e.g., 4xx client errors, validation errors) will not resolve the issue and will waste resources.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Design the retried function or the downstream service to handle duplicate requests safely, often by using unique request IDs or transaction identifiers.","message":"When retrying operations that modify state (e.g., payments, creating resources), ensure the underlying operation is idempotent. Without idempotency, retries can lead to unintended side effects like duplicate charges or entries.","severity":"gotcha","affected_versions":"All versions"}],"env_vars":null,"last_verified":"2026-04-11T00:00:00.000Z","next_check":"2026-07-10T00:00:00.000Z"}