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"])