2021年9月30日木曜日

PythonでGitHubのGraphQL APIを使う

GitHubにはAPIがあってリポジトリの情報取得などができる。REST APIGraphQL APIが利用可能だが、ここではGraphQL APIをPythonで使ってみる。


環境


WSL2(Ubuntu20.04)。


Explorerでクエリの確認

GraphQLではクエリを使うが、ExplorerでGraphQL APIへのクエリを試せる。Pythonで実行する前にクエリの結果を確認するのに使える。

例としてGraphQLでの呼び出しの作成にあるクエリを実行してみる。このクエリではoctocat/Hello-Worldリポジトリのクローズ済み最新20のissueの情報を取得できる。

query {
  repository(owner:"octocat", name:"Hello-World") {
    issues(last:20, states:CLOSED) {
      edges {
        node {
          title
          url
          labels(first:5) {
            edges {
              node {
                name
              }
            }
          }
        }
      }
    }
  }
}

Explorer画面の左ペインに上記クエリをペーストし、三角矢印のアイコンをクリックするとクエリが実行され、右ペインに結果が表示される。



アクセストークンの生成

GraphQL APIの使用にはアクセストークンが必要なので生成する。GitHubにログインしたらSettings > Developer Settings > Personal access tokens > Generate new token でアクセストークンを生成する。この際にトークンの有効期限やスコープを設定する。生成したらコピーしておく。



PythonでGraphQL APIを使う

アクセストークンを取得したのでPythonでGraphQL APIを使ってみる。トークンは送信ヘッダーのAuthorizationにセットする。クエリの検索条件はsearchで指定する。以下のコードでは「pandas」というワードをリポジトリ名に含み、スターが500以上、言語がPythonというリポジトリを検索する。リポジトリの検索条件指定についてはリポジトリを検索するを参照。取得するデータは検索条件に合致したリポジトリの数と各リポジトリの情報。nodesに取得するリポジトリの情報を指定する。

import requests
import json

endpoint = 'https://api.github.com/graphql'
api_token = '生成したアクセストークン'
headers = {'Authorization': 'token ' + api_token}

query = """
{ 
  search(type: REPOSITORY, query: "pandas in:name stars:>=500 language:python sort:stars", first: 100)   {
    repositoryCount
    nodes {
      ... on Repository {
        id
        url
        name
        description
        stargazers {
          totalCount
        }
        forks {
          totalCount
        }
        createdAt
        updatedAt
      }
    }
  }
}
"""
r = requests.post(url=endpoint, json={'query': query}, headers=headers)

search_result = json.loads(r.text)['data']['search']

# リポジトリ数
repo_count = search_result['repositoryCount']
print('repositoryCount: ' + str(repo_count))

# リポジトリ名とスター数
nodes = search_result['nodes']
for n in nodes:
  print('\nname: ' + n.['name'])
  print('stargazers totalCount: ' + str(n['stargazers']['totalCount']))
以下のように検索条件に合致したリポジトリ数と各リポジトリの情報が取得できる。


0 件のコメント:

コメントを投稿