-
Notifications
You must be signed in to change notification settings - Fork 325
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
use a cherrypy server for easy token collection
- Loading branch information
Showing
2 changed files
with
66 additions
and
31 deletions.
There are no files selected for viewing
This file contains 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
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']) |
This file contains 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
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 |