Open ethanopp opened 3 years ago
It seems like the credentials are saving correctly, but when I pass them to the WithingsApi() I get this:
unsupported operand type(s) for -: 'int' and 'method'
I am a little confused because the common.py shows token_expiry as int https://github.com/vangorra/python_withings_api/blob/7ac2327249e95a106da0634c2ed87f27bfc3842e/withings_api/common.py#L585
Could you please let me know what I am doing wrong here?
Save the tokens to db table:
# Function for auto saving withings token_dict to db
def save_withings_token(tokens):
app.server.logger.debug('***** ATTEMPTING TO SAVE TOKENS *****')
token_dict = tokens.dict()
# Can't save arrow method to sqlite, so save it as timestamp
token_dict['created'] = token_dict['created'].timestamp()
token_dict['token_expiry'] = int(round(token_dict['created'])) + int(token_dict['expires_in'])
# Delete current tokens
app.session.execute(delete(apiTokens).where(apiTokens.service == 'Withings'))
# Insert new tokens
app.session.add(apiTokens(date_utc=datetime.utcnow(), service='Withings', tokens=str(token_dict)))
app.session.commit()
app.session.remove()
app.server.logger.debug('***** SAVED TOKENS *****')
Query the db table and create the Credentials() object
def current_token_dict():
try:
token_dict = app.session.query(apiTokens.tokens).filter(apiTokens.service == 'Withings').first()
token_dict = ast.literal_eval(token_dict[0]) if token_dict else {}
app.session.remove()
except BaseException as e:
app.server.logger.error(e)
token_dict = {}
return token_dict
def withings_creds(token_dict):
'''
:param token_dict:
:return: Withings Credentials Object
'''
return Credentials(client_id=client_id,
consumer_secret=client_secret,
access_token=token_dict['access_token'],
token_expiry=token_dict['token_expiry'],
token_type=token_dict['token_type'],
userid=token_dict['userid'],
refresh_token=token_dict['refresh_token'])
Pass the Credentials() object to WithingsAPI to test if tokens are working
def withings_connected():
token_dict = current_token_dict()
try:
if token_dict:
creds = withings_creds(token_dict)
client = WithingsApi(credentials=creds, refresh_cb=save_withings_token)
measures = client.measure_get_meas()
app.server.logger.debug('Withings Connected')
return True
except BaseException as e:
app.server.logger.error('Withings not connected')
app.server.logger.error(e)
return False
Alright think I'm pretty close... Got it working now by using Credentials2 instead of Credentials... Only last issue now is that it doesn't seem like the refresh_cb is working if I go into my db and manually update the 'expires_in' to 10... Thanks again in advance
def current_token_dict():
try:
token_dict = app.session.query(apiTokens.tokens).filter(apiTokens.service == 'Withings').first()
token_dict = ast.literal_eval(token_dict[0]) if token_dict else {}
app.session.remove()
except BaseException as e:
app.server.logger.error(e)
token_dict = {}
return token_dict
# Function for auto saving withings token_dict to db
def save_withings_token(tokens):
app.server.logger.debug('***** ATTEMPTING TO SAVE TOKENS *****')
token_dict = tokens.dict()
# Can't save arrow method to sqlite, so save it as timestamp
token_dict['created'] = round(int(token_dict['created'].timestamp()))
# Delete current tokens
app.session.execute(delete(apiTokens).where(apiTokens.service == 'Withings'))
# Insert new tokens
app.session.add(apiTokens(date_utc=datetime.utcnow(), service='Withings', tokens=str(token_dict)))
app.session.commit()
app.session.remove()
app.server.logger.debug('***** SAVED TOKENS *****')
def withings_creds(token_dict):
'''
:param token_dict:
:return: Withings Credentials Object
'''
return Credentials2(client_id=client_id,
consumer_secret=client_secret,
access_token=token_dict['access_token'],
expires_in=token_dict['expires_in'],
created=token_dict['created'],
token_type=token_dict['token_type'],
userid=token_dict['userid'],
refresh_token=token_dict['refresh_token'])
def withings_connected():
token_dict = current_token_dict()
try:
if token_dict:
creds = withings_creds(token_dict)
client = WithingsApi(credentials=creds, refresh_cb=save_withings_token)
measures = client.measure_get_meas()
app.server.logger.debug('Withings Connected')
return True
except BaseException as e:
app.server.logger.error('Withings not connected')
app.server.logger.error(e)
return False
Put some more time into this... Updated my functions to use pickle as per the integration test example:
def save_withings_token(credentials: CredentialsType) -> None:
app.server.logger.debug('***** ATTEMPTING TO SAVE TOKENS *****')
# Delete current tokens
app.session.execute(delete(apiTokens).where(apiTokens.service == 'Withings'))
# Insert new tokens
app.session.add(apiTokens(date_utc=datetime.utcnow(), service='Withings', tokens=pickle.dumps(credentials)))
app.session.commit()
app.session.remove()
app.server.logger.debug('***** SAVED TOKENS *****')
def load_credentials() -> CredentialsType:
try:
token_pickle = app.session.query(apiTokens.tokens).filter(apiTokens.service == 'Withings').first().tokens
creds = cast(CredentialsType, pickle.loads(token_pickle))
app.session.remove()
except BaseException as e:
app.server.logger.error(e)
creds = None
return creds
def withings_connected():
try:
client = WithingsApi(credentials=load_credentials(), refresh_cb=save_withings_token)
measures = client.measure_get_meas()
app.server.logger.debug('Withings Connected')
return True
except BaseException as e:
app.server.logger.error('Withings not connected')
app.server.logger.error(e)
return False
# Redirect function to save tokens the first time - ** WORKING **
def update_tokens(search):
query_params = urlparse.urlparse(search)
creds = withings_auth_client.get_credentials(parse_qs(query_params.query)['code'][0])
save_withings_token(creds)
The above all works when I do the initial connection via the authorize_url, and continues to work until the the token expires... When the refresh_db tries to run though, I keep getting Error code 401
@vangorra please help!
@vangorra wanted to check in once more to see if you could please help out here.
Thanks in advance...
I have essentially the same issue as ethanopp. The .credentials file is not being created and it is failing in the token generation also with the following screen.
This site can’t be reached184.187.79.5 took too long to respond. Try:
Checking the connection Checking the proxy and the firewall Running Windows Network Diagnostics ERR_CONNECTION_TIMED_OUT
The app authentication (step 1) works where it asks the user to press the authorize app button. It fails in the second step with the error shown above. I tried the same invocation with localhost:5000 as my uri and it fails with the same error message. Please help. I am running scripts/integration_test.py with mode=None
Code has been working now for over a year, stopped working all of the sudden...wondering if something has changed
Code is pretty straightforward, user clicks 'Allow', I parse query params for the code and then pass to the .get_credentials() function.
The code is being parsed correctly so it seems something with the function is off...
Here is the error I'm getting
Also, when trying to
print(creds)
I getinvalid syntax (<unknown>, line 1)