Coverage for polar/integrations/github/client.py: 54%

27 statements  

« prev     ^ index     » next       coverage.py v7.15.2, created at 2026-10-07 12:42 +0000

1from enum import StrEnum 

2from typing import Any 

3 

4from githubkit import ( 

5 AppAuthStrategy, 

6 AppInstallationAuthStrategy, 

7 GitHub, 

8 Response, 

9 TokenAuthStrategy, 

10) 

11 

12from polar.config import settings 

13 

14 

15class UnexpectedStatusCode(Exception): ... 15 ↛ 18line 15 didn't jump to line 18 because

16 

17 

18class AuthenticationRequired(UnexpectedStatusCode): ... 18 ↛ 21line 18 didn't jump to line 21 because

19 

20 

21class Forbidden(UnexpectedStatusCode): ... 21 ↛ 24line 21 didn't jump to line 24 because

22 

23 

24class NotFound(UnexpectedStatusCode): ... 24 ↛ 27line 24 didn't jump to line 27 because

25 

26 

27class ValidationFailed(UnexpectedStatusCode): ... 27 ↛ 30line 27 didn't jump to line 30 because

28 

29 

30class GitHubApp(StrEnum): 

31 repository_benefit = "repository_benefit" 

32 

33 

34HTTP_EXCEPTIONS = { 

35 401: AuthenticationRequired, 

36 403: Forbidden, 

37 404: NotFound, 

38 422: ValidationFailed, 

39} 

40 

41############################################################################### 

42# GITHUB API HELPERS 

43############################################################################### 

44 

45 

46def ensure_expected_response( 

47 response: Response[Any], accepted: set[int] = {200, 304} 

48) -> bool: 

49 status_code = response.status_code 

50 if status_code in accepted: 

51 return True 

52 

53 http_exception = HTTP_EXCEPTIONS.get(status_code, UnexpectedStatusCode) 

54 raise http_exception() 

55 

56 

57############################################################################### 

58# GITHUB API CLIENTS 

59############################################################################### 

60 

61 

62def get_client(access_token: str) -> GitHub[TokenAuthStrategy]: 

63 return GitHub(access_token, http_cache=False) 

64 

65 

66def get_app_client( 

67 app: GitHubApp = GitHubApp.repository_benefit, 

68) -> GitHub[AppAuthStrategy]: 

69 return GitHub( 

70 AppAuthStrategy( 

71 app_id=settings.GITHUB_REPOSITORY_BENEFITS_APP_IDENTIFIER, 

72 private_key=settings.GITHUB_REPOSITORY_BENEFITS_APP_PRIVATE_KEY, 

73 client_id=settings.GITHUB_REPOSITORY_BENEFITS_CLIENT_ID, 

74 client_secret=settings.GITHUB_REPOSITORY_BENEFITS_CLIENT_SECRET, 

75 ), 

76 http_cache=False, 

77 ) 

78 

79 

80def get_app_installation_client( 

81 installation_id: int, 

82 *, 

83 app: GitHubApp = GitHubApp.repository_benefit, 

84) -> GitHub[AppInstallationAuthStrategy]: 

85 if not installation_id: 

86 raise Exception("unable to create github client: no installation_id provided") 

87 

88 return GitHub( 

89 AppInstallationAuthStrategy( 

90 app_id=settings.GITHUB_REPOSITORY_BENEFITS_APP_IDENTIFIER, 

91 private_key=settings.GITHUB_REPOSITORY_BENEFITS_APP_PRIVATE_KEY, 

92 client_id=settings.GITHUB_REPOSITORY_BENEFITS_CLIENT_ID, 

93 client_secret=settings.GITHUB_REPOSITORY_BENEFITS_CLIENT_SECRET, 

94 installation_id=installation_id, 

95 ), 

96 http_cache=False, 

97 ) 

98 

99 

100__all__ = [ 

101 "get_client", 

102 "get_app_client", 

103 "get_app_installation_client", 

104 "GitHub", 

105 "AppInstallationAuthStrategy", 

106 "TokenAuthStrategy", 

107 "Response", 

108]