access token refresh - 401 issues

sam123456sam123456 Member Posts: 25

This is more likely an issue on my end, but I'm trying to rule things out. I'm working in python.

I have created a connection class, that class has a method called 'refresh access'. Whenever I create a new connection instance, I follow up by calling the 'refresh_access' token. This is all working as anticipated.

I then use that connection class to interact with the API. It works perfectly until it needs a refresh. At that point I call it again, but any subsequent API interactions produce a 401 invalid token error. In the debugger I can clearly see that the method is properly updating the 'access_token' variable. Is there any other variable that needs to be updated?

class LightspeedStoreConn:
    """class for connecting to Lightspeed"""
    def __init__(self, store_credentials_data, devcreds):
        self.access_token = ''  
        self.expires_in = '' 
        self.token_type = store_credentials_data['token_type']
        self.scope = store_credentials_data['scope']
        self.refresh_token = store_credentials_data['refresh_token']
        self.account_id = store_credentials_data['account_id']
        self.client_id = devcreds['clientID']
        self.client_secret = devcreds['clientSec']
        self.base_url = 'https://api.lightspeedapp.com/API/Account/'

    def refresh_access(self):
        payload = {
            'refresh_token': f'{self.refresh_token}',
            'client_secret': f'{self.client_secret}',
            'client_id': f'{self.client_id}',
            'grant_type': 'refresh_token',
        }
        r = requests.request("POST",
                             'https://cloud.lightspeedapp.com/oauth/access_token.php',
                             data=payload).json()
        self.access_token = r['access_token']
        self.expires_in = r['expires_in']

creating a new connection - this works

conn = LightspeedStoreConn(store_credentials_data, devcreds)
conn.refresh_access()

Trying to refresh dynamically:

except:
    if pagedata['httpCode'] == '401':
        self.refresh_access()

This does refresh the 'access_token' variable (i traced the results in the debugger), but any subsequent attempts to interact with the API using that new code produce more 401 token errors. to be clear it IS passing the new access token on the subsequent requests.

6 comments

  • Adrian SamuelAdrian Samuel Moderator, Lightspeed Staff Posts: 584 moderator

    Hey @sam123456,

    The newly created access token is all you need after you make the refresh request. You most likely have an issue regarding variable scope. Where something is missing from the request headers or url because the class variable and the method variable aren't in the same place.

    I would suggest using the debugger or simply printing out the whole request setup to the console to see if it matches up correctly.

    Adrian Samuel

    API Integrations Consultant - Strategic Solutions

    Lightspeed HQ

  • algulsientoalgulsiento Member Posts: 8
    edited September 2019

    You need to use the "refresh token" that you get from the initial response to revive an expired token.

    Initial response:

    {

     "access_token": "<ACCESS_TOKEN>",

     "expires_in": 1800,

     "token_type": "bearer",

     "scope": "employee:all systemuserid:<USER_ID>",

     "refresh_token": "<REFRESH_TOKEN>"

    }

    When access_token expires you need to make a call to revive it like this:

    curl -F 'refresh_token=<REFRESH_TOKEN>' -F 'client_id=<CLIENT_ID>' -F 'client_secret=<CLIENT_SECRET>' -F 'grant_type=refresh_token' https://cloud.lightspeedapp.com/oauth/access_token.php

  • VintageWineGuyVintageWineGuy Member Posts: 31

    @sam123456 How has your python library building coming? I am on the same path of using python to automate some of the things I need to do in the shop, and also looking at layering some analytics on top. I don't suppose you have posted your stuff on git? You have a big headstart on me, but I would be happy to collab and share anything I do to the community. Looking for a good place to do so.

  • sam123456sam123456 Member Posts: 25

    I had about two months away from this project and am back on board with it now. I've got a few reports automated, but currently the library is mixed into a repo with a bunch of proprietary stuff, give me a few days to get it untangled and I'll share it with you. If i forget or you don't hear from me, feel free to remind me :)

  • sam123456sam123456 Member Posts: 25

    @VintageWineGuy here's the link to the public repo:

    I only threw in one example script now, but LMK if you need help with something else. This is pretty bare bones, but the methods for establishing a connection and handling pagination are working well for me and that was the hard part initially.

  • VintageWineGuyVintageWineGuy Member Posts: 31
    edited January 14

    Hey @sam123456 Thank you! I have also been working on the same thing, thank you for this. Here is the repo I have been using as well, just to share back. Same story, just working through things to try to understand the how everything works.

    Currently, this is broke because I am working on it, but passing along for the community:


    Also, I have been looking at the Shopify and bigcommerce python api libraries for inspiration. They are well done and supported by the vendor (hey lightspeed, that would be nice!). As I am looking at extending mine, I have been looking at theirs to keep some consistency and leverage some of what they have built - it is similar in concept and it feels like it would be helpful to have them work similarly.


    Post edited by VintageWineGuy on
Sign In or Register to comment.