Last active
April 21, 2025 13:14
-
-
Save nat/d5cb7f356cdb677aa6cf3eecdd20a74c to your computer and use it in GitHub Desktop.
Authenticate with GitHub from Python using the new device auth flow
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
# | |
# Implements the GitHub device auth flow described here: | |
# https://docs.github.com/en/free-pro-team@latest/developers/apps/authorizing-oauth-apps#device-flow | |
from urllib.parse import parse_qs | |
import urllib, requests, time, webbrowser, json | |
client_id ='a945f87ad537bfddb109' | |
# Kick off the headless device auth flow on github.com | |
url = 'https://github.com/login/device/code' | |
response = requests.post(url, data = {'client_id': client_id, 'scope': ''}) | |
params = parse_qs(response.text) | |
YELLOW = '\033[93m' | |
END = '\033[0m' | |
print ("First copy your one-time code: " + YELLOW + params['user_code'][0] + END) | |
time.sleep(1) | |
input("Then, press Enter to open %s in a browser..." % (params['verification_uri'][0])) | |
webbrowser.open(params['verification_uri'][0]) | |
print() | |
print ("Waiting for authorization...", end='', flush=True) | |
# Poll for the user to finish the auth flow | |
interval = int(params['interval'][0]) + 1 | |
while True: | |
time.sleep(interval) | |
print('.', end='', flush=True) | |
poll_response = requests.post('https://github.com/login/oauth/access_token', | |
data = {'client_id': client_id, | |
'device_code': params['device_code'], | |
'grant_type': 'urn:ietf:params:oauth:grant-type:device_code'}) | |
poll_params = parse_qs(poll_response.text) | |
if 'error' in poll_params: | |
continue | |
if 'access_token' in poll_params: | |
print() | |
access_token=poll_params['access_token'][0] | |
print("Got access token: " + access_token) | |
break | |
response = requests.get('https://api.github.com/user', | |
headers = {'Authorization': 'token ' + access_token}) | |
r = json.loads(response.text) | |
login = r['login'] | |
print("Authenticated with GitHub as %s!" % (login)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment