-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathgithub.py
More file actions
50 lines (40 loc) · 1.86 KB
/
github.py
File metadata and controls
50 lines (40 loc) · 1.86 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
from typing import Any
import httpx
from fastapi_oauth20.errors import GetUserInfoError
from fastapi_oauth20.oauth20 import OAuth20Base
class GitHubOAuth20(OAuth20Base):
"""GitHub OAuth2 client implementation."""
def __init__(self, client_id: str, client_secret: str):
"""
Initialize GitHub OAuth2 client.
:param client_id: GitHub OAuth App client ID.
:param client_secret: GitHub OAuth App client secret.
:return:
"""
super().__init__(
client_id=client_id,
client_secret=client_secret,
authorize_endpoint='https://github.com/login/oauth/authorize',
access_token_endpoint='https://github.com/login/oauth/access_token',
userinfo_endpoint='https://api.github.com/user',
default_scopes=['user', 'user:email'],
)
async def get_userinfo(self, access_token: str) -> dict[str, Any]:
"""
Retrieve user information from GitHub API.
:param access_token: Valid GitHub access token with appropriate scopes.
:return:
"""
headers = {'Authorization': f'Bearer {access_token}'}
async with httpx.AsyncClient(headers=headers) as client:
response = await client.get(self.userinfo_endpoint)
self.raise_httpx_oauth20_errors(response)
result = self.get_json_result(response, err_class=GetUserInfoError)
email = result.get('email')
if email is None:
response = await client.get(f'{self.userinfo_endpoint}/emails')
self.raise_httpx_oauth20_errors(response)
emails = self.get_json_result(response, err_class=GetUserInfoError)
email = next((email['email'] for email in emails if email.get('primary')), emails[0]['email'])
result['email'] = email
return result