mirror of
https://github.com/josegonzalez/python-github-backup.git
synced 2025-12-25 09:01:11 +01:00
update retry logic and logging
### What 1. configureable retry count 2. additional logging ### Why 1. pass retry count as a command line arg; default 5 2. show details when api requests fail ### Testing before merge compiles cleanly ### Validation after merge compile and test ### Issue addressed by this PR https://github.com/stellar/ops/issues/2039
This commit is contained in:
@@ -4,6 +4,7 @@
|
||||
import logging
|
||||
import os
|
||||
import sys
|
||||
from github_backup import max_retries
|
||||
|
||||
from github_backup.github_backup import (
|
||||
backup_account,
|
||||
@@ -39,6 +40,7 @@ logging.basicConfig(level=logging.INFO, handlers=[stdout_handler, stderr_handler
|
||||
def main():
|
||||
"""Main entry point for github-backup CLI."""
|
||||
args = parse_args()
|
||||
max_retries.MAX_RETRIES = args.max_retries
|
||||
|
||||
if args.private and not get_auth(args):
|
||||
logger.warning(
|
||||
|
||||
@@ -25,6 +25,7 @@ from http.client import IncompleteRead
|
||||
from urllib.error import HTTPError, URLError
|
||||
from urllib.parse import urlencode, urlparse
|
||||
from urllib.request import HTTPRedirectHandler, Request, build_opener, urlopen
|
||||
from github_backup import max_retries
|
||||
|
||||
try:
|
||||
from . import __version__
|
||||
@@ -75,7 +76,7 @@ else:
|
||||
)
|
||||
|
||||
# Retry configuration
|
||||
MAX_RETRIES = 5
|
||||
MAX_RETRIES = max_retries.MAX_RETRIES
|
||||
|
||||
|
||||
def logging_subprocess(
|
||||
@@ -468,6 +469,13 @@ def parse_args(args=None):
|
||||
parser.add_argument(
|
||||
"--exclude", dest="exclude", help="names of repositories to exclude", nargs="*"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--retries",
|
||||
dest="max_retries",
|
||||
type=int,
|
||||
default=5,
|
||||
help="maximum number of retries for API calls (default: 5)",
|
||||
)
|
||||
return parser.parse_args(args)
|
||||
|
||||
|
||||
@@ -737,16 +745,19 @@ def make_request_with_retry(request, auth):
|
||||
except HTTPError as exc:
|
||||
# HTTPError can be used as a response-like object
|
||||
if not is_retryable_status(exc.code, exc.headers):
|
||||
logger.error(f"API Error: {exc.code} {exc.reason} for {request.full_url}")
|
||||
raise # Non-retryable error
|
||||
|
||||
if attempt >= MAX_RETRIES - 1:
|
||||
logger.error(f"HTTP {exc.code} failed after {MAX_RETRIES} attempts")
|
||||
logger.error(f"HTTP {exc.code} failed after {MAX_RETRIES} attempts for {request.full_url}")
|
||||
raise
|
||||
|
||||
delay = calculate_retry_delay(attempt, exc.headers)
|
||||
logger.warning(
|
||||
f"HTTP {exc.code}, retrying in {delay:.1f}s "
|
||||
f"(attempt {attempt + 1}/{MAX_RETRIES})"
|
||||
f"HTTP {exc.code} ({exc.reason}), retrying in {delay:.1f}s "
|
||||
f"(attempt {attempt + 1}/{MAX_RETRIES}) for {request.full_url}"
|
||||
|
||||
)
|
||||
if auth is None and exc.code in (403, 429):
|
||||
logger.info("Hint: Authenticate to raise your GitHub rate limit")
|
||||
@@ -754,12 +765,12 @@ def make_request_with_retry(request, auth):
|
||||
|
||||
except (URLError, socket.error) as e:
|
||||
if attempt >= MAX_RETRIES - 1:
|
||||
logger.error(f"Connection error failed after {MAX_RETRIES} attempts: {e}")
|
||||
logger.error(f"Connection error failed after {MAX_RETRIES} attempts: {e} for {request.full_url}")
|
||||
raise
|
||||
delay = calculate_retry_delay(attempt, {})
|
||||
logger.warning(
|
||||
f"Connection error: {e}, retrying in {delay:.1f}s "
|
||||
f"(attempt {attempt + 1}/{MAX_RETRIES})"
|
||||
f"(attempt {attempt + 1}/{MAX_RETRIES}) for {request.full_url}"
|
||||
)
|
||||
time.sleep(delay)
|
||||
|
||||
|
||||
1
github_backup/max_retries.py
Normal file
1
github_backup/max_retries.py
Normal file
@@ -0,0 +1 @@
|
||||
MAX_RETRIES=None
|
||||
Reference in New Issue
Block a user