mirror of
https://github.com/status-im/PyGithub.git
synced 2026-09-01 19:31:10 +00:00
Handle HTTP 202 HEAD&GET with a retry (#791)
* Handle HTTP 202 Fixes #564 After some testing, it seems GitHub seems to be able to process the chrunching of statistics for every repository I tested in around 2 seconds. So a delay of around 5 seconds should be plenty to be very certain that the next try should succeed. Another option would be to put this value lower and possibly waste an extra retry on it. * Only re-request data if HEAD or GET (those are 'safe') to e.g. avoid running a duplicate POST or PUT, that can change stuff on the server Using RFC 2616 and https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html as guideline * Fix testStatistics * change wait time to 2 secs
This commit is contained in:
committed by
Wan Liuyang
parent
8bdac23ca1
commit
3aead15818
@@ -9,6 +9,7 @@
|
||||
# Copyright 2016 Peter Buckley <dx-pbuckley@users.noreply.github.com> #
|
||||
# Copyright 2018 Wan Liuyang <tsfdye@gmail.com> #
|
||||
# Copyright 2018 sfdye <tsfdye@gmail.com> #
|
||||
# Copyright 2018 Maarten Fonville <maarten.fonville@gmail.com #
|
||||
# #
|
||||
# This file is part of PyGithub. #
|
||||
# http://pygithub.readthedocs.io/ #
|
||||
@@ -31,6 +32,7 @@
|
||||
|
||||
REQ_IF_NONE_MATCH = "If-None-Match"
|
||||
REQ_IF_MODIFIED_SINCE = "If-Modified-Since"
|
||||
PROCESSING_202_WAIT_TIME = 2
|
||||
|
||||
# ##############################################################################
|
||||
# Response Header #
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
# Copyright 2017 Simon <spam@esemi.ru> #
|
||||
# Copyright 2018 R1kk3r <R1kk3r@users.noreply.github.com> #
|
||||
# Copyright 2018 sfdye <tsfdye@gmail.com> #
|
||||
# Copyright 2018 Maarten Fonville <maarten.fonville@gmail.com> #
|
||||
# #
|
||||
# This file is part of PyGithub. #
|
||||
# http://pygithub.readthedocs.io/ #
|
||||
@@ -57,6 +58,7 @@ import os
|
||||
import re
|
||||
import requests
|
||||
import sys
|
||||
import time
|
||||
import urllib
|
||||
import urlparse
|
||||
from io import IOBase
|
||||
@@ -402,6 +404,10 @@ class Requester:
|
||||
|
||||
self.__log(verb, url, requestHeaders, input, status, responseHeaders, output)
|
||||
|
||||
if status == 202 and (verb == 'GET' or verb == 'HEAD'): # only for requests that are considered 'safe' in RFC 2616
|
||||
time.sleep(Consts.PROCESSING_202_WAIT_TIME)
|
||||
return self.__requestRaw(original_cnx, verb, url, requestHeaders, input)
|
||||
|
||||
if status == 301 and 'location' in responseHeaders:
|
||||
return self.__requestRaw(original_cnx, verb, responseHeaders['location'], requestHeaders, input)
|
||||
|
||||
|
||||
+55
-1
File diff suppressed because one or more lines are too long
@@ -1,55 +0,0 @@
|
||||
https
|
||||
GET
|
||||
api.github.com
|
||||
None
|
||||
/repos/jacquev6/PyGithub/stats/contributors
|
||||
{'Authorization': 'Basic login_and_password_removed', 'User-Agent': 'PyGithub/Python'}
|
||||
None
|
||||
202
|
||||
[('status', '202 Accepted'), ('x-ratelimit-remaining', '4965'), ('x-github-media-type', 'github.beta; format=json'), ('x-content-type-options', 'nosniff'), ('access-control-expose-headers', 'ETag, Link, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes'), ('x-github-request-id', '4C79374B:3446:13B76A5:528030E9'), ('content-length', '2'), ('server', 'GitHub.com'), ('x-ratelimit-limit', '5000'), ('access-control-allow-credentials', 'true'), ('date', 'Mon, 11 Nov 2013 01:20:42 GMT'), ('access-control-allow-origin', '*'), ('content-type', 'application/json; charset=utf-8'), ('x-ratelimit-reset', '1384134844')]
|
||||
{}
|
||||
|
||||
https
|
||||
GET
|
||||
api.github.com
|
||||
None
|
||||
/repos/jacquev6/PyGithub/stats/commit_activity
|
||||
{'Authorization': 'Basic login_and_password_removed', 'User-Agent': 'PyGithub/Python'}
|
||||
None
|
||||
202
|
||||
[('status', '202 Accepted'), ('x-ratelimit-remaining', '4964'), ('x-github-media-type', 'github.beta; format=json'), ('x-content-type-options', 'nosniff'), ('access-control-expose-headers', 'ETag, Link, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes'), ('x-github-request-id', '4C79374B:3448:429A229:528030EA'), ('content-length', '2'), ('server', 'GitHub.com'), ('x-ratelimit-limit', '5000'), ('access-control-allow-credentials', 'true'), ('date', 'Mon, 11 Nov 2013 01:20:42 GMT'), ('access-control-allow-origin', '*'), ('content-type', 'application/json; charset=utf-8'), ('x-ratelimit-reset', '1384134844')]
|
||||
{}
|
||||
|
||||
https
|
||||
GET
|
||||
api.github.com
|
||||
None
|
||||
/repos/jacquev6/PyGithub/stats/code_frequency
|
||||
{'Authorization': 'Basic login_and_password_removed', 'User-Agent': 'PyGithub/Python'}
|
||||
None
|
||||
202
|
||||
[('status', '202 Accepted'), ('x-ratelimit-remaining', '4963'), ('x-github-media-type', 'github.beta; format=json'), ('x-content-type-options', 'nosniff'), ('access-control-expose-headers', 'ETag, Link, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes'), ('x-github-request-id', '4C79374B:3448:429A284:528030EA'), ('content-length', '2'), ('server', 'GitHub.com'), ('x-ratelimit-limit', '5000'), ('access-control-allow-credentials', 'true'), ('date', 'Mon, 11 Nov 2013 01:20:42 GMT'), ('access-control-allow-origin', '*'), ('content-type', 'application/json; charset=utf-8'), ('x-ratelimit-reset', '1384134844')]
|
||||
{}
|
||||
|
||||
https
|
||||
GET
|
||||
api.github.com
|
||||
None
|
||||
/repos/jacquev6/PyGithub/stats/participation
|
||||
{'Authorization': 'Basic login_and_password_removed', 'User-Agent': 'PyGithub/Python'}
|
||||
None
|
||||
200
|
||||
[('status', '202 Accepted'), ('x-ratelimit-remaining', '4962'), ('x-github-media-type', 'github.beta; format=json'), ('x-content-type-options', 'nosniff'), ('access-control-expose-headers', 'ETag, Link, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes'), ('x-github-request-id', '4C79374B:3447:29BC88A:528030EB'), ('access-control-allow-credentials', 'true'), ('vary', 'Accept, Authorization, Cookie, Accept-Encoding'), ('content-length', '260'), ('server', 'GitHub.com'), ('x-ratelimit-limit', '5000'), ('etag', '"a896655765faac08fb15ce0da319416c"'), ('cache-control', 'private, max-age=60, s-maxage=60'), ('date', 'Mon, 11 Nov 2013 01:20:43 GMT'), ('access-control-allow-origin', '*'), ('content-type', 'application/json; charset=utf-8'), ('x-ratelimit-reset', '1384134844')]
|
||||
{}
|
||||
|
||||
https
|
||||
GET
|
||||
api.github.com
|
||||
None
|
||||
/repos/jacquev6/PyGithub/stats/punch_card
|
||||
{'Authorization': 'Basic login_and_password_removed', 'User-Agent': 'PyGithub/Python'}
|
||||
None
|
||||
200
|
||||
[('status', '202 Accepted'), ('x-ratelimit-remaining', '4961'), ('x-github-media-type', 'github.beta; format=json'), ('x-content-type-options', 'nosniff'), ('access-control-expose-headers', 'ETag, Link, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes'), ('x-github-request-id', '4C79374B:3448:429A33C:528030EB'), ('access-control-allow-credentials', 'true'), ('vary', 'Accept, Authorization, Cookie, Accept-Encoding'), ('content-length', '1490'), ('server', 'GitHub.com'), ('x-ratelimit-limit', '5000'), ('etag', '"41cbe788b8174e5a98906512e68a825d"'), ('cache-control', 'private, max-age=60, s-maxage=60'), ('date', 'Mon, 11 Nov 2013 01:20:43 GMT'), ('access-control-allow-origin', '*'), ('content-type', 'application/json; charset=utf-8'), ('x-ratelimit-reset', '1384134844')]
|
||||
{}
|
||||
|
||||
@@ -674,17 +674,7 @@ class Repository(Framework.TestCase):
|
||||
def testUnsubscribePubSubHubbub(self):
|
||||
self.repo.unsubscribe_from_hub("push", "http://requestb.in/1bc1sc61")
|
||||
|
||||
def testStatisticsBeforeCaching(self):
|
||||
self.assertEqual(self.repo.get_stats_contributors(), None)
|
||||
self.assertEqual(self.repo.get_stats_commit_activity(), None)
|
||||
self.assertEqual(self.repo.get_stats_code_frequency(), None)
|
||||
# ReplayData for those last two get_stats is forged because I was not
|
||||
# able to find a repo where participation and punch_card had never been
|
||||
# computed, and pushing to master did not reset the cache for them
|
||||
self.assertEqual(self.repo.get_stats_participation(), None)
|
||||
self.assertEqual(self.repo.get_stats_punch_card(), None)
|
||||
|
||||
def testStatisticsAfterCaching(self):
|
||||
def testStatistics(self):
|
||||
stats = self.repo.get_stats_contributors()
|
||||
seenJacquev6 = False
|
||||
for s in stats:
|
||||
|
||||
Reference in New Issue
Block a user