Store: per-host backoff after 403/429 honouring Retry-After

A host that answers 403/429 is left alone until its Retry-After (or GitHub's
rate-limit reset; default 10 minutes). Meanwhile cached data is served, or the
source reports 'limited' with its own name, e.g. 'GitHub is limiting requests;
try again in 10 minutes'. Covers _web reads/downloads and F-Droid fetches.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
saphidandClaude Opus 5.5 committed 2026-09-28 22:09:55 +10:00
1 parent c68afa6c5d
commit 7c439fdf28
7 files changed
+159 -28

No files matched your search

+3 -2
View File
@@ -25,7 +25,8 @@ def _api(path):
if token:
headers['Authorization'] = 'Bearer ' + token
try:
return json.loads(_web.read(API + path, ('api.github.com',), headers))
return json.loads(_web.read(API + path, ('api.github.com',), headers, name='GitHub',
hint='' if token else ' (set FRAME_GITHUB_TOKEN to raise the limit)'))
except (ValueError, TypeError) as e:
raise SourceError('Invalid GitHub response') from e
@@ -112,4 +113,4 @@ def download(source, entry_id, version_code=None):
expected = 'https://github.com/' + entry['id'] + '/releases/download/'
if not v['url'].startswith(expected):
raise SourceError('APK URL does not belong to the curated publisher')
return _web.apk(v['url'], HOSTS, v['sha256'])
return _web.apk(v['url'], HOSTS, v['sha256'], name='GitHub')