Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Need help with initial access token. #34

Open
Ashwin1010 opened this issue Feb 20, 2019 · 6 comments
Open

Need help with initial access token. #34

Ashwin1010 opened this issue Feb 20, 2019 · 6 comments

Comments

@Ashwin1010
Copy link

Ashwin1010 commented Feb 20, 2019

withings_git

I am getting TokenMissing error while trying to execute auth.get_authorize_url( redirect_uri)

And apparently withings has depreciated OAuth1 and moved to OAuth2.
But get_authorize_url still uses OAuth1Session?

@psilo909
Copy link

psilo909 commented Apr 14, 2019

same for me, in my own plugin, which was running PERFECTLY for months, now i get a missing token exception when doing a credentials = self._auth.get_credentials(code)

          if self._auth is None:
            self._auth = NokiaAuth(
                self.plugin._client_id,
                self.plugin._consumer_secret,
                callback_uri=self._get_callback_url(),
                scope='user.info,user.metrics,user.activity'
            )

...

            try:
                credentials = self._auth.get_credentials(code)
            except Exception as e:
                self.logger.error(
                    "Plugin '{}': An error occurred, perhaps code parameter is invalid or too old? Message: {}".format(
                        self.plugin.get_fullname(), str(e)))

2019-04-14 07:46:47 ERROR plugins.withings_health Plugin 'withings_health_withings_health_rene': An error occurred, perhaps code parameter is invalid or too old? Message: (missing_token) M
issing access token parameter.

@psilo909
Copy link

It looks like at least these requirements are "hard":

requests-oauth>=0.4.1,<0.5
requests-oauthlib>=1.0,<1.1

While i can update requests to 2.21

When upgrading oauth to a non supported version, the library breaks in the sense of my error described above.. With these versions all is working well now!

added info to my plugin!

@ethanopp
Copy link

ethanopp commented Jun 27, 2019

Any update on this?

@psilo909 I am running requests-ouath 0.4.1 and requests-oauthlib 1.0.0 and still getting this error with the following code

    raise MissingTokenError(description="Missing access token parameter.")
oauthlib.oauth2.rfc6749.errors.MissingTokenError: (missing_token) Missing access token parameter.
    client_id = config.get('withings', 'client_id')
    client_secret = config.get('withings', 'client_secret')
    redirect_uri = config.get('withings', 'redirect_uri')

    auth = NokiaAuth(client_id, client_secret, callback_uri=redirect_uri)
    authorize_url = auth.get_authorize_url()
    print("Go to %s allow the app and copy the url you are redirected to." % authorize_url)
    authorization_response = input('Please enter your full authorization response url: ')
    creds = auth.get_credentials(authorization_response)

    client = NokiaApi(creds)
    measures = client.get_measures(limit=1)
    print("Your last measured weight: %skg" % measures[0].weight)

@stuwilkins
Copy link

Any update? As of today I am getting this error too. I am running the following requests:

requests                  2.21.0                   py37_0  
requests-oauth            0.4.1                    pypi_0    pypi
requests-oauthlib         1.0.0                    py37_1  

This was working, but the token expired and then I am getting the error

MissingTokenError: (missing_token) Missing access token parameter.

Any help appreciated

@ethanopp
Copy link

ethanopp commented Dec 3, 2019

@stuwilkins I unfortunately had to figure this out on my own after several hours of trial and error... It was about half a year ago though so I don't recall EXACTLY what the error was - but I recall there were a few 'ah-ha' moments... Here are all the basic functions I am using, hope they can help you out:

config = configparser.ConfigParser()
config.read('./config.ini')

client_id = config.get('withings', 'client_id')
client_secret = config.get('withings', 'client_secret')
redirect_uri = config.get('withings', 'redirect_uri')

# Fetch saved tokens from db
def current_token_dict():
    try:
        session, engine = db_connect()
        token_dict = session.query(apiTokens.tokens).filter(apiTokens.service == 'Withings').first()
        token_dict = ast.literal_eval(token_dict[0]) if token_dict else {}
        engine.dispose()
        session.close()
    except BaseException as e:
        dash_app.server.logger.error(e)
        token_dict = {}
    return token_dict

