GitHub REST API概要
PyGitHubライブラリ、Personal access token、APIレート制限を学びます。
「GitHub REST API概要」はCoddyKit上の無料AI Agentsレッスンです。 これはレッスン1/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはAI Agents学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 AI Agentsコースには全4レッスンが含まれています。
PyGitHub — Python用GitHubクライアント
PyGitHubは、GitHub REST API向けの最も広く使われているPythonライブラリです。生のHTTP APIを、リポジトリ、issue、PR、コミット、ユーザーを表すPythonオブジェクトで扱えるようにラップしています。GitHubの自動化タスクのほとんどは、Github(token=)とg.get_repo()から始まります。
# Install: pip install PyGitHub
from github import Github
import os
# Authenticate with a personal access token
g = Github(token=os.environ['GITHUB_TOKEN'])
# Get the authenticated user
user = g.get_user()
print(f'Logged in as: {user.login}')
print(f'Name: {user.name}')
print(f'Public repos: {user.public_repos}')
# Get a specific repository
repo = g.get_repo('octocat/Hello-World')
print(f'Repo: {repo.full_name}')
print(f'Stars: {repo.stargazers_count}')認証: Personal Access Token
最も簡単な認証方法はPersonal Access Token (PAT)です。これはGitHubアカウントに紐づく長期間有効なトークンです。github.com → Settings → Developer settings → Personal access tokensから作成できます。環境変数に保存し、コード内には決して記述しないでください。セキュリティを高めるため、対象を特定のリポジトリに限定できるfine-grained PATを使用してください。
from github import Github, Auth
import os
# Method 1: Classic token (works with PyGitHub)
token = os.environ['GITHUB_TOKEN']
g = Github(token=token)
# Method 2: Auth object (recommended for PyGitHub >= 1.59)
auth = Auth.Token(os.environ['GITHUB_TOKEN'])
g = Github(auth=auth)
# Test authentication
try:
user = g.get_user()
print(f'Authenticated as {user.login}')
except Exception as e:
print(f'Auth failed: {e}')
print('Check: Is GITHUB_TOKEN set? Has it expired?')
g.close() # close the connection when doneGitHub App認証
本番環境のエージェントには、PATよりもGitHub Appsが適しています。きめ細かな権限を設定でき、特定のリポジトリにインストールできるほか、自動的にローテーションされる短期間有効なインストールトークンを使用します。github.GithubIntegrationを使ってインストールトークンを生成してください。
import os
import github
APP_ID = os.environ['GITHUB_APP_ID']
PRIVATE_KEY = os.environ['GITHUB_APP_PRIVATE_KEY'] # PEM content
INSTALLATION_ID = os.environ['GITHUB_INSTALLATION_ID']
# Create GitHub App client
auth = github.Auth.AppAuth(APP_ID, PRIVATE_KEY)
gi = github.GithubIntegration(auth=auth)
# Get installation access token (expires in 1 hour)
installation = gi.get_installation(int(INSTALLATION_ID))
access_token = gi.get_access_token(int(INSTALLATION_ID))
# Use the token with a standard Github client
g = github.Github(token=access_token.token)
print(f'App authenticated, token expires: {access_token.expires_at}')レート制限: 1時間あたり5,000リクエスト
GitHub REST APIでは、認証済みユーザーは1時間あたり5,000リクエストまで利用できます。各API呼び出し(ページネーションされたものも含む)がカウントされます。バッチ処理を実行する前に残りのクォータを確認してください。使い切ると、レート制限がリセットされるまで、すべてのリクエストが403 Forbiddenを返します。
from github import Github
import os
g = Github(token=os.environ['GITHUB_TOKEN'])
# Check current rate limit status
rate_limit = g.get_rate_limit()
core = rate_limit.core
print(f'Remaining: {core.remaining}/{core.limit} requests')
print(f'Resets at: {core.reset}')
# Calculate time until reset
import datetime
now = datetime.datetime.utcnow()
reset_in = (core.reset.replace(tzinfo=None) - now).seconds
print(f'Reset in: {reset_in // 60}m {reset_in % 60}s')
# Check before heavy operations
if core.remaining < 100:
print('WARNING: Rate limit nearly exhausted!')リポジトリオブジェクトの取得
repoオブジェクトは、ほぼすべてのGitHub操作の出発点です。g.get_repo('owner/name')で取得できます。メタデータ(スター数、フォーク数、説明、公開範囲)と、issue、PR、コミット、リリースなどにアクセスするためのメソッドが含まれています。
from github import Github
import os
g = Github(token=os.environ['GITHUB_TOKEN'])
repo = g.get_repo('myorg/myrepo')
# Repository metadata
print(f'Full name: {repo.full_name}')
print(f'Description: {repo.description}')
print(f'Default branch: {repo.default_branch}')
print(f'Stars: {repo.stargazers_count}')
print(f'Forks: {repo.forks_count}')
print(f'Open issues: {repo.open_issues_count}')
print(f'Private: {repo.private}')
print(f'Language: {repo.language}')
print(f'Created: {repo.created_at}')
print(f'Last push: {repo.pushed_at}')APIのページネーション — PaginatedList
多数の項目(issue、コミット、PR)を返すGitHub API呼び出しは、PaginatedListを返します。通常のリストと同じように反復処理でき、反復に合わせてPyGitHubがページを自動的に取得します。ただし、PaginatedListに対してlen()を呼び出すとすべてのページが取得されるため、コストが高くなる場合があります。
from github import Github
import os
g = Github(token=os.environ['GITHUB_TOKEN'])
repo = g.get_repo('myorg/myrepo')
# PaginatedList: fetch pages lazily as you iterate
issues = repo.get_issues(state='open') # returns PaginatedList
# Iterate — fetches pages 30 at a time automatically
for issue in issues:
print(f'#{issue.number}: {issue.title}')
# Get first N items without fetching everything
first_10 = list(issues[:10]) # only fetches first page
# Count (WARNING: fetches ALL pages)
total_open = issues.totalCount # uses the count from API metadata, not iterationレート制限例外の処理
レート制限を超えると、PyGitHubはgithub.GithubException.RateLimitExceededExceptionを発生させます。リセット時刻を確認し、制限がリセットされるまでスリープして対処してください。これをリトライ用ラッパーに組み込むと、GitHubへのあらゆる呼び出しを堅牢にできます。
from github import Github
from github.GithubException import RateLimitExceededException
import os
import time
import datetime
g = Github(token=os.environ['GITHUB_TOKEN'])
def github_call_with_rate_limit(func, *args, **kwargs):
while True:
try:
return func(*args, **kwargs)
except RateLimitExceededException:
rate_limit = g.get_rate_limit()
reset_time = rate_limit.core.reset.replace(tzinfo=None)
now = datetime.datetime.utcnow()
wait_seconds = (reset_time - now).total_seconds() + 10
print(f'Rate limit exceeded. Sleeping {wait_seconds:.0f}s until reset...')
time.sleep(max(wait_seconds, 1))
# Usage
repo = github_call_with_rate_limit(
g.get_repo, 'myorg/myrepo'
)GitHub全体の検索
g.search_issues()、g.search_repositories()、g.search_code()を使うと、すべての公開リポジトリ(および自分のプライベートリポジトリ)を対象にGitHub検索を実行できます。これらはSearch APIを使用し、1分あたり30リクエストという独立したレート制限が適用されます。
from github import Github
import os
g = Github(token=os.environ['GITHUB_TOKEN'])
# Search issues across all your repos
results = g.search_issues(
query='is:open is:issue label:bug user:myorg',
sort='created',
order='desc'
)
print(f'Found {results.totalCount} open bugs')
for issue in results[:10]:
print(f'{issue.repository.full_name}#{issue.number}: {issue.title}')
# Search for repos using a specific package
repos = g.search_repositories(
query='topic:machine-learning language:python stars:>100'
)
for repo in repos[:5]:
print(f'{repo.full_name}: {repo.stargazers_count} stars')複数のリポジトリの操作
エージェントは、組織内の複数のリポジトリを横断して処理する必要があることがよくあります。g.get_organization()で組織内のすべてのリポジトリを一覧取得し、ループで処理してください。言語、アーカイブ済みかどうか、活動日時で絞り込むと、活動していないリポジトリを処理せずに済みます。
from github import Github
import os
import datetime
g = Github(token=os.environ['GITHUB_TOKEN'])
org = g.get_organization('myorg')
# Get all active Python repos
cutoff = datetime.datetime.now() - datetime.timedelta(days=180)
active_repos = [
repo
for repo in org.get_repos(type='all')
if (
not repo.archived
and repo.language == 'Python'
and repo.pushed_at
and repo.pushed_at.replace(tzinfo=None) > cutoff
)
]
print(f'Active Python repos: {len(active_repos)}')
for repo in active_repos[:5]:
print(f' {repo.name}: last push {repo.pushed_at.date()}')リポジトリからのファイル内容の読み取り
repo.get_contents(path)を使うと、リポジトリ内の任意のファイルを読み取れます。内容はbase64でエンコードされていますが、PyGitHubが.decoded_contentプロパティを通じて自動的にデコードします。refパラメーターでブランチまたはコミットSHAを指定してください。
from github import Github
import os
g = Github(token=os.environ['GITHUB_TOKEN'])
repo = g.get_repo('myorg/myrepo')
# Read a file from the default branch
contents = repo.get_contents('README.md')
readme_text = contents.decoded_content.decode('utf-8')
print(f'README ({len(readme_text)} chars):')
print(readme_text[:200])
# Read from a specific branch
requirements = repo.get_contents(
'requirements.txt',
ref='feature/new-deps'
)
deps = requirements.decoded_content.decode('utf-8')
print('Dependencies:', deps[:300])一般的なGitHub例外のエラー処理
PyGitHubは、すべてのAPIエラーに対してGithubExceptionを発生させます。一般的なサブクラスには、UnknownObjectException(404 — リポジトリまたはissueが見つからない)、BadCredentialsException(401 — トークンが不正)、RateLimitExceededException(403 — レート制限超過)があります。これらは必ず個別に捕捉してください。
from github import Github
from github.GithubException import (
GithubException, UnknownObjectException,
BadCredentialsException, RateLimitExceededException
)
import os
g = Github(token=os.environ['GITHUB_TOKEN'])
def get_repo_safely(repo_full_name):
try:
return g.get_repo(repo_full_name)
except BadCredentialsException:
print('ERROR: GitHub token is invalid or expired')
return None
except UnknownObjectException:
print(f'ERROR: Repo not found: {repo_full_name}')
print('Check: typo in name? Private repo you can\'t access?')
return None
except RateLimitExceededException:
print('ERROR: GitHub rate limit exceeded, retry later')
return None
except GithubException as e:
print(f'GitHub API error {e.status}: {e.data}')
return Noneクイックチェック: レート制限
GitHub APIのレート制限についての理解度を確認しましょう。
GitHub REST APIの振り返り
これで、PyGitHubを使ってGitHubに接続できるようになりました:
- PAT認証にはGithub(token=)またはGithub(auth=Auth.Token(...))を使用します
- きめ細かな権限が必要な本番環境のエージェントには、
GithubIntegrationを使ったGitHub Appsを使用します - レート制限: 5,000 req/hr。
g.get_rate_limit()で確認し、RateLimitExceededExceptionを処理します - PaginatedList: 遅延方式で反復処理します。すべてのページを取得せずに件数を得るには
.totalCountを使用します - g.get_repo('owner/name') — リポジトリレベルの操作の入口です
UnknownObjectException(404)とBadCredentialsException(401)は明示的に捕捉します
よくある質問
「GitHub REST API概要」レッスンは無料ですか?
はい。「GitHub REST API概要」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、AI Agentsコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 AI Agentsコースには全4レッスンが含まれています。
「GitHub REST API概要」で何を学びますか?
PyGitHubライブラリ、Personal access token、APIレート制限を学びます。 ブラウザで直接実行するハンズオンコードでAI Agentsを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
AI Agentsを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのAI Agentsは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン1/4です。
「GitHub REST API概要」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このAI Agentsレッスンでコードを書いて実行できますか?
はい。すべてのAI Agentsレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- GitHub REST API概要
- Issueの一覧表示と管理
- PRレビューコメントの自動化
- コミット履歴と差分の分析