Created
October 1, 2016 22:34
-
-
Save sxlijin/b4ad4361fd78712d45dccd7da2d7b9d4 to your computer and use it in GitHub Desktop.
Demo of how to access the protected branches API (currently in preview) with Python.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
""" | |
Demo of how to access the protected branches API, currently in preview. | |
See https://developer.github.com/changes/2016-06-27-protected-branches-api-update/ | |
Note that you get a 404 if you attempt to get the protection of a branch on a | |
repo that your token actually works for (it's not well-defined behavior, but | |
it's what happens). | |
Note that for this to work on non-unix systems, AUTH_TOKEN must be set. | |
""" | |
import argparse, json, requests, subprocess | |
AUTH_TOKEN=None | |
def get_auth_token(): | |
""" | |
Returns AUTH_TOKEN if AUTH_TOKEN is not None; if AUTH_TOKEN is None, gets | |
OAuth token from git-credential. | |
""" | |
if AUTH_TOKEN is not None: | |
return AUTH_TOKEN | |
command = ' | '.join(('git credential fill <<< "host=github.com"', | |
'grep -o "password=\w\+"', | |
'cut -d= -f2' | |
)) | |
return subprocess.check_output(command, shell=True).strip().decode('utf-8') | |
def make_api_url(*args): | |
""" | |
Concatenates *args to make a path to access the GitHub API. | |
""" | |
return '/'.join(('https://api.github.com', 'repos', *args)) | |
def make_api_headers(): | |
""" | |
Returns a dict representing the headers needed to access the GH API. | |
""" | |
APPLICATION_HEADER_VALUE='application/vnd.github.loki-preview+json' | |
return { | |
'Authorization': 'token {:s}'.format(get_auth_token()), | |
'Accept': APPLICATION_HEADER_VALUE, | |
} | |
def get_branches(target_repo): | |
""" | |
Returns the <response> corresponding to the response from the GH API | |
endpoint which lists the branches in a $target_repo. | |
""" | |
url = make_api_url(target_repo, 'branches') | |
return requests.get(url, headers=make_api_headers()) | |
def get_protection(target_repo, branch): | |
""" | |
Returns the <response> corresponding to the response from the GH API | |
endpoint which lists the protection status of $branch in $target_repo. | |
""" | |
url = make_api_url(target_repo, 'branches', branch, 'protection') | |
return requests.get(url, headers=make_api_headers()) | |
def set_protection(target_repo, branch, data=None): | |
""" | |
Sets protections on $branch in $target_repo, where $data is the JSON that | |
sent in a PUT request to the corresponding GH API endpoint. | |
If $data is not specified, it defaults to no required status checks, and | |
saying restricting permissions to no users/teams (note that admins can | |
still push to the branch even when restrictions are so set). | |
Returns the <response> corresponding to the response from the GH API | |
endpoint. | |
""" | |
url = make_api_url(target_repo, 'branches', branch, 'protection') | |
if data is None: | |
data = { | |
'required_status_checks': None, | |
'restrictions': { | |
'users': [], | |
'teams': [], | |
}, | |
} | |
return requests.put(url, headers=make_api_headers(), json=data) | |
def delete_protection(target_repo, branch): | |
""" | |
Returns the <response> corresponding to the response from the GH API | |
endpoint which deletes the protection status of $branch in $target_repo. | |
""" | |
url = make_api_url(target_repo, 'branches', branch, 'protection') | |
return requests.delete(url, headers=make_api_headers()) | |
def main(): | |
parser = argparse.ArgumentParser(description = __doc__) | |
parser.add_argument( | |
'target_repo', | |
help='the target repository (specify as either org/repo or repo)' | |
) | |
parser.add_argument( | |
'target_branch', | |
help='the target branch' | |
) | |
parser.add_argument( | |
'action', | |
choices=['get', 'set', 'delete'], | |
help='action to perform on branch protections' | |
) | |
def do_and_print_json(fxn, *args): | |
print( | |
json.dumps( | |
fxn(*args).json(), | |
sort_keys=True, | |
indent=2 | |
) | |
) | |
{ | |
'get': lambda *args: do_and_print_json(get_protection, *args), | |
'set': lambda *args: do_and_print_json(set_protection, *args), | |
'delete': delete_protection, | |
}[parser.parse_args().action]( | |
parser.parse_args().target_repo, | |
parser.parse_args().target_branch | |
) | |
if __name__ == "__main__": | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment