github.com/yrj2011/jx-test-infra@v0.0.0-20190529031832-7a2065ee98eb/experiment/graphql_issue_example.py (about) 1 #!/usr/bin/env python 2 3 # Copyright 2017 The Kubernetes Authors. 4 # 5 # Licensed under the Apache License, Version 2.0 (the "License"); 6 # you may not use this file except in compliance with the License. 7 # You may obtain a copy of the License at 8 # 9 # http://www.apache.org/licenses/LICENSE-2.0 10 # 11 # Unless required by applicable law or agreed to in writing, software 12 # distributed under the License is distributed on an "AS IS" BASIS, 13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 # See the License for the specific language governing permissions and 15 # limitations under the License. 16 17 # USAGE: find_issues.py <github_token> 18 from __future__ import print_function 19 20 import sys 21 import json 22 import argparse 23 24 import requests 25 26 GITHUB_API_URL = "https://api.github.com" 27 28 29 def do_github_graphql_request(query, token, variables=None): 30 """performs a requests.put with the correct headers for a GitHub request. 31 32 see: https://developer.github.com/v4/ 33 34 Args: 35 query: the graphQL query string (excluding the variables section) 36 token: a GitHub API token string 37 variables: a dict of key=value variables that will be sent with the query 38 39 Returns: 40 A requests.Response object 41 """ 42 url = "https://api.github.com/graphql" 43 headers = { 44 "Authorization": "bearer " + token, 45 } 46 data = json.dumps({"query": query, "variables": json.dumps(variables)}) 47 return requests.post(url, headers=headers, data=data) 48 49 50 ISSUES_QUERY = """ 51 query($owner:String!, $name:String!, $after:String) { 52 repository(owner:$owner, name:$name) { 53 issues(first:100, after:$after) { 54 nodes{ 55 number 56 title 57 state 58 createdAt 59 labels(first:100){ 60 nodes{ 61 name 62 } 63 } 64 assignees(first:100){ 65 nodes{ 66 login 67 } 68 } 69 } 70 pageInfo{ 71 hasNextPage 72 endCursor 73 } 74 } 75 } 76 rateLimit { 77 limit 78 cost 79 remaining 80 resetAt 81 } 82 } 83 """ 84 85 def get_issues(owner, name, token, after=None): 86 """returns the result of do_github_graphql_request for a repo issues query. 87 88 This query requests the first 100 issues for a repo with the first 100 89 assignee logins and labels as well as the issue title, number, state, 90 creation time and the pageInfo for getting the next page of results 91 92 Args: 93 owner: the GitHub repo owner as in github.com/kubernetes/test-infra -> 94 owner="kubernetes" 95 name: this GitHub repo name as in github.com.kubernetes/test-infra -> 96 name = "test-infra" 97 token: a GitHub API token string 98 after: this should be None or the endCursor from pageInfo 99 100 Returns: 101 A requests.Response object 102 """ 103 variables = {"owner": owner, "name": name} 104 if after is not None: 105 variables["after"] = after 106 return do_github_graphql_request(ISSUES_QUERY, token, variables) 107 108 109 def get_all_issues(owner, name, token, issue_func, show_progress=False): 110 """gets all issues for a repo and applies issue_func to each. 111 112 Args: 113 owner: the GitHub repo owner as in github.com/kubernetes/test-infra -> 114 owner="kubernetes" 115 name: this GitHub repo name as in github.com.kubernetes/test-infra -> 116 name = "test-infra" 117 token: a GitHub API token string 118 issue_func: a function that takes one argument (the json of each issue) 119 this will be applied to each issue object returned by the GitHub API 120 show_progress: if True then print '.' for each request made 121 122 Raises: 123 IOError: an error occurred while getting the issues 124 """ 125 response = get_issues(owner, name, token) 126 while True: 127 if show_progress: 128 print(".", end="") 129 sys.stdout.flush() 130 if response.status_code != 200: 131 raise IOError("failed to fetch issues for repo: %s/%s" % (owner, name)) 132 response_json = response.json() 133 # NOTE: this will also contain the rate limit info if we need that later 134 # https://developer.github.com/v4/guides/resource-limitations/ 135 data = response_json["data"] 136 issues = data["repository"]["issues"]["nodes"] 137 for entry in issues: 138 issue_func(entry) 139 page_info = data["repository"]["issues"]["pageInfo"] 140 if not page_info["hasNextPage"]: 141 break 142 response = get_issues(owner, name, token, page_info["endCursor"]) 143 144 145 def main(): 146 parser = argparse.ArgumentParser() 147 parser.add_argument('--org', default='kubernetes') 148 parser.add_argument('--repo', default='test-infra') 149 parser.add_argument('token', help='GitHub auth token.') 150 options = parser.parse_args() 151 print("getting issues for: %s/%s" % (options.org, options.repo)) 152 # TODO: replace this with with something more useful? 153 def issue_func(issue): 154 print(issue) 155 get_all_issues(options.org, options.repo, options.token, issue_func) 156 print("done") 157 158 159 if __name__ == "__main__": 160 main()