From 7d09a158c37af4898c57da4196be9a7b3abc3c9b Mon Sep 17 00:00:00 2001 From: Rohit Malhotra Date: Mon, 3 Feb 2025 11:44:32 -0500 Subject: [PATCH] Fix Github service bugs (#6571) Co-authored-by: tofarr --- openhands/server/routes/github.py | 4 +-- openhands/server/routes/settings.py | 2 +- openhands/server/services/github_service.py | 29 ++++++++++++++------- 3 files changed, 23 insertions(+), 12 deletions(-) diff --git a/openhands/server/routes/github.py b/openhands/server/routes/github.py index 217ea83570..d92105419e 100644 --- a/openhands/server/routes/github.py +++ b/openhands/server/routes/github.py @@ -53,8 +53,8 @@ async def get_github_installation_ids( github_user_id: str | None = Depends(get_user_id), ): client = GithubServiceImpl(github_token, github_user_id) - installations = await client.get_installation_ids() - return JSONResponse(content=[i['id'] for i in installations]) + installations_ids = await client.get_installation_ids() + return JSONResponse(content=installations_ids) @app.get('/search/repositories') diff --git a/openhands/server/routes/settings.py b/openhands/server/routes/settings.py index 40366253ce..aa538f5e3d 100644 --- a/openhands/server/routes/settings.py +++ b/openhands/server/routes/settings.py @@ -51,7 +51,7 @@ async def store_settings( # We check if the token is valid by getting the user # If the token is invalid, this will raise an exception github = GitHubService(settings.github_token, None) - response = await github.get_user() + response = await github.fetch_response('get_user') if response.status_code != status.HTTP_200_OK: raise Exception('Invalid Github Token') diff --git a/openhands/server/services/github_service.py b/openhands/server/services/github_service.py index 576ed05b6f..dd11d17832 100644 --- a/openhands/server/services/github_service.py +++ b/openhands/server/services/github_service.py @@ -1,8 +1,10 @@ import httpx import requests +from fastapi import Response from fastapi.responses import JSONResponse from openhands.server.shared import server_config +from openhands.server.types import AppMode from openhands.utils.async_utils import call_sync_from_async @@ -12,8 +14,10 @@ class GitHubService: def __init__(self, token: str, user_id: str | None): self.token = token self.user_id = user_id - self.headers = { - 'Authorization': f'Bearer {token}', + + def _get_github_headers(self): + return { + 'Authorization': f'Bearer {self.token}', 'Accept': 'application/vnd.github.v3+json', } @@ -23,17 +27,20 @@ class GitHubService: async def _get_latest_token(self): pass - async def _fetch_data(self, url: str, params: dict | None = None): + async def _fetch_data(self, url: str, params: dict | None = None) -> Response: try: async with httpx.AsyncClient() as client: - response = await client.get(url, headers=self.headers, params=params) - if server_config.app_mode == 'SAAS' and self._has_token_expired( + response = await client.get( + url, headers=self._get_github_headers(), params=params + ) + if server_config.app_mode == AppMode.SAAS and self._has_token_expired( response.status_code ): await self._get_latest_token() response = await client.get( - url, headers=self.headers, params=params + url, headers=self._get_github_headers(), params=params ) + response.raise_for_status() return response @@ -62,11 +69,15 @@ class GitHubService: params['sort'] = sort return await self._fetch_data(url, params) - async def get_installation_ids(self): + async def get_installation_ids(self) -> list[int]: url = f'{self.BASE_URL}/user/installations' response = await self._fetch_data(url) data = response.json() - return data.get('installations', []) + if not isinstance(data, dict): + return [] + + installations = data.get('installations', []) + return [i['id'] for i in installations] async def search_repositories( self, query: str, per_page: int, sort: str, order: str @@ -74,7 +85,7 @@ class GitHubService: url = f'{self.BASE_URL}/search/repositories' params = {'q': query, 'per_page': per_page, 'sort': sort, 'order': order} return await call_sync_from_async( - requests.get, url, headers=self.headers, params=params + requests.get, url, headers=self._get_github_headers(), params=params ) async def fetch_response(self, method: str, *args, **kwargs):