From 69cbcf937a5ec758ee5217794e417290982bf3fd Mon Sep 17 00:00:00 2001 From: Russ Allbery Date: Mon, 18 Sep 2023 11:47:44 -0700 Subject: [PATCH] Treat GitHub app and installation IDs as ints Gidgethub treats app and installation IDs as str, but the GitHub API appears to return int. Use int in GitHubAppClientFactory for consistency with what GitHub returns, and convert them to str when passing them to Gidgethub. Add a changelog entry and a note on the class about this out of an abundance of caution. --- changelog.d/20230918_114322_rra_DM_40744.md | 3 +++ src/safir/github/_client.py | 16 +++++++++++----- 2 files changed, 14 insertions(+), 5 deletions(-) create mode 100644 changelog.d/20230918_114322_rra_DM_40744.md diff --git a/changelog.d/20230918_114322_rra_DM_40744.md b/changelog.d/20230918_114322_rra_DM_40744.md new file mode 100644 index 00000000..e8eef5ec --- /dev/null +++ b/changelog.d/20230918_114322_rra_DM_40744.md @@ -0,0 +1,3 @@ +### Backwards-incompatible changes + +- `safir.github.GitHubAppClientFactory` now expects the application ID and installation ID (for `create_installation_client`) to be of type `int`, not `str`. This appears to match what GitHub's API returns, but not what Gidgethub expects. The ID is converted to a string when passing it to Gidgethub. diff --git a/src/safir/github/_client.py b/src/safir/github/_client.py index cf64e286..5608add0 100644 --- a/src/safir/github/_client.py +++ b/src/safir/github/_client.py @@ -21,10 +21,16 @@ class GitHubAppClientFactory: from (e.g. ``lsst-sqre/times-square``). http_client The httpx client. + + Notes + ----- + Gidgethub treats the application ID and installation ID as strings, but + GitHub's API appears to return them as integers. This class expects them + to be integers and converts them to strings when calling Gidgethub. """ def __init__( - self, *, id: str, key: str, name: str, http_client: httpx.AsyncClient + self, *, id: int, key: str, name: str, http_client: httpx.AsyncClient ) -> None: self.app_id = id self.app_key = key @@ -43,7 +49,7 @@ def get_app_jwt(self) -> str: The JWT token. """ return gidgethub.apps.get_jwt( - app_id=self.app_id, private_key=self.app_key + app_id=str(self.app_id), private_key=self.app_key ) def _create_client(self, *, oauth_token: str | None = None) -> GitHubAPI: @@ -72,7 +78,7 @@ def create_app_client(self) -> GitHubAPI: return self._create_client(oauth_token=self.get_app_jwt()) async def create_installation_client( - self, installation_id: str + self, installation_id: int ) -> GitHubAPI: """Create a client authenticated as an installation of the GitHub App for a specific repository or organization. @@ -93,8 +99,8 @@ async def create_installation_client( anon_client = self.create_anonymous_client() token_info = await gidgethub.apps.get_installation_access_token( anon_client, - installation_id=installation_id, - app_id=self.app_id, + installation_id=str(installation_id), + app_id=str(self.app_id), private_key=self.app_key, ) return self._create_client(oauth_token=token_info["token"])