From ac96aa830c478037a9ee37f8d888a3527a44960b Mon Sep 17 00:00:00 2001 From: "M. R. Vallejo" Date: Tue, 23 Feb 2016 19:52:20 -0600 Subject: [PATCH 1/7] Fixed the part where it doesn't work --- fitbit/api.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/fitbit/api.py b/fitbit/api.py index 6498f7a..6ed77d4 100644 --- a/fitbit/api.py +++ b/fitbit/api.py @@ -169,6 +169,9 @@ def __init__(self, client_id , client_secret, self.session = requests.Session() self.client_id = client_id self.client_secret = client_secret + dec_str = ":".join([client_id, client_secret]) + enc_str = base64.b64encode(dec_str.encode("utf-8")) + self.auth_header = {"Authorization": b'Basic ' + enc_str} self.token = {'access_token' : access_token, 'refresh_token': refresh_token} self.oauth = OAuth2Session(client_id) @@ -269,8 +272,7 @@ def fetch_access_token(self, code, redirect_uri): auth = OAuth2Session(self.client_id, redirect_uri=redirect_uri) self.token = auth.fetch_token( self.access_token_url, - username=self.client_id, - password=self.client_secret, + headers=self.auth_header, code=code) return self.token From 0242a6687f7d62000492292fa80844de66e1e317 Mon Sep 17 00:00:00 2001 From: "M. R. Vallejo" Date: Tue, 1 Mar 2016 16:14:49 -0600 Subject: [PATCH 2/7] Fixed the refresh token endpoint part --- fitbit/api.py | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/fitbit/api.py b/fitbit/api.py index 6ed77d4..8ba6225 100644 --- a/fitbit/api.py +++ b/fitbit/api.py @@ -283,15 +283,10 @@ def refresh_token(self): the token is internally saved """ - unenc_str = (self.client_id + ':' + self.client_secret).encode('utf8') - headers = { - 'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8', - 'Authorization': b'Basic ' + base64.b64encode(unenc_str) - } self.token = self.oauth.refresh_token( self.refresh_token_url, refresh_token=self.token['refresh_token'], - headers=headers) + auth=(self.client_id, self.client_secret)) return self.token From c1e43c63109d05c008bed30e3e52205648f91638 Mon Sep 17 00:00:00 2001 From: "M. R. Vallejo" Date: Thu, 3 Mar 2016 16:35:53 -0600 Subject: [PATCH 3/7] Removed the refreshing token part of the request. This kills the token --- fitbit/api.py | 23 ----------------------- 1 file changed, 23 deletions(-) diff --git a/fitbit/api.py b/fitbit/api.py index 8ba6225..b16b9a9 100644 --- a/fitbit/api.py +++ b/fitbit/api.py @@ -191,29 +191,6 @@ def make_request(self, url, data={}, method=None, **kwargs): if not method: method = 'POST' if data else 'GET' - try: - auth = OAuth2(client_id=self.client_id, token=self.token) - response = self._request(method, url, data=data, auth=auth, **kwargs) - except TokenExpiredError as e: - self.refresh_token() - auth = OAuth2(client_id=self.client_id, token=self.token) - response = self._request(method, url, data=data, auth=auth, **kwargs) - - #yet another token expiration check - #(the above try/except only applies if the expired token was obtained - #using the current instance of the class this is a a general case) - if response.status_code == 401: - d = json.loads(response.content.decode('utf8')) - try: - if(d['errors'][0]['errorType']=='oauth' and - d['errors'][0]['fieldName']=='access_token' and - d['errors'][0]['message'].find('Access token invalid or expired:')==0): - self.refresh_token() - auth = OAuth2(client_id=self.client_id, token=self.token) - response = self._request(method, url, data=data, auth=auth, **kwargs) - except: - pass - if response.status_code == 401: raise HTTPUnauthorized(response) elif response.status_code == 403: From fdfb5c3c94f688131fc3caaace201368c29ecbbe Mon Sep 17 00:00:00 2001 From: "M. R. Vallejo" Date: Thu, 3 Mar 2016 16:50:10 -0600 Subject: [PATCH 4/7] re fxied and stuff --- fitbit/api.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/fitbit/api.py b/fitbit/api.py index b16b9a9..469f4fb 100644 --- a/fitbit/api.py +++ b/fitbit/api.py @@ -191,6 +191,9 @@ def make_request(self, url, data={}, method=None, **kwargs): if not method: method = 'POST' if data else 'GET' + auth = OAuth2(client_id=self.client_id, token=self.token) + response = self._request(method, url, data=data, auth=auth, **kwargs) + if response.status_code == 401: raise HTTPUnauthorized(response) elif response.status_code == 403: From 246e66ae82e3922ddb8c81333649829ca624268a Mon Sep 17 00:00:00 2001 From: "M. R. Vallejo" Date: Mon, 7 Mar 2016 19:06:47 -0600 Subject: [PATCH 5/7] Timeouts and better token refresh functionality --- fitbit/api.py | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/fitbit/api.py b/fitbit/api.py index 469f4fb..42254c2 100644 --- a/fitbit/api.py +++ b/fitbit/api.py @@ -64,7 +64,7 @@ def _request(self, method, url, **kwargs): """ A simple wrapper around requests. """ - return self.session.request(method, url, **kwargs) + return self.session.request(method, url, timeout=30.0, **kwargs) def make_request(self, url, data={}, method=None, **kwargs): """ @@ -180,7 +180,7 @@ def _request(self, method, url, **kwargs): """ A simple wrapper around requests. """ - return self.session.request(method, url, **kwargs) + return self.session.request(method, url, timeout=30.0, **kwargs) def make_request(self, url, data={}, method=None, **kwargs): """ @@ -263,10 +263,19 @@ def refresh_token(self): the token is internally saved """ - self.token = self.oauth.refresh_token( - self.refresh_token_url, - refresh_token=self.token['refresh_token'], - auth=(self.client_id, self.client_secret)) + try: + self.token = self.oauth.refresh_token( + self.refresh_token_url, + refresh_token=self.token['refresh_token'], + auth=(self.client_id, self.client_secret), + timeout=30) + except requests.Timeout: + self.token = self.oauth.refresh_token( + self.refresh_token_url, + refresh_token=self.token['refresh_token'], + auth=(self.client_id, self.client_secret), + timeout=30) + return self.token From 290c5958eb858e7c766382c20d853017f8b98932 Mon Sep 17 00:00:00 2001 From: "M. R. Vallejo" Date: Thu, 5 May 2016 17:54:25 -0500 Subject: [PATCH 6/7] Reduced timeout --- fitbit/api.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/fitbit/api.py b/fitbit/api.py index 42254c2..16d6c27 100644 --- a/fitbit/api.py +++ b/fitbit/api.py @@ -64,7 +64,7 @@ def _request(self, method, url, **kwargs): """ A simple wrapper around requests. """ - return self.session.request(method, url, timeout=30.0, **kwargs) + return self.session.request(method, url, timeout=10.0, **kwargs) def make_request(self, url, data={}, method=None, **kwargs): """ @@ -180,7 +180,7 @@ def _request(self, method, url, **kwargs): """ A simple wrapper around requests. """ - return self.session.request(method, url, timeout=30.0, **kwargs) + return self.session.request(method, url, timeout=10.0, **kwargs) def make_request(self, url, data={}, method=None, **kwargs): """ @@ -268,13 +268,13 @@ def refresh_token(self): self.refresh_token_url, refresh_token=self.token['refresh_token'], auth=(self.client_id, self.client_secret), - timeout=30) + timeout=10) except requests.Timeout: self.token = self.oauth.refresh_token( self.refresh_token_url, refresh_token=self.token['refresh_token'], auth=(self.client_id, self.client_secret), - timeout=30) + timeout=10) return self.token From ca5e17117f8dc945fb00c97ee9aa85621f7cd835 Mon Sep 17 00:00:00 2001 From: "M. R. Vallejo" Date: Mon, 29 Aug 2016 11:19:08 -0500 Subject: [PATCH 7/7] Made the timeout a constant so it's easy to tweak and also increased it from 10 to 27 seconds --- fitbit/api.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/fitbit/api.py b/fitbit/api.py index 16d6c27..ad27245 100644 --- a/fitbit/api.py +++ b/fitbit/api.py @@ -19,6 +19,7 @@ HTTPTooManyRequests) from fitbit.utils import curry +TIMEOUT_SECONDS = 27.0 class FitbitOauthClient(object): API_ENDPOINT = "https://api.fitbit.com" @@ -64,7 +65,7 @@ def _request(self, method, url, **kwargs): """ A simple wrapper around requests. """ - return self.session.request(method, url, timeout=10.0, **kwargs) + return self.session.request(method, url, timeout=TIMEOUT_SECONDS, **kwargs) def make_request(self, url, data={}, method=None, **kwargs): """ @@ -180,7 +181,7 @@ def _request(self, method, url, **kwargs): """ A simple wrapper around requests. """ - return self.session.request(method, url, timeout=10.0, **kwargs) + return self.session.request(method, url, timeout=TIMEOUT_SECONDS, **kwargs) def make_request(self, url, data={}, method=None, **kwargs): """ @@ -268,13 +269,13 @@ def refresh_token(self): self.refresh_token_url, refresh_token=self.token['refresh_token'], auth=(self.client_id, self.client_secret), - timeout=10) + timeout=TIMEOUT_SECONDS) except requests.Timeout: self.token = self.oauth.refresh_token( self.refresh_token_url, refresh_token=self.token['refresh_token'], auth=(self.client_id, self.client_secret), - timeout=10) + timeout=TIMEOUT_SECONDS) return self.token