Skip to content

Commit

Permalink
use a cherrypy server for easy token collection
Browse files Browse the repository at this point in the history
  • Loading branch information
brad committed Jun 13, 2015
1 parent fb3b0ca commit 3abe822
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 31 deletions.
96 changes: 65 additions & 31 deletions gather_keys_oauth2.py
Original file line number Diff line number Diff line change
@@ -1,45 +1,79 @@
#!/usr/bin/env python
import pprint
import sys
import cherrypy
import os
import sys
import threading
import traceback
import webbrowser

from fitbit.api import FitbitOauth2Client
from base64 import b64encode
from fitbit.api import FitbitOauth2Client
from oauthlib.oauth2.rfc6749.errors import MismatchingStateError, MissingTokenError
from requests_oauthlib import OAuth2Session


def gather_keys(client_id,client_secret, redirect_uri):

# setup
pp = pprint.PrettyPrinter(indent=4)
client = FitbitOauth2Client(client_id, client_secret)
class OAuth2Server:
def __init__(self, client_id, client_secret,
redirect_uri='http://127.0.0.1:8080/'):
""" Initialize the FitbitOauth2Client """
self.redirect_uri = redirect_uri
self.success_html = """
<h1>You are now authorized to access the Fitbit API!</h1>
<br/><h3>You can close this window</h3>"""
self.failure_html = """
<h1>ERROR: %s</h1><br/><h3>You can close this window</h3>%s"""
self.oauth = FitbitOauth2Client(client_id, client_secret)

#get authorization url
url = client.authorize_token_url(redirect_uri=redirect_uri)
def browser_authorize(self):
"""
Open a browser to the authorization url and spool up a CherryPy
server to accept the response
"""
url, _ = self.oauth.authorize_token_url(redirect_uri=self.redirect_uri)
# Open the web browser in a new thread for command-line browser support
threading.Timer(1, webbrowser.open, args=(url,)).start()
cherrypy.quickstart(self)

print('* Authorize the request token in your browser\nCopy code here\n')
print(url)
try:
verifier = raw_input('Code: ')
except NameError:
# Python 3.x
verifier = input('Code: ')
@cherrypy.expose
def index(self, state, code=None, error=None):
"""
Receive a Fitbit response containing a verification code. Use the code
to fetch the access_token.
"""
error = None
if code:
try:
self.oauth.fetch_access_token(code, self.redirect_uri)
except MissingTokenError:
error = self._fmt_failure(
'Missing access token parameter.</br>Please check that '
'you are using the correct client_secret')
except MismatchingStateError:
error = self._fmt_failure('CSRF Warning! Mismatching state')
else:
error = self._fmt_failure('Unknown error while authenticating')
# Use a thread to shutdown cherrypy so we can return HTML first
self._shutdown_cherrypy()
return error if error else self.success_html

# get access token
print('\n* Obtain an access token ...\n')
token = client.fetch_access_token(verifier,redirect_uri)
print('RESPONSE')
pp.pprint(token)
print('')
return(token)
def _fmt_failure(self, message):
tb = traceback.format_tb(sys.exc_info()[2])
tb_html = '<pre>%s</pre>' % ('\n'.join(tb)) if tb else ''
return self.failure_html % (message, tb_html)

def _shutdown_cherrypy(self):
""" Shutdown cherrypy in one second, if it's running """
if cherrypy.engine.state == cherrypy.engine.states.STARTED:
threading.Timer(1, cherrypy.engine.exit).start()


if __name__ == '__main__':

if not (len(sys.argv) == 4):
print "Arguments: client_id, client_secret, and redirect_uri"
if not (len(sys.argv) == 3):
print("Arguments: client_id and client_secret")
sys.exit(1)

client_id = sys.argv[1]
client_sec = sys.argv[2]
redirect_uri = sys.argv[3]

token = gather_keys(client_id,client_sec,redirect_uri)
server = OAuth2Server(*sys.argv[1:])
server.browser_authorize()
print('FULL RESULTS = %s' % server.oauth.token)
print('ACCESS_TOKEN = %s' % server.oauth.token['access_token'])
1 change: 1 addition & 0 deletions requirements/dev.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
-r base.txt
-r test.txt

cherrypy>=3.7,<3.8
tox>=1.8,<1.9

0 comments on commit 3abe822

Please sign in to comment.