Skip to content

Instantly share code, notes, and snippets.

@erik4github
Created January 16, 2025 21:29
Show Gist options
  • Save erik4github/2819173e89f9d7250f4bafbc5d3b68ca to your computer and use it in GitHub Desktop.
Save erik4github/2819173e89f9d7250f4bafbc5d3b68ca to your computer and use it in GitHub Desktop.
import logging
import requests
from requests.adapters import HTTPAdapter, Retry
from requests.exceptions import RetryError, HTTPError
# Configure basic logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
def call_api_with_retries():
# Create a single Session
session = requests.Session()
# Configure retries for certain HTTP status codes or connection problems
retries = Retry(
total=3, # max retry attempts
backoff_factor=0.1, # sleep between attempts: 0.1s, 0.2s, 0.4s...
status_forcelist=[500, 502, 503, 504],
raise_on_status=False # by default, don't raise automatically on 5xx
)
adapter = HTTPAdapter(max_retries=retries)
session.mount("http://", adapter)
session.mount("https://", adapter)
# Example #1: URL that returns an HTTP 500
# This will NOT raise RetryError if the connection succeeds but the server
# keeps returning 500. Instead, you'll get a 5xx Response (response.ok = False).
url_500 = "http://httpstat.us/500"
# Example #2: URL that fails to connect (e.g., invalid port or hostname),
# which typically leads to RetryError if it never succeeds.
url_unreachable = "http://127.0.0.1:9999"
try:
logger.info("Sending request to %s", url_500)
response = session.get(url_500)
# If the server responded with 4xx/5xx, log "API call failed"
if not response.ok:
logger.error(
"API call failed (status code: %s, reason: %s)",
response.status_code,
response.reason
)
# Optionally raise an exception:
# response.raise_for_status()
except RetryError as ex:
# This block triggers if the retry logic fails entirely
logger.exception("Max retries exhausted when calling %s", url_500)
raise ex
except HTTPError as ex:
logger.exception("HTTP error occurred during request to %s", url_500)
raise ex
# Now illustrate unreachable URL => triggers RetryError if all attempts fail
try:
logger.info("Sending request to %s", url_unreachable)
response = session.get(url_unreachable)
# If no RetryError was raised, check the response
if not response.ok:
logger.error(
"API call failed (status code: %s, reason: %s)",
response.status_code,
response.reason
)
except RetryError as ex:
logger.exception("Max retries exhausted when calling %s", url_unreachable)
raise ex
except HTTPError as ex:
logger.exception("HTTP error occurred during request to %s", url_unreachable)
raise ex
if __name__ == "__main__":
call_api_with_retries()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment