Skip to content

Commit b48dca6

Browse files
authored
fix: handle retrying and non-200 status codes when downloading advisories (#124)
Turns out we don't actually raise an error if we get a non-200 status code in this script, so if that happens we can end up generating advisories with incomplete data. In addition to having a non-200 raise an error I've also included logic for retrying once since a 429 was what originally led to me discovering this
1 parent e58c278 commit b48dca6

1 file changed

Lines changed: 19 additions & 2 deletions

File tree

scripts/download_sa_advisories.py

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
import json
1111
import os
12+
import time
1213
import typing
1314

1415
import requests
@@ -49,12 +50,28 @@ def download_sa_advisories_from_rest_api(last_modified_timestamp: int) -> None:
4950

5051
print(f'fetching sa advisories modified after {last_modified_timestamp}')
5152
url = 'https://www.drupal.org/api-d7/node.json?type=sa&sort=changed&direction=DESC&field_is_psa=0'
53+
retry = True
5254
while url != '':
5355
print(f'fetching {url}')
5456
response = requests.get(url, headers={'user-agent': user_agent})
57+
58+
# if we're making too many requests and have not already retried the current
59+
# url, wait the requested number of seconds before doing a retry
60+
if retry and response.status_code == 429:
61+
retry = False # just give up if we get told to back off again
62+
seconds = int(response.headers.get('Retry-After', 0))
63+
print(f' |* (waiting {seconds} seconds before retrying)')
64+
time.sleep(seconds)
65+
continue
66+
5567
if response.status_code != 200:
56-
print(f'X API responded {response.status_code}')
57-
break
68+
raise Exception(f'unexpected {response.status_code} response when fetching {url}')
69+
70+
# allow (re)retrying for future requests
71+
retry = True
72+
73+
# grab each advisory from the response and write it to disk
74+
# before then continuing to the next page (if there is one)
5875
data: drupal.ApiResponse[drupal.Advisory] = response.json()
5976
url = data.get('next', '').replace('api-d7/node?', 'api-d7/node.json?')
6077
for item in data['list']:

0 commit comments

Comments
 (0)