GitHubリポジトリのファイル履歴を取得・分析するクラス
GitHubFileHistoryAnalyzer(access_token: str)パラメータ:
access_token(str): GitHub Personal Access Token
例:
analyzer = GitHubFileHistoryAnalyzer("ghp_xxxxxxxxxxxx")指定されたファイルのコミット履歴を取得します。
get_file_history(
repo_name: str,
file_path: str,
max_commits: Optional[int] = None
) -> List[CommitInfo]パラメータ:
repo_name(str): リポジトリ名(例: "owner/repo")file_path(str): ファイルパス(例: "docs/file.xml")max_commits(Optional[int]): 取得するコミットの最大数(Noneの場合は全て)
戻り値:
List[CommitInfo]: コミット情報のリスト
例:
commits = analyzer.get_file_history(
"nakamura196/toyo_urenja_tei",
"docs/177-04.xml",
max_commits=50
)パッチ情報を分析し、統計情報を生成します。
analyze_patches(commits: List[CommitInfo]) -> Dict[str, Any]パラメータ:
commits(List[CommitInfo]): コミット情報のリスト
戻り値:
Dict[str, Any]: 分析結果の辞書
戻り値の構造:
{
"total_commits": int,
"total_additions": int,
"total_deletions": int,
"change_types": {
"structural": int,
"content": int,
"attribute": int,
"formatting": int
},
"monthly_activity": {
"YYYY-MM": int,
...
},
"authors": {
"author_name": int,
...
}
}AI分析用のプロンプトを生成します。
generate_ai_prompt(
commits: List[CommitInfo],
analysis: Dict[str, Any]
) -> strパラメータ:
commits(List[CommitInfo]): コミット情報のリストanalysis(Dict[str, Any]): analyze_patchesの結果
戻り値:
str: AI分析用のプロンプト文字列
分析結果をJSONファイルに保存します。
save_analysis(
commits: List[CommitInfo],
analysis: Dict[str, Any],
output_path: str
)パラメータ:
commits(List[CommitInfo]): コミット情報のリストanalysis(Dict[str, Any]): 分析結果output_path(str): 出力ファイルパス
OpenRouter APIを使用してAI分析を行うクラス
OpenRouterClient(api_key: str)パラメータ:
api_key(str): OpenRouter API Key
例:
client = OpenRouterClient("sk-or-v1-xxxxxxxxxxxx")ファイル履歴の分析を実行します。
analyze_file_history(
prompt: str,
model: str = "google/gemini-2.5-pro",
temperature: float = 0.7,
max_tokens: Optional[int] = None
) -> OpenRouterResponseパラメータ:
prompt(str): 分析用プロンプトmodel(str): 使用するモデル(デフォルト: "google/gemini-2.5-pro")temperature(float): 生成時の温度パラメータ(デフォルト: 0.7)max_tokens(Optional[int]): 最大トークン数
戻り値:
OpenRouterResponse: AI応答オブジェクト
利用可能なモデル例:
google/gemini-2.5-progoogle/gemini-2.0-flashanthropic/claude-3-sonnetopenai/gpt-4-turbo
分析結果を読みやすい形式にフォーマットします。
format_analysis_result(response: OpenRouterResponse) -> strパラメータ:
response(OpenRouterResponse): AI応答オブジェクト
戻り値:
str: フォーマットされた結果文字列
分析結果をファイルに保存します。
save_analysis_result(
response: OpenRouterResponse,
output_path: str,
format: str = "json"
)パラメータ:
response(OpenRouterResponse): AI応答オブジェクトoutput_path(str): 出力ファイルパスformat(str): 出力形式("json" または "markdown"、デフォルト: "json")
コミット情報を格納するデータクラス
@dataclass
class CommitInfo:
sha: str # コミットSHA
message: str # コミットメッセージ
date: datetime # コミット日時
author: str # 作者名
patch: Optional[str] # 差分情報
additions: int # 追加行数
deletions: int # 削除行数
changes: int # 変更行数OpenRouter APIレスポンスを格納するデータクラス
@dataclass
class OpenRouterResponse:
content: str # AI生成コンテンツ
model: str # 使用されたモデル
usage: Dict[str, int] # トークン使用量
raw_response: Dict[str, Any] # 生のAPIレスポンスusage の構造:
{
"prompt_tokens": int, # 入力トークン数
"completion_tokens": int, # 出力トークン数
"total_tokens": int # 合計トークン数
}両クラスは以下の例外を発生させる可能性があります:
try:
commits = analyzer.get_file_history("owner/repo", "file.py")
except Exception as e:
print(f"エラー: {str(e)}")一般的なエラー:
github.GithubException: GitHub API関連のエラーrequests.exceptions.RequestException: ネットワークエラーKeyError: レスポンス解析エラーFileNotFoundError: ファイル操作エラー
from github import GithubException
try:
analyzer = GitHubFileHistoryAnalyzer(token)
commits = analyzer.get_file_history(repo, file_path)
if not commits:
print("コミット履歴が見つかりません")
return
analysis = analyzer.analyze_patches(commits)
except GithubException as e:
if e.status == 404:
print("リポジトリまたはファイルが見つかりません")
elif e.status == 401:
print("認証エラー: トークンを確認してください")
else:
print(f"GitHub APIエラー: {e}")
except Exception as e:
print(f"予期しないエラー: {e}")from github_file_history_analyzer import GitHubFileHistoryAnalyzer
from openrouter_client import OpenRouterClient
import os
from dotenv import load_dotenv
# 環境変数を読み込む
load_dotenv()
# 初期化
github_token = os.getenv("GITHUB_TOKEN")
openrouter_key = os.getenv("OPENROUTER_API_KEY")
analyzer = GitHubFileHistoryAnalyzer(github_token)
ai_client = OpenRouterClient(openrouter_key)
# ファイル履歴を取得
commits = analyzer.get_file_history(
"nakamura196/toyo_urenja_tei",
"docs/177-04.xml",
max_commits=50
)
# 変更を分析
analysis = analyzer.analyze_patches(commits)
# プロンプトを生成
prompt = analyzer.generate_ai_prompt(commits, analysis)
# AI分析を実行
response = ai_client.analyze_file_history(
prompt,
model="google/gemini-2.5-pro",
temperature=0.7
)
# 結果を保存
ai_client.save_analysis_result(
response,
"output/analysis.md",
format="markdown"
)
print("分析が完了しました")