python-fitbit API更新令牌
问题描述:
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)
答
据我了解,你需要刷新全球蟒蛇变量(不是环境变量)这样
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
我尝试了你的建议,但我仍然收到同样的错误。我基本上只是将'Fitbit'类实例化到变量'kurt'中,然后尝试获取一些数据。根据我的理解,如果'refresh_cb'函数是正确的,那么它将得到新的令牌并使用提供的函数来保存它们。 –