From dd7ac1f18ef4a431e2c2137029ff5e093ba27000 Mon Sep 17 00:00:00 2001 From: Niels de Vos Date: Wed, 14 Oct 2020 14:59:35 +0200 Subject: [PATCH] ci: log rate limit in case the GitHub API returns 403 Anonymous users have a low (currently 60) rate limit of API calls. Authorized users have a much higher (currently 5000) limit. Print the available, used and remainling rate limit when the GitHub API returns a 403 messages like: Error: 403 Client Error: rate limit exceeded In case of anonymous access to the API, and hitting the limit, the message in the logs will also include the following: Rate limit (limit/used/remaining): 60/60/0 Signed-off-by: Niels de Vos --- scripts/get_github_labels.py | 38 ++++++++++++++++++++++++++++-------- scripts/get_patch_release.py | 37 ++++++++++++++++++++++++++++------- 2 files changed, 60 insertions(+), 15 deletions(-) diff --git a/scripts/get_github_labels.py b/scripts/get_github_labels.py index 94703a07f..965d470eb 100755 --- a/scripts/get_github_labels.py +++ b/scripts/get_github_labels.py @@ -29,6 +29,33 @@ Formatted URL for fetching the labels, replace '%s' with the number of the Issue or Pull-Request. ''' +def log_rate_limit(res): + limit = -1 + if 'X-Ratelimit-Limit' in res.headers: + limit = int(res.headers['X-Ratelimit-Limit']) + + remaining = -1 + if 'X-Ratelimit-Remaining' in res.headers: + remaining = int(res.headers['X-Ratelimit-Remaining']) + + used = -1 + if 'X-Ratelimit-Used' in res.headers: + used = int(res.headers['X-Ratelimit-Used']) + + print('Rate limit (limit/used/remaining): %d/%d/%d' % (limit, used, remaining)) + + +def get_github_auth(): + auth = None + + if 'GITHUB_API_TOKEN' in os.environ: + github_api_token = os.environ['GITHUB_API_TOKEN'] + if github_api_token != '': + # the username "unused" is not relevant, needs to be non-empty + auth = HTTPBasicAuth('unused', github_api_token) + + return auth + def get_json_labels(gh_id): ''' @@ -37,15 +64,10 @@ def get_json_labels(gh_id): ''' url = LABEL_URL_FMT % gh_id headers = {'Accept': 'application/vnd.github.v3+json'} + res = requests.get(url, headers=headers, auth=get_github_auth()) - auth = None - if 'GITHUB_API_TOKEN' in os.environ: - github_api_token = os.environ['GITHUB_API_TOKEN'] - if github_api_token != '': - # the username "unused" is not relevant, needs to be non-empty - auth = HTTPBasicAuth('unused', github_api_token) - - res = requests.get(url, headers=headers, auth=auth) + if res.status_code == 403: + log_rate_limit(res) # if "res.status_code != requests.codes.ok", raise an exception res.raise_for_status() diff --git a/scripts/get_patch_release.py b/scripts/get_patch_release.py index b4a6b52da..123678162 100755 --- a/scripts/get_patch_release.py +++ b/scripts/get_patch_release.py @@ -23,21 +23,44 @@ returned releases from default 30 to 50 (max 100). ''' -def get_json_releases(): - ''' - Fetch the releases from GitHub, return the full JSON structures that were - obtained. - ''' - headers = {'Accept': 'application/vnd.github.v3+json'} +def log_rate_limit(res): + limit = -1 + if 'X-Ratelimit-Limit' in res.headers: + limit = int(res.headers['X-Ratelimit-Limit']) + remaining = -1 + if 'X-Ratelimit-Remaining' in res.headers: + remaining = int(res.headers['X-Ratelimit-Remaining']) + + used = -1 + if 'X-Ratelimit-Used' in res.headers: + used = int(res.headers['X-Ratelimit-Used']) + + print('Rate limit (limit/used/remaining): %d/%d/%d' % (limit, used, remaining)) + + +def get_github_auth(): auth = None + if 'GITHUB_API_TOKEN' in os.environ: github_api_token = os.environ['GITHUB_API_TOKEN'] if github_api_token != '': # the username "unused" is not relevant, needs to be non-empty auth = HTTPBasicAuth('unused', github_api_token) - res = requests.get(RELEASE_URL, headers=headers) + return auth + + +def get_json_releases(): + ''' + Fetch the releases from GitHub, return the full JSON structures that were + obtained. + ''' + headers = {'Accept': 'application/vnd.github.v3+json'} + res = requests.get(RELEASE_URL, headers=headers, auth=get_github_auth()) + + if res.status_code == 403: + log_rate_limit(res) # if "res.status_code != requests.codes.ok", raise an exception res.raise_for_status()