PySpeckle authentication

I would say that I second this request… but it was actually me that asked David… :grin:

Would a quick fix be possible? For example, that there would be an option to feed an API token to client.login instead of a username and password?

Or some other way? David identified that SpeckleBlender updates the https headers to add the token as the Authorization header. Is there a way that I could use this technique (i.e. could someone help me work out how to do this in the short term)?

1 Like

We have some analysis models that are defined in text files, and I was wondering if I could use Python to parse them and then send Speckle formatted information up to the server (I already have some parsers for reading the files). I am a complete newbie and am trying to get a handle on what would be involved. Anything that could help me (and other newbies) with that would be appreciated.

As per the posting below by David, having easy access to authentication flows would certainly be helpful.

To answer the 1.0 question, there isn’t a way to use client.login directly with the token as the /login route requires the user’s email and password.

However, I can give a cheeky suggestion! The pyspeckle client stores the response of the login request in client.me. You could chuck the token in there directly and use the client that way. I haven’t looked into this very hard so I’m not immediately sure if this will break anything - tread carefully!

client = SpeckleApiClient("hestia.speckle.works")
client.me = {
        "token": "JWT your token here"
        }
2 Likes

for reference, here are the contents of client.me when logged in properly:

contents of

you could add some of these fields to the dict along with the token if they are required somewhere else in your code

1 Like

Thanks for this. In fact, I think I tried this - I extended the SpeckleApiClient to allow me to insert my api token:

class SpeckleApiTokenClient(SpeckleApiClient):
    def apiTokenLogin(self, api_token):
        self.s.headers.update({
            'content-type': 'application/json',
            'Authorization': api_token,
        })

However, it seems that my api token does not work in this location. When I compare it to the token that is pulled in by the login function I find that it is much longer than my api token. Am I doing something wrong? Am I doing what you suggested?

I tried what you suggested, and I get the same error as with my approach:

ConnectionError: HTTPSConnectionPool(host='https', port=443): Max retries exceeded with url: //hestia.speckle.works/api/v1/streams/taNRrjz3u (Caused by NewConnectionError('<urllib3.connection.VerifiedHTTPSConnection object at 0x0000014F8CC2D2E8>: Failed to establish a new connection: [Errno 11001] getaddrinfo failed',))

Thinking again: I see that there are two relevant items: token & apitoken

I have apitoken from the SpeckleServer interface, but I don’t think I have token.

How can I get token?

Pretty sure the two are the same. Just put both keys into the me dict :slight_smile:

Ah regarding your extension of the client, I am afk at the moment so I can’t double check right now but I think you need to populate the me dict (not just the headers) bc the client methods use me['token'] in a few places

@andrew.mole ah just looked at your error message and I think there might be something else going on here. If you weren’t authenticated properly, you would be getting a 401 unauthorised error.

Going to the stream myself, it looks like it doesn’t exist?

stream dne

If it was an authorisation problem, you would be getting an error message like this:

stream not public

Thanks! It seems to work putting the same token in for both token and apitoken.

1 Like

Great, glad you got that working :blush:

as a followup, I have created a function called login_with_token, and submitted a pull request to PySpeckle.

1 Like