Last active
December 12, 2025 15:23
-
-
Save ncoop57/9b063060087c4ae090606d1ad18a59a8 to your computer and use it in GitHub Desktop.
GitHub API tools for solveit
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| from ghapi.all import GhApi | |
| from datetime import datetime, timedelta | |
| __all__ = ['get_prs', 'get_pr', 'get_issues', 'get_issue', 'get_notifications', 'ghapi_tools'] | |
| api = GhApi() | |
| def issue_to_xml(issue, comments=None): | |
| "Convert a GitHub issue/PR to XML format" | |
| labels = ','.join(l['name'] for l in issue.get('labels', [])) | |
| is_pr = 'pull_request' in issue or 'diff_url' in issue | |
| typ = 'pr' if is_pr else 'issue' | |
| parts = [f'<{typ} number="{issue["number"]}" state="{issue["state"]}">', | |
| f' <title>{issue["title"]}</title>', | |
| f' <author>{issue["user"]["login"]}</author>', | |
| f' <created>{issue["created_at"]}</created>', | |
| f' <url>{issue["html_url"]}</url>', | |
| f' <labels>{labels}</labels>', | |
| f' <body>{issue.get("body") or ""}</body>'] | |
| if comments: | |
| parts.append(' <comments>') | |
| for c in comments: | |
| parts.append(f' <comment author="{c["user"]["login"]}" created="{c["created_at"]}">{c["body"]}</comment>') | |
| parts.append(' </comments>') | |
| parts.append(f'</{typ}>') | |
| return '\n'.join(parts) | |
| def get_prs(owner:str, # owner of the repo | |
| repo:str): # name of the repo | |
| 'Get a list of all the PRs currently open' | |
| prs = api.pulls.list(owner, repo) | |
| return '\n'.join(f'- #{pr.number}: {pr.title}' for pr in prs) | |
| def get_pr(owner:str, # owner of the repo | |
| repo:str, # name of the repo | |
| num:int): # num for the pr | |
| 'Get the details of the given PR' | |
| pr = api.pulls.get(owner, repo, pull_number=num) | |
| comments = api.issues.list_comments(owner, repo, issue_number=num) | |
| return issue_to_xml(pr, comments) | |
| def get_issues(owner:str, # owner of the repo | |
| repo:str): # name of the repo | |
| 'Get a list of all the issues currently open (excludes PRs)' | |
| issues = api.issues.list_for_repo(owner, repo) | |
| issues = [i for i in issues if 'pull_request' not in i] | |
| return '\n'.join(f'- #{i.number}: {i.title}' for i in issues) | |
| def get_issue(owner:str, # owner of the repo | |
| repo:str, # name of the repo | |
| num:int): # issue number | |
| 'Get the details of the given issue' | |
| issue = api.issues.get(owner, repo, issue_number=num) | |
| comments = api.issues.list_comments(owner, repo, issue_number=num) | |
| return issue_to_xml(issue, comments) | |
| def get_notifications(): | |
| "Get unread notifications for open PRs/Issues from the last 7 days" | |
| since = (datetime.now() - timedelta(days=7)).isoformat() + 'Z' | |
| ns = api.activity.list_notifications_for_authenticated_user(since=since) | |
| results = [] | |
| for n in ns: | |
| if not n.unread: continue | |
| repo = n.repository.full_name | |
| owner, repo_name = repo.split('/') | |
| subj = n.subject | |
| # Extract number from URL (e.g., .../pulls/1199 -> 1199) | |
| num = int(subj.url.split('/')[-1]) | |
| # Fetch current state | |
| if subj.type == 'PullRequest': | |
| item = api.pulls.get(owner, repo_name, num) | |
| if item.state != 'open' or item.merged_at: continue | |
| url = f'https://github.com/{repo}/pull/{num}' | |
| elif subj.type == 'Issue': | |
| item = api.issues.get(owner, repo_name, num) | |
| if item.state != 'open': continue | |
| url = f'https://github.com/{repo}/issues/{num}' | |
| else: continue | |
| results.append(f'- [{subj.type}] {repo}#{num}: {subj.title} ({n.reason})\n {url}') | |
| return '\n'.join(results) if results else 'No unread notifications for open items!' | |
| def ghapi_tools(): | |
| "Add a note describing available ghapi tools" | |
| from dialoghelper.core import add_msg | |
| content = """Tools available from `ghapi_tools` (gist `9b063060087c4ae090606d1ad18a59a8`): | |
| - &`get_prs`: Get a list of all the PRs currently open for a repo. | |
| - &`get_pr`: Get the details of a specific PR including comments, formatted as XML. | |
| - &`get_issues`: Get a list of all open issues (excludes PRs) for a repo. | |
| - &`get_issue`: Get the details of a specific issue including comments, formatted as XML. | |
| - &`get_notifications`: Get unread notifications for open PRs/Issues from the last 7 days.""" | |
| add_msg(content, msg_type='note') |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment