import os from github import Github from typing import List, Optional try: from .models import PROpportunity except ImportError: from models import PROpportunity HELP_LABELS = ["good first issue", "help wanted"] class GitHubClient: def __init__(self, token: Optional[str] = None): self.token = token or os.getenv("GITHUB_TOKEN") if not self.token: raise ValueError("GitHub token must be provided via argument or GITHUB_TOKEN env var.") self.client = Github(self.token) def search_repositories(self, keyword: Optional[str], topic: Optional[str], per_page: int, page: int): query = [] if keyword: query.append(keyword) if topic: query.append(f"topic:{topic}") query_str = " ".join(query) return self.client.search_repositories(query_str, sort="stars", order="desc") def find_pr_opportunities(self, keyword: Optional[str], topic: Optional[str], per_page: int = 10, page: int = 1) -> List[PROpportunity]: repos = self.search_repositories(keyword, topic, per_page, page) opportunities = [] count = 0 for repo in repos.get_page(page-1): issues = repo.get_issues(state="open", labels=HELP_LABELS) for issue in issues: if issue.pull_request is not None: continue # skip PRs labels = [l.name for l in issue.labels] if any(l.lower() in HELP_LABELS for l in labels): opportunities.append(PROpportunity( repo_name=repo.full_name, repo_url=repo.html_url, issue_title=issue.title, issue_url=issue.html_url, issue_labels=labels, issue_body=issue.body )) count += 1 if count >= per_page: break if count >= per_page: break return opportunities, repos.totalCount