# Function for auto saving withings token_dict to db
def save_withings_token(tokens):
    dash_app.server.logger.debug('***** ATTEMPTING TO SAVE TOKENS *****')

    # Withings API returns the following, when refreshing use this
    try:
        token_dict = {
            'access_token': tokens['access_token'],
            'token_expiry': int((datetime.utcnow() - datetime(1970, 1, 1)).total_seconds()) + int(
                tokens['expires_in']),
            'token_type': tokens['token_type'],
            'user_id': tokens['userid'],
            'refresh_token': tokens['refresh_token']
        }

    # NokiaCredentials is an object (not dict)... When running for the first time use this (no record in db)
    except:
        token_dict = {
            'access_token': tokens.access_token,
            'token_expiry': tokens.token_expiry,
            'token_type': tokens.token_type,
            'user_id': tokens.user_id,
            'refresh_token': tokens.refresh_token
        }

    session, engine = db_connect()
    # Delete current key
    session.execute(delete(apiTokens).where(apiTokens.service == 'Withings'))
    # Insert new key
    session.add(apiTokens(date_utc=datetime.utcnow(), service='Withings', tokens=str(token_dict)))
    session.commit()

    engine.dispose()
    session.close()
    dash_app.server.logger.debug('***** SAVED TOKENS *****')


def nokia_creds(token_dict):
    '''
    :param token_dict:
    :return: Nokia Credentials Object
    '''
    return NokiaCredentials(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'],
                            user_id=token_dict['user_id'],
                            refresh_token=token_dict['refresh_token'])


# Pull code from redirect and send through nokia functions to save tokens
# Callback for authorizing withings tokens
@dash_app.callback(Output('withings-token-refresh', 'children'),
                   [Input('url', 'search')],
                   [State('url', 'pathname')])
def update_tokens(token, pathname):
    if 'withings' in pathname:
        dash_app.server.logger.debug(
            '*******************************************************************************************************************')
        if token:
            auth_code = re.findall('=(?<=\=)(.*?)(?=\&)', token)[0]
            dash_app.server.logger.debug(
                'AUTH CODE = {}'.format(auth_code))

            creds = auth_client.get_credentials(auth_code)
            dash_app.server.logger.debug(
                'CREDS = {}'.format(creds))

            save_withings_token(creds)

# Simple function to test if auth tokens have already been saved and are not expired
def withings_connected():
    token_dict = current_token_dict()
    try:
        if token_dict:
            creds = nokia_creds(token_dict)
            client = NokiaApi(credentials=creds, refresh_cb=save_withings_token)
            measures = client.get_measures(limit=1)
            dash_app.server.logger.debug('Withings Connected')
            return True
    except BaseException as e:
        dash_app.server.logger.error('Withings not connected')
        dash_app.server.logger.error(e)
        return False


def pull_withings_data():
    # UTC dates will get sampled into daily
    if withings_connected():
        client = NokiaApi(nokia_creds(current_token_dict()), refresh_cb=save_withings_token)
        df = pd.DataFrame([measure.__dict__ for measure in client.get_measures()])
        df['date_utc'] = df['date'].apply(
            lambda x: datetime.strptime(str(x.format('YYYY-MM-DD HH:mm:ss')), '%Y-%m-%d %H:%M:%S'))
        df = df.drop(columns=['date'])
        df = df.set_index(df['date_utc'])
        df = df[['weight', 'fat_ratio', 'hydration']]
        # Convert to lbs
        df['weight'] *= 2.20462

        # Filter to days later than what is already in db
        session, engine = db_connect()
        withings_max_date = session.query(func.max(withings.date_utc)).first()[0]
        withings_max_date = datetime.strptime('1991-08-30 00:00:00',
                                              '%Y-%m-%d %H:%M:%S') if not withings_max_date else withings_max_date
        engine.dispose()
        session.close()

        df = df[(df.index > withings_max_date) & (~np.isnan(df['weight'])) & (~np.isnan(df['fat_ratio']))]
        if len(df) > 0:
            dash_app.server.logger.info('New withings measurements found!')
            df.to_sql('withings', engine, if_exists='append', index=True)




@stuwilkins
Copy link

Thanks for the code @ethanopp I will look this weekend and see if I can get it to work.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants