8000 Initial commit for issues/585. · sigmavirus24/github3.py@a32860f · GitHub
[go: up one dir, main page]

Skip to content

Commit a32860f

Browse files
Initial commit for issues/585.
Resolves #585 This reduces user rate limiting when a 304 response is returned
1 parent 872c813 commit a32860f

File tree

6 files changed

+131
-0
lines changed

6 files changed

+131
-0
lines changed

github3/repos/branch.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,26 @@ def _update_attributes(self, branch):
3838
def _repr(self):
3939
return '<Repository Branch [{0}]>'.format(self.name)
4040

41+
def latest_sha(self, differs_from=''):
42+
"""Check if SHA-1 is the same as remote branch
43+
44+
See: https://git.io/vaqIw
45+
46+
:param differs_from string: (optional), sha to compare against
47+
:returns: strring of the SHA or None
48+
"""
49+
# If-None-Match returns 200 instead of 304 value does not have quotes
50+
headers = {
51+
'Accept': 'application/vnd.github.chitauri-preview+sha',
52+
'If-None-Match': '"{0}"'.format(differs_from)
53+
}
54+
base = self._api.split('/branches', 1)[0]
55+
url = self._build_url('commits', self.name, base_url=base)
56+
resp = self._get(url, headers=headers)
57+
if resp:
58+
sha = None if self._boolean(resp, 304, 200) else resp.content
59+
return sha
60+
4161
def protect(self, enforcement=None, status_checks=None):
4262
"""Enable force push protection and configure status check enforcement.
4363
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"http_interactions": [{"request": {"body": {"string": "", "encoding": "utf-8"}, "headers": {"Accept-Encoding": "gzip, deflate", "Accept": "application/vnd.github.loki-preview+json", "User-Agent": "github3.py/1.0.0a4", "Accept-Charset": "utf-8", "Connection": "keep-alive", "Content-Type": "application/json"}, "method": "GET", "uri": "https://api.github.com/repos/sigmavirus24/github3.py/branches/develop"}, "response": {"body": {"string": "", "base64_string": "H4sIAAAAAAAAA+1XTY/TMBD9K1G47m6c76QSAokTAm5wAVaVY08Si8QOtlNYqv53xmm72xYQTRdx2luVet68eZ4vr31Je/AXPocVdGrwr3ym+l5Yf7H2TUvxnyKPWBHGdV3lNCGszFgcpRHPswSSIi6SJClJSnl5ZEpH2yrtQHb4r6n0XinNqWEKT0JPRYfgRjQ9XQk9mih5ORrQ5kYqDUN3d9MI247VDdLB85xaxzIiYXZN4msSvg/LRZouwvCjv9lztvD/PPZgDG0cp3egG/CGses8DV9HMNZ7lhaJV2vVe+/evtEjNKDDssiDncif5Wf5YXAhcY8rZqwWsjGeVV5LV+DZFjwtmtZ6o+68WunpCx4ce5CWWqEkKmI1oPf9JYU1lBGPSJ4ygCSrirCiZVxHJCtoWcVpGPI0JGWOhgiKrFtrB7MIAjqIA6UDlF6Z4PBWgu09xDfDnfsZOL8mONsfXs4jHW7z0QQz8xClWjI1Ssxk8jgSFxBobd8tj+N+SOc/yrt1dEGg5sTXrEudG17gDFBdg7n0UOadaoQ8KWg8ILi/iBJSxAQPr6il+pTq9NHsctB1AKakRXhX+MEYbI1frJ7HiNboHYaD9f+Wy1M7ORIbLc6/GTxcq65T3xDllPRx0fzqKLi3vEfBEr8QBS3XgcIegNphSBsnhDB2PqnJao1VbOxScIdjUHsNfDaxnR3S+iaR0XrqGxPgWBmmxeCa1HyCR9aIpnRDpfgxtbz5aGjtcnRqabMjnKzQGscipvps863ZOhi0WFF256TRwECsUOwLIU/sEdHeDW4AfcCkcNILC0vKe1eGNe0MnM7FpxI9mmtPJXpJUT2V6G4pDX7T9S8p0YHqaZguPu13OVweq4jxkpdhDCnJKG69CSdFlvI0SouCZyXLeARY849YrfZjf4a382fn4dK422rO9rO52gvBKI9JWVAKhEesInGaFzxnSQgh5JDWhNGsikv+b4SY4e1RQpztZ3OLHXzZCfkFswM1ga6+dHGvNJWsxb394ZnnYjiAO2M9dZv/PQBSG7SywKbnCNIDSasOcC+z+OBx0+7rKNxqgauCHc0SvbNtHCDxScPArZDLzr06kYVUcju63MidFsDvU0lMv4Uc1WiuBX7FBdD5w0cIPhrNNRP+7Waz+Qkez2dHxQ4AAA==", "encoding": "utf-8"}, "headers": {"vary": "Accept", "x-github-media-type": "github.loki-preview; format=json", "x-xss-protection": "1; mode=block", "x-content-type-options": "nosniff", "etag": "W/\"30b5e0e1742d28983cbab707d60d71af\"", "cache-control": "public, max-age=60, s-maxage=60", "status": "200 OK", "x-ratelimit-remaining": "34", "x-served-by": "8a5c38021a5cd7cef7b8f49a296fee40", "access-control-expose-headers": "ETag, Link, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval", "transfer-encoding": "chunked", "x-github-request-id": "BCDD0B45:10EA0:94350ED:56E27045", "date": "Fri, 11 Mar 2016 07:14:13 GMT", "access-control-allow-origin": "*", "content-security-policy": "default-src 'none'", "content-encoding": "gzip", "strict-transport-security": "max-age=31536000; includeSubdomains; preload", "server": "GitHub.com", "x-ratelimit-limit": "60", "x-frame-options": "deny", "content-type": "application/json; charset=utf-8", "x-ratelimit-reset": "1457683267"}, "status": {"message": "OK", "code": 200}, "url": "https://api.github.com/repos/sigmavirus24/github3.py/branches/develop"}, "recorded_at": "2016-03-11T07:14:13"}, {"request": {"body": {"string": "", "encoding": "utf-8"}, "headers": {"Accept-Encoding": "gzip, deflate", "Accept": "application/vnd.github.chitauri-preview+sha", "User-Agent": "github3.py/1.0.0a4", "Accept-Charset": "utf-8", "Connection": "keep-alive", "If-None-Match": "\"872c813ffb7a40c96c3252d764e4838444905ad9\"", "Content-Type": "application/json"}, "method": "GET", "uri": "https://api.github.com/repos/sigmavirus24/github3.py/commits/develop"}, "response": {"body": {"string": "", "encoding": null}, "headers": {"status": "304 Not Modified", "x-ratelimit-remaining": "34", "x-xss-protection": "1; mode=block", "x-content-type-options": "nosniff", "content-security-policy": "default-src 'none'", "access-control-expose-headers": "ETag, Link, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval", "x-github-request-id": "BCDD0B45:10EA0:943510C:56E27045", "strict-transport-security": "max-age=31536000; includeSubdomains; preload", "vary": "Accept", "server": "GitHub.com", "last-modified": "Tue, 01 Mar 2016 19:55:11 GMT", "x-ratelimit-limit": "60", "etag": "\"872c813ffb7a40c96c3252d764e4838444905ad9\"", "x-served-by": "8a5c38021a5cd7cef7b8f49a296fee40", "cache-control": "public, max-age=60, s-maxage=60", "date": "Fri, 11 Mar 2016 07:14:13 GMT", "access-control-allow-origin": "*", "x-frame-options": "deny", "x-ratelimit-reset": "1457683267"}, "status": {"message": "Not Modified", "code": 304}, "url": "https://api.github.com/repos/sigmavirus24/github3.py/commits/develop"}, "recorded_at": "2016-03-11T07:14:13"}], "recorded_with": "betamax/0.5.0"}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"http_interactions": [{"request": {"body": {"string": "", "encoding": "utf-8"}, "headers": {"Accept-Encoding": "gzip, deflate", "Accept": "application/vnd.github.loki-preview+json", "User-Agent": "github3.py/1.0.0a4", "Accept-Charset": "utf-8", "Connection": "keep-alive", "Content-Type": "application/json"}, "method": "GET", "uri": "https://api.github.com/repos/sigmavirus24/github3.py/branches/develop"}, "response": {"body": {"string": "", "base64_string": "H4sIAAAAAAAAA+1XTY/TMBD9K1G47m6c76QSAokTAm5wAVaVY08Si8QOtlNYqv53xmm72xYQTRdx2luVet68eZ4vr31Je/AXPocVdGrwr3ym+l5Yf7H2TUvxnyKPWBHGdV3lNCGszFgcpRHPswSSIi6SJClJSnl5ZEpH2yrtQHb4r6n0XinNqWEKT0JPRYfgRjQ9XQk9mih5ORrQ5kYqDUN3d9MI247VDdLB85xaxzIiYXZN4msSvg/LRZouwvCjv9lztvD/PPZgDG0cp3egG/CGses8DV9HMNZ7lhaJV2vVe+/evtEjNKDDssiDncif5Wf5YXAhcY8rZqwWsjGeVV5LV+DZFjwtmtZ6o+68WunpCx4ce5CWWqEkKmI1oPf9JYU1lBGPSJ4ygCSrirCiZVxHJCtoWcVpGPI0JGWOhgiKrFtrB7MIAjqIA6UDlF6Z4PBWgu09xDfDnfsZOL8mONsfXs4jHW7z0QQz8xClWjI1Ssxk8jgSFxBobd8tj+N+SOc/yrt1dEGg5sTXrEudG17gDFBdg7n0UOadaoQ8KWg8ILi/iBJSxAQPr6il+pTq9NHsctB1AKakRXhX+MEYbI1frJ7HiNboHYaD9f+Wy1M7ORIbLc6/GTxcq65T3xDllPRx0fzqKLi3vEfBEr8QBS3XgcIegNphSBsnhDB2PqnJao1VbOxScIdjUHsNfDaxnR3S+iaR0XrqGxPgWBmmxeCa1HyCR9aIpnRDpfgxtbz5aGjtcnRqabMjnKzQGscipvps863ZOhi0WFF256TRwECsUOwLIU/sEdHeDW4AfcCkcNILC0vKe1eGNe0MnM7FpxI9mmtPJXpJUT2V6G4pDX7T9S8p0YHqaZguPu13OVweq4jxkpdhDCnJKG69CSdFlvI0SouCZyXLeARY849YrfZjf4a382fn4dK422rO9rO52gvBKI9JWVAKhEesInGaFzxnSQgh5JDWhNGsikv+b4SY4e1RQpztZ3OLHXzZCfkFswM1ga6+dHGvNJWsxb394ZnnYjiAO2M9dZv/PQBSG7SywKbnCNIDSasOcC+z+OBx0+7rKNxqgauCHc0SvbNtHCDxScPArZDLzr06kYVUcju63MidFsDvU0lMv4Uc1WiuBX7FBdD5w0cIPhrNNRP+7Waz+Qkez2dHxQ4AAA==", "encoding": "utf-8"}, "headers": {"vary": "Accept", "x-github-media-type": "github.loki-preview; format=json", "x-xss-protection": "1; mode=block", "x-content-type-options": "nosniff", "etag": "W/\"30b5e0e1742d28983cbab707d60d71af\"", "cache-control": "public, max-age=60, s-maxage=60", "status": "200 OK", "x-ratelimit-remaining": "32", "x-served-by": "a241e1a8264a6ace03db946c85b92db3", "access-control-expose-headers": "ETag, Link, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval", "transfer-encoding": "chunked", "x-github-request-id": "BCDD0B45:10E9F:A9A9D53:56E27046", "date": "Fri, 11 Mar 2016 07:14:14 GMT", "access-control-allow-origin": "*", "content-security-policy": "default-src 'none'", "content-encoding": "gzip", "strict-transport-security": "max-age=31536000; includeSubdomains; preload", "server": "GitHub.com", "x-ratelimit-limit": "60", "x-frame-options": "deny", "content-type": "application/json; charset=utf-8", "x-ratelimit-reset": "1457683267"}, "status": {"message": "OK", "code": 200}, "url": "https://api.github.com/repos/sigmavirus24/github3.py/branches/develop"}, "recorded_at": "2016-03-11T07:14:14"}, {"request": {"body": {"string": "", "encoding": "utf-8"}, "headers": {"Accept-Encoding": "gzip, deflate", "Accept": "application/vnd.github.chitauri-preview+sha", "User-Agent": "github3.py/1.0.0a4", "Accept-Charset": "utf-8", "Connection": "keep-alive", "If-None-Match": "\"fakesha\"", "Content-Type": "application/json"}, "method": "GET", "uri": "https://api.github.com/repos/sigmavirus24/github3.py/commits/develop"}, "response": {"body": {"string": "872c813ffb7a40c96c3252d764e4838444905ad9", "encoding": "utf-8"}, "headers": {"content-length": "40", "vary": "Accept", "x-github-media-type": "github.v3; param=chitauri-preview; format=sha", "x-xss-protection": "1; mode=block", "x-content-type-options": "nosniff", "etag": "\"872c813ffb7a40c96c3252d764e4838444905ad9\"", "cache-control": "public, max-age=60, s-maxage=60", "status": "200 OK", "x-ratelimit-remaining": "31", "x-served-by": "e183f7c661b1bbc2c987b3c4dc7b04e0", "access-control-expose-headers": "ETag, Link, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval", "x-github-request-id": "BCDD0B45:10E9F:A9A9D75:56E27046", "last-modified": "Tue, 01 Mar 2016 19:55:11 GMT", "date": "Fri, 11 Mar 2016 07:14:14 GMT", "access-control-allow-origin": "*", "content-security-policy": "default-src 'none'", "strict-transport-security": "max-age=31536000; includeSubdomains; preload", "server": "GitHub.com", "x-ratelimit-limit": "60", "x-frame-options": "deny", "content-type": "application/vnd.github.chitauri-preview+sha; charset=utf-8", "x-ratelimit-reset": "1457683267"}, "status": {"message": "OK", "code": 200}, "url": "https://api.github.com/repos/sigmavirus24/github3.py/commits/develop"}, "recorded_at": "2016-03-11T07:14:14"}], "recorded_with": "betamax/0.5.0"}

tests/integration/test_repos_branch.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,3 +52,23 @@ def test_unprotect(self):
5252
branch = next(repository.br 8000 anches(protected=True))
5353
branch.unprotect()
5454
assert branch.protection == expected
55+
56+
def test_latest_sha(self):
57+
repository = self.gh.repository('sigmavirus24', 'github3.py')
58+
cassette_name = self.cassette_name('latest_sha')
59+
with self.recorder.use_cassette(cassette_name):
60+
branch = repository.branch('develop')
61+
sha = '872c813ffb7a40c96c3252d764e4838444905ad9'
62+
latest_sha = branch.latest_sha(differs_from=sha)
63+
64+
assert latest_sha is None
65+
66+
def test_latest_sha_differs(self):
67+
repository = self.gh.repository('sigmavirus24', 'github3.py')
68+
cassette_name = self.cassette_name('latest_sha_differs')
69+
with self.recorder.use_cassette(cassette_name):
70+
branch = repository.branch('develop')
71+
sha = 'fakesha'
72+
latest_sha = branch.latest_sha(differs_from=sha)
73+
74+
assert isinstance(latest_sha, str)

tests/unit/json/repos_branch_example

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
{
2+
"name": "master",
3+
"protection": {
4+
"enabled": false,
5+
"required_status_checks": {
6+
"enforcement_level": "off",
7+
"contexts": [
8+
9+
]
10+
}
11+
},
12+
"commit": {
13+
"sha": "7fd1a60b01f91b314f59955a4e4d4e80d8edf11d",
14+
"commit": {
15+
"author": {
16+
"name": "The Octocat",
17+
"date": "2012-03-06T15:06:50-08:00",
18+
"email": "octocat@nowhere.com"
19+
},
20+
"url": "https://api.github.com/repos/octocat/Hello-World/git/commits/7fd1a60b01f91b314f59955a4e4d4e80d8edf11d",
21+
"message": "Merge pull request #6 from Spaceghost/patch-1\n\nNew line at end of file.",
22+
"tree": {
23+
"sha": "b4eecafa9be2f2006ce1b709d6857b07069b4608",
24+
"url": "https://api.github.com/repos/octocat/Hello-World/git/trees/b4eecafa9be2f2006ce1b709d6857b07069b4608"
25+
},
26+
"committer": {
27+
"name": "The Octocat",
28+
"date": "2012-03-06T15:06:50-08:00",
29+
"email": "octocat@nowhere.com"
30+
}
31+
},
32+
"author": {
33+
"gravatar_id": "",
34+
"avatar_url": "https://secure.gravatar.com/avatar/7ad39074b0584bc555d0417ae3e7d974?d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-140.png",
35+
"url": "https://api.github.com/users/octocat",
36+
"id": 583231,
37+
"login": "octocat"
38+
},
39+
"parents": [
40+
{
41+
"sha": "553c2077f0edc3d5dc5d17262f6aa498e69d6f8e",
42+
"url": "https://api.github.com/repos/octocat/Hello-World/commits/553c2077f0edc3d5dc5d17262f6aa498e69d6f8e"
43+
},
4 F438 4+
{
45+
"sha": "762941318ee16e59dabbacb1b4049eec22f0d303",
46+
"url": "https://api.github.com/repos/octocat/Hello-World/commits/762941318ee16e59dabbacb1b4049eec22f0d303"
47+
}
48+
],
49+
"url": "https://api.github.com/repos/octocat/Hello-World/commits/7fd1a60b01f91b314f59955a4e4d4e80d8edf11d",
50+
"committer": {
51+
"gravatar_id": "",
52+
"avatar_url": "https://secure.gravatar.com/avatar/7ad39074b0584bc555d0417ae3e7d974?d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-140.png",
53+
"url": "https://api.github.com/users/octocat",
54+
"id": 583231,
55+
"login": "octocat"
56+
}
57+
},
58+
"_links": {
59+
"html": "https://github.com/octocat/Hello-World/tree/master",
60+
"self": "https://api.github.com/repos/octocat/Hello-World/branches/master"
61+
}
62+
}

tests/unit/test_repos_branch.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
"""Unit tests for methods implemented on Branch."""
2+
import github3
3+
from . import helper
4+
5+
get_example_data = helper.create_example_data_helper('repos_branch_example')
6+
url_for = helper.create_url_helper(
7+
'https://api.github.com/repos/octocat/Hello-World/commits/master'
8+
)
9+
10+
11+
class TestBranch(helper.UnitHelper):
12+
"""Branch unit tests."""
13+
14+
described_class = github3.repos.branch.Branch
15+
example_data = get_example_data()
16+
17+
def test_latest_sha(self):
18+
"""Verify the request for retreiving the latest_sha."""
19+
headers = {
20+
'Accept': 'application/vnd.github.chitauri-preview+sha',
21+
'If-None-Match': '"123"'
22+
}
23+
self.instance.latest_sha(differs_from='123')
24+
self.session.get.assert_called_once_with(
25+
url_for(),
26+
headers=headers
27+
)

0 commit comments

Comments
 (0)
0