{"library":"stamina","title":"Stamina: Production-Grade Retries","type":"library","description":"Stamina is a Python library that provides production-grade retries made easy, acting as an opinionated wrapper around Tenacity. It ensures resilient systems by handling transient failures with sensible defaults like exponential backoff with jitter, configurable exception handling, and automatic async support. It releases regularly, typically every few months, and is designed to minimize potential for misuse.","language":"python","status":"active","last_verified":"Thu May 21","install":{"commands":["pip install stamina","pip install stamina httpx"],"cli":null},"imports":["from stamina import retry","from stamina import retry_context","from stamina import set_testing","from stamina import RetryingCaller"],"auth":{"required":false,"env_vars":[]},"links":{"homepage":null,"github":"https://github.com/hynek/stamina","docs":"https://stamina.hynek.me/","changelog":"https://github.com/hynek/stamina/blob/main/CHANGELOG.md","pypi":"https://pypi.org/project/stamina/","npm":null,"openapi_spec":null,"status_page":null,"smithery":null},"quickstart":{"code":"import httpx\nimport stamina\nimport os\n\n@stamina.retry(on=httpx.HTTPStatusError, attempts=3, timeout=5)\ndef fetch_url_with_retry(url: str) -> str:\n    try:\n        response = httpx.get(url, timeout=1)\n        response.raise_for_status() # Raises HTTPStatusError for 4xx/5xx responses\n        return f\"Successfully fetched: {response.status_code}\"\n    except httpx.HTTPStatusError as e:\n        # Example: only retry on 5xx errors\n        if e.response.status_code >= 500:\n            print(f\"Retrying on {e.response.status_code} for {url}...\")\n            raise\n        else:\n            print(f\"Not retrying on {e.response.status_code} for {url}.\")\n            raise\n    except httpx.RequestError as e:\n        print(f\"Request error for {url}: {e}, retrying...\")\n        raise\n\n# Example usage:\ntry:\n    # This URL will fail with 500 and retry\n    print(fetch_url_with_retry(\"https://httpbin.org/status/500\"))\nexcept (httpx.HTTPStatusError, httpx.RequestError) as e:\n    print(f\"Final failure after retries for 500: {e}\")\n\ntry:\n    # This URL will fail with 404 and not retry (due to the if e.response.status_code >= 500 check)\n    print(fetch_url_with_retry(\"https://httpbin.org/status/404\"))\nexcept (httpx.HTTPStatusError, httpx.RequestError) as e:\n    print(f\"Final failure for 404 (not retried): {e}\")\n\ntry:\n    # This URL will succeed\n    print(fetch_url_with_retry(\"https://httpbin.org/status/200\"))\nexcept (httpx.HTTPStatusError, httpx.RequestError) as e:\n    print(f\"Unexpected failure for 200: {e}\")\n","lang":"python","description":"This quickstart demonstrates using the `@stamina.retry` decorator with `httpx` to handle transient HTTP errors. It configures retries for `httpx.HTTPStatusError` but includes a custom check to only retry on 5xx status codes, explicitly not retrying on 4xx client errors, and limits attempts and total timeout.","tag":null,"tag_description":null,"last_tested":"2026-04-25","results":[{"runtime":"python:3.10-alpine","exit_code":1},{"runtime":"python:3.10-slim","exit_code":1},{"runtime":"python:3.11-alpine","exit_code":1},{"runtime":"python:3.11-slim","exit_code":1},{"runtime":"python:3.12-alpine","exit_code":1},{"runtime":"python:3.12-slim","exit_code":1},{"runtime":"python:3.13-alpine","exit_code":1},{"runtime":"python:3.13-slim","exit_code":1},{"runtime":"python:3.9-alpine","exit_code":1},{"runtime":"python:3.9-slim","exit_code":1}]},"compatibility":{"tag":null,"tag_description":null,"last_tested":"2026-05-21","installed_version":"25.1.0","pypi_latest":"26.1.0","is_stale":true,"summary":{"python_range":"3.10–3.9","success_rate":100,"avg_install_s":1.9,"avg_import_s":0.11,"wheel_type":"wheel"},"results":[{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"stamina","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":null,"import_time_s":0.07,"mem_mb":2.9,"disk_size":"18.2M"},{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"stamina","exit_code":0,"wheel_type":null,"failure_reason":null,"import_side_effects":null,"install_time_s":null,"import_time_s":0.08,"mem_mb":2.9,"disk_size":"18.2M"},{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"stamina","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":null,"import_time_s":0.07,"mem_mb":2.9,"disk_size":"22.3M"},{"runtime":"python:3.10-alpine","python_version":"3.10","os_libc":"alpine (musl)","variant":"stamina","exit_code":0,"wheel_type":null,"failure_reason":null,"import_side_effects":null,"install_time_s":null,"import_time_s":0.07,"mem_mb":2.9,"disk_size":"22.3M"},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"stamina","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":1.5,"import_time_s":0.05,"mem_mb":2.9,"disk_size":"19M"},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"stamina","exit_code":0,"wheel_type":null,"failure_reason":null,"import_side_effects":null,"install_time_s":null,"import_time_s":0.06,"mem_mb":2.9,"disk_size":"19M"},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"stamina","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":2.2,"import_time_s":0.04,"mem_mb":2.9,"disk_size":"23M"},{"runtime":"python:3.10-slim","python_version":"3.10","os_libc":"slim (glibc)","variant":"stamina","exit_code":0,"wheel_type":null,"failure_reason":null,"import_side_effects":null,"install_time_s":null,"import_time_s":0.06,"mem_mb":2.9,"disk_size":"23M"},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"stamina","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":null,"import_time_s":0.12,"mem_mb":3.3,"disk_size":"20.0M"},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"stamina","exit_code":0,"wheel_type":null,"failure_reason":null,"import_side_effects":null,"install_time_s":null,"import_time_s":0.19,"mem_mb":3.3,"disk_size":"20.0M"},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"stamina","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":null,"import_time_s":0.13,"mem_mb":3.3,"disk_size":"24.6M"},{"runtime":"python:3.11-alpine","python_version":"3.11","os_libc":"alpine (musl)","variant":"stamina","exit_code":0,"wheel_type":null,"failure_reason":null,"import_side_effects":null,"install_time_s":null,"import_time_s":0.15,"mem_mb":3.3,"disk_size":"24.6M"},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"stamina","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":1.6,"import_time_s":0.1,"mem_mb":3.3,"disk_size":"21M"},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"stamina","exit_code":0,"wheel_type":null,"failure_reason":null,"import_side_effects":null,"install_time_s":null,"import_time_s":0.12,"mem_mb":3.3,"disk_size":"21M"},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"stamina","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":2.3,"import_time_s":0.1,"mem_mb":3.3,"disk_size":"25M"},{"runtime":"python:3.11-slim","python_version":"3.11","os_libc":"slim (glibc)","variant":"stamina","exit_code":0,"wheel_type":null,"failure_reason":null,"import_side_effects":null,"install_time_s":null,"import_time_s":0.12,"mem_mb":3.3,"disk_size":"25M"},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"stamina","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":null,"import_time_s":0.12,"mem_mb":3.3,"disk_size":"11.9M"},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"stamina","exit_code":0,"wheel_type":null,"failure_reason":null,"import_side_effects":null,"install_time_s":null,"import_time_s":0.15,"mem_mb":3.3,"disk_size":"11.9M"},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"stamina","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":null,"import_time_s":0.12,"mem_mb":3.3,"disk_size":"16.3M"},{"runtime":"python:3.12-alpine","python_version":"3.12","os_libc":"alpine (musl)","variant":"stamina","exit_code":0,"wheel_type":null,"failure_reason":null,"import_side_effects":null,"install_time_s":null,"import_time_s":0.13,"mem_mb":3.3,"disk_size":"16.3M"},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"stamina","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":1.5,"import_time_s":0.12,"mem_mb":3.3,"disk_size":"12M"},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"stamina","exit_code":0,"wheel_type":null,"failure_reason":null,"import_side_effects":null,"install_time_s":null,"import_time_s":0.17,"mem_mb":3.3,"disk_size":"12M"},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"stamina","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":2,"import_time_s":0.12,"mem_mb":3.3,"disk_size":"17M"},{"runtime":"python:3.12-slim","python_version":"3.12","os_libc":"slim (glibc)","variant":"stamina","exit_code":0,"wheel_type":null,"failure_reason":null,"import_side_effects":null,"install_time_s":null,"import_time_s":0.15,"mem_mb":3.3,"disk_size":"17M"},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"stamina","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":null,"import_time_s":0.12,"mem_mb":3.5,"disk_size":"11.7M"},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"stamina","exit_code":0,"wheel_type":null,"failure_reason":null,"import_side_effects":null,"install_time_s":null,"import_time_s":0.14,"mem_mb":3.5,"disk_size":"11.5M"},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"stamina","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":null,"import_time_s":0.11,"mem_mb":3.5,"disk_size":"15.7M"},{"runtime":"python:3.13-alpine","python_version":"3.13","os_libc":"alpine (musl)","variant":"stamina","exit_code":0,"wheel_type":null,"failure_reason":null,"import_side_effects":null,"install_time_s":null,"import_time_s":0.13,"mem_mb":3.5,"disk_size":"15.6M"},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"stamina","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":1.5,"import_time_s":0.11,"mem_mb":3.3,"disk_size":"12M"},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"stamina","exit_code":0,"wheel_type":null,"failure_reason":null,"import_side_effects":null,"install_time_s":null,"import_time_s":0.18,"mem_mb":3.3,"disk_size":"12M"},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"stamina","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":2,"import_time_s":0.11,"mem_mb":3.3,"disk_size":"16M"},{"runtime":"python:3.13-slim","python_version":"3.13","os_libc":"slim (glibc)","variant":"stamina","exit_code":0,"wheel_type":null,"failure_reason":null,"import_side_effects":null,"install_time_s":null,"import_time_s":0.13,"mem_mb":3.3,"disk_size":"16M"},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"stamina","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":null,"import_time_s":0.07,"mem_mb":3.1,"disk_size":"18.0M"},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"stamina","exit_code":0,"wheel_type":null,"failure_reason":null,"import_side_effects":null,"install_time_s":null,"import_time_s":0.11,"mem_mb":3.1,"disk_size":"18.0M"},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"stamina","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":null,"import_time_s":0.07,"mem_mb":3.1,"disk_size":"21.6M"},{"runtime":"python:3.9-alpine","python_version":"3.9","os_libc":"alpine (musl)","variant":"stamina","exit_code":0,"wheel_type":null,"failure_reason":null,"import_side_effects":null,"install_time_s":null,"import_time_s":0.07,"mem_mb":3.1,"disk_size":"21.6M"},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"stamina","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":1.9,"import_time_s":0.06,"mem_mb":3.1,"disk_size":"18M"},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"stamina","exit_code":0,"wheel_type":null,"failure_reason":null,"import_side_effects":null,"install_time_s":null,"import_time_s":0.07,"mem_mb":3.1,"disk_size":"18M"},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"stamina","exit_code":0,"wheel_type":"wheel","failure_reason":null,"import_side_effects":"clean","install_time_s":2.5,"import_time_s":0.07,"mem_mb":3.1,"disk_size":"22M"},{"runtime":"python:3.9-slim","python_version":"3.9","os_libc":"slim (glibc)","variant":"stamina","exit_code":0,"wheel_type":null,"failure_reason":null,"import_side_effects":null,"install_time_s":null,"import_time_s":0.08,"mem_mb":3.1,"disk_size":"22M"}]}}