Skip to content

Instantly share code, notes, and snippets.

@nat
Last active December 7, 2020 05:33
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nat/d5cb7f356cdb677aa6cf3eecdd20a74c to your computer and use it in GitHub Desktop.
Save nat/d5cb7f356cdb677aa6cf3eecdd20a74c to your computer and use it in GitHub Desktop.
Authenticate with GitHub from Python using the new device auth flow
#!/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