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()