feat: migrate tools to github_api httpx client, fix async tests#199
Merged
ichoosetoaccept merged 1 commit intomainfrom Feb 27, 2026
Merged
feat: migrate tools to github_api httpx client, fix async tests#199ichoosetoaccept merged 1 commit intomainfrom
ichoosetoaccept merged 1 commit intomainfrom
Conversation
Greptile SummaryThis PR successfully replaces subprocess-based Major changes:
Implementation quality:
The async migration is complete and correct - all blocking calls now properly use Confidence Score: 5/5
Important Files Changed
Sequence DiagramsequenceDiagram
participant Tool as Tool Function
participant API as github_api
participant Cache as LRU Cache
participant HTTP as httpx Client
participant GitHub as GitHub API
Tool->>API: graphql(query) / rest(endpoint)
API->>Cache: Check cache key
alt Cache Hit
Cache-->>API: Return cached result
API-->>Tool: Return data
else Cache Miss
API->>API: get_token() (cached)
API->>HTTP: POST/GET with Bearer token
HTTP->>GitHub: HTTPS Request
GitHub-->>HTTP: JSON Response
HTTP-->>API: Parse response
API->>API: _raise_for_status()
alt Success
API->>Cache: Store result
API-->>Tool: Return data
else Error (401/403/5xx)
API-->>Tool: Raise GitHubError/GitHubAuthError
end
end
Last reviewed commit: 6f8ce5c |
20c7994 to
5ebf934
Compare
- Add github_api.py with GitHubClient (httpx), token resolution, REST/GraphQL helpers - Migrate comments.py, stack.py, issues.py, descriptions.py to github_api - Make async: _get_pr_reviews, _get_pr_issue_comments, _get_pr_commits, _fetch_thread_detail, resolve_comment, reply_to_comment, _fetch_merged_prs, _fetch_pr_summary, _fetch_open_prs, create_issue_from_comment - Update server.py to await now-async calls - Fix test_comments.py, test_stack.py, test_issues.py: AsyncMock, await, github_api mock paths throughout - Add httpx to dependencies
5ebf934 to
6f8ce5c
Compare
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

What
Replaces all per-request
ghCLI subprocess calls with a direct GitHub REST/GraphQL client built onhttpx. Token is resolved once at startup (env var →gh auth tokenfallback) and reused for every request.Why
ghCLI calls block the event loop and were the root cause of the MCP server becoming unresponsive under load.cwddependency:ghused the working directory to detect the repo;httpxcalls use an explicitrepoparameter or a one-timeghfallback, so the server no longer needs a workspace root.github_api.pylayer is the foundation for switching to fine-grained PATs and removing theghCLI runtime dependency entirely.Changes
New:
src/codereviewbuddy/github_api.pyGitHubError/GitHubAuthErrorexception hierarchyparse_repo()— splitsowner/repostringsget_token()— resolves token once (GH_TOKEN → GITHUB_TOKEN →gh auth token), raisesGitHubAuthErrorwith a magic PAT-creation URL if none foundgraphql()— cached GraphQL queries, cache-busting mutationsrest()— cached GET requests, paginated REST withLink:header followingdownload_bytes()— for CI log zip downloadsMigrated callers
tools/comments.pygh.graphql/gh.rest→await github_api.graphql/rest; internal functions madeasynctools/stack.py_fetch_merged_prs,_fetch_pr_summary,_fetch_open_prsnowasynctools/issues.pycreate_issue_from_commentnowasynctools/descriptions.py_fetch_pr_infonowasyncserver.pyawaitadded to calls that becameasyncTests
tests/test_github_api.py— new; covers token resolution, error types, REST/GraphQL/paginate/download viarespxmockstests/test_comments.py,test_stack.py,test_issues.py— updated toAsyncMock, correctgithub_api.*patch paths,awaiton async callsWhat's not changed yet (follow-up phases)
gh.get_repo_infoandgh.get_current_pr_numberstill used as sync fallbacks (wrapped inasyncio.to_thread) — Phase 3 will replace these with git + APIserver.pyworkspace detection still present — Phase 4 will simplifyci.pystill usesghfor log fetching — Phase 5Closes #65
Related to #85