The docs python-fitbit API建議將'refresh_cb'函數作爲參數傳遞,因此我們不必每次都需要手動檢索訪問令牌,刷新令牌和expires_at變量Fitbit API。我已將這些值放入環境變量中,每次手動檢索值時,都可以成功訪問我的Fitbit信息。但是,我不明白refresh_cb
函數應該做什麼或返回。我知道這是爲了保存新的令牌,但我只是試圖將環境變量更改爲新值,但當我嘗試執行任何操作時,這些錯誤仍然會觸發一個(Invalid grant)
錯誤。這裏是我到目前爲止的代碼:python-fitbit API更新令牌
from fitbit import Fitbit
import os
CLIENT_ID = os.environ['client_id']
SECRET = os.environ['secret']
ACCESS_TOKEN = os.environ['access_token']
EXPIRES_AT = os.environ['expires_in']
REFRESH_TOKEN = os.environ['refresh_token']
USER_ID = os.environ['user_id']
def refresh_cb(token_dict):
"""Function for refreshing access_token, refresh_token, and expires_at."""
os.environ['access_token'] = token_dict['access_token']
os.environ['expires_at'] = str(token_dict['expires_at'])
os.environ['refresh_token'] = token_dict['refresh_token']
return token_dict
kurt = Fitbit(
CLIENT_ID,
SECRET,
access_token=ACCESS_TOKEN,
refresh_token=REFRESH_TOKEN,
expires_at=EXPIRES_AT,
refresh_cb=refresh_cb
)
這裏的文檔說什麼:
我們也強烈建議傳遞一個refresh_cb關鍵字參數, 這應該是採取一個參數的函數:令牌字典。當 該參數存在時,我們將在需要時自動刷新訪問令牌並調用此函數,以便您可以保存 已更新的令牌數據。如果您不保存更新的信息,那麼您最終可能會得到無效的訪問和刷新令牌,並且唯一可以從中恢復的方式是重新授權用戶。如果您有一個 工作示例或可以指向正確的方向,我真的 欣賞它。
編輯:
這裏是完整的回溯我越來越:
TokenExpiredError Traceback (most recent call last)
~/Projects/kurt_data/ENV/lib/python3.6/site-packages/requests_oauthlib/oauth2_session.py in request(self, method, url, data, headers, withhold_token, client_id, client_secret, **kwargs)
329 url, headers, data = self._client.add_token(url,
--> 330 http_method=method, body=data, headers=headers)
331 # Attempt to retrieve and save new access token if expired
~/Projects/kurt_data/ENV/lib/python3.6/site-packages/oauthlib/oauth2/rfc6749/clients/base.py in add_token(self, uri, http_method, body, headers, token_placement, **kwargs)
192 if self._expires_at and self._expires_at < time.time():
--> 193 raise TokenExpiredError()
194
TokenExpiredError: (token_expired)
During handling of the above exception, another exception occurred:
InvalidGrantError Traceback (most recent call last)
<ipython-input-3-c92ce9c67530> in <module>()
----> 1 sleep = kurt.sleep()
~/Projects/kurt_data/ENV/lib/python3.6/site-packages/fitbit/utils.py in _curried(*moreargs, **morekwargs)
36 def curry(_curried_func, *args, **kwargs):
37 def _curried(*moreargs, **morekwargs):
---> 38 return _curried_func(*(args+moreargs), **dict(kwargs, **morekwargs))
39 return _curried
~/Projects/kurt_data/ENV/lib/python3.6/site-packages/fitbit/api.py in _COLLECTION_RESOURCE(self, resource, date, user_id, data)
313 base_url = "{0}/{1}/user/{2}/{resource}.json"
314 url = base_url.format(*self._get_common_args(user_id), **kwargs)
--> 315 return self.make_request(url, data)
316
317 def _DELETE_COLLECTION_RESOURCE(self, resource, log_id):
~/Projects/kurt_data/ENV/lib/python3.6/site-packages/fitbit/api.py in make_request(self, *args, **kwargs)
221
222 method = kwargs.get('method', 'POST' if 'data' in kwargs else 'GET')
--> 223 response = self.client.make_request(*args, **kwargs)
224
225 if response.status_code == 202:
~/Projects/kurt_data/ENV/lib/python3.6/site-packages/fitbit/api.py in make_request(self, url, data, method, **kwargs)
94 client_id=self.client_id,
95 client_secret=self.client_secret,
---> 96 **kwargs
97 )
98
~/Projects/kurt_data/ENV/lib/python3.6/site-packages/fitbit/api.py in _request(self, method, url, **kwargs)
66
67 try:
---> 68 response = self.session.request(method, url, **kwargs)
69
70 # If our current token has no expires_at, or something manages to slip
~/Projects/kurt_data/ENV/lib/python3.6/site-packages/requests_oauthlib/oauth2_session.py in request(self, method, url, data, headers, withhold_token, client_id, client_secret, **kwargs)
341 auth = requests.auth.HTTPBasicAuth(client_id, client_secret)
342 token = self.refresh_token(
--> 343 self.auto_refresh_url, auth=auth, **kwargs
344 )
345 if self.token_updater:
~/Projects/kurt_data/ENV/lib/python3.6/site-packages/requests_oauthlib/oauth2_session.py in refresh_token(self, token_url, refresh_token, body, auth, timeout, headers, verify, proxies, **kwargs)
307 r = hook(r)
308
--> 309 self.token = self._client.parse_request_body_response(r.text, scope=self.scope)
310 if not 'refresh_token' in self.token:
311 log.debug('No new refresh token given. Re-using old.')
~/Projects/kurt_data/ENV/lib/python3.6/site-packages/oauthlib/oauth2/rfc6749/clients/base.py in parse_request_body_response(self, body, scope, **kwargs)
406 .. _`Section 7.1`: http://tools.ietf.org/html/rfc6749#section-7.1
407 """
--> 408 self.token = parse_token_response(body, scope=scope)
409 self._populate_attributes(self.token)
410 return self.token
~/Projects/kurt_data/ENV/lib/python3.6/site-packages/oauthlib/oauth2/rfc6749/parameters.py in parse_token_response(body, scope)
377
378 params = OAuth2Token(params, old_scope=scope)
--> 379 validate_token_parameters(params)
380 return params
381
~/Projects/kurt_data/ENV/lib/python3.6/site-packages/oauthlib/oauth2/rfc6749/parameters.py in validate_token_parameters(params)
384 """Ensures token precence, token type, expiration and scope in params."""
385 if 'error' in params:
--> 386 raise_from_error(params.get('error'), params)
387
388 if not 'access_token' in params:
~/Projects/kurt_data/ENV/lib/python3.6/site-packages/oauthlib/oauth2/rfc6749/errors.py in raise_from_error(error, params)
404 for _, cls in inspect.getmembers(sys.modules[__name__], inspect.isclass):
405 if cls.error == error:
--> 406 raise cls(**kwargs)
InvalidGrantError: (invalid_grant)
我嘗試了你的建議,但我仍然收到同樣的錯誤。我基本上只是將'Fitbit'類實例化到變量'kurt'中,然後嘗試獲取一些數據。根據我的理解,如果'refresh_cb'函數是正確的,那麼它將得到新的令牌並使用提供的函數來保存它們。 –