2017-10-10 120 views
1

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) 

回答

0

據我瞭解,你需要刷新全球蟒蛇變量(不是環境變量)這樣

def refresh_cb(token_dict): 
    """Function for refreshing access_token, refresh_token, and expires_at.""" 
    global ACCESS_TOKEN 
    global EXPIRES_AT 
    global REFRESH_TOKEN 
    ACCESS_TOKEN = token_dict['access_token'] 
    EXPIRES_AT = str(token_dict['expires_at']) 
    REFRESH_TOKEN = token_dict['refresh_token'] 

    return token_dict 
+0

我嘗試了你的建議,但我仍然收到同樣的錯誤。我基本上只是將'Fitbit'類實例化到變量'kurt'中,然後嘗試獲取一些數據。根據我的理解,如果'refresh_cb'函數是正確的,那麼它將得到新的令牌並使用提供的函數來保存它們。 –