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