Push API & Websockets

Hi,

I'm back with my silly project on displaying statuses via Python websocket API so I can show something going on in my big screen attached totally unnecessarily to my OctoPi setup next to the printer.

However since I last made a progress on this API it did work and I managed to receive all GCODE commands via the push, but now I can't get it to work at all.

I saw @Fabian 's post on the authentication needed to be double-wrapped in json but even that does not work. I am also confused whether an additional header is needed for web-socket in top of the authentication message?

There was a reference to documentation on messaging @foosel directly in case someone is planning on using this API and get the latest plans. Well, here we go I guess :slight_smile:

So the question is: how to do the authentication with Python3 to the PUSH API via websocket using the websocket-client library and get the GCODE notifications (or anything for that matter) after socket has been initiated?

Cheers :slight_smile:

I can't help you with your question - I just want to inform you that @foosel is on vacation right now. She will be back approximately around the 10th of January. :slight_smile:

1 Like

I posted in the other thread, but I think you might just be missing the API auth process that needs to happen ahead of the websocket auth, in order to get a session key.

The code I used is public, you can see it at the following address:

Line 45 is the most important one where the authentication is done.

It's Javascript, and I haven't done anything there in a while, so I can't guarantee that this code works in recent Octoprint versions.

My experience is with a browser client, which reacts very sensitively to stuff like CORS or mixed content (using unencrypted websockets from an encrypted page). This should be less problematic in a Python client, but I'd still try both the ws: and the wss: version, in case one version is not allowed. You might also run into issues with self-signed certificates, in which case you either need to disable certificate validation in Python or use a certifate that your computer will regard as valid.

1 Like

Thanks for the heads up :slight_smile: Likewise I am on holiday until January, but in my case this is the time I have finally time for my hobby projects from work :smiley:

2 Likes

Wait what.....Foosel is a lady?
I totally did not know that!

lol, you've never watched an octoprint video...

3 Likes

1 Like

Here I am, back from my own holidays eager to see how my 3 new replies to the thread help me onwards with my problem, but all I see was a discovery of Foosel's gender :joy:

Anyway, couldn't get Fabian's code to work with my python version, so still something missing. Will give it another look next week.

Well, I put some effort to this now after sauna (which always helps), and managed to get this working!

Essentially I guess I was getting mixed with different tokens and in what form to send them, of which finally the following snippet worked.

Especially the format of auth_message was the key: use username + session token. Nothing else worked. I'm sure there is a prettier way but if someone else is stuck with this, here's one way of getting it work.

Cheers.

import websocket, json, requests

try:
    import thread
except ImportError:
    import _thread as thread
import time

HOST = "ws://octopi/sockjs/websocket"

def on_open(ws):
    auth_message = "{ \"auth\": \"xxx:"+session+"\" }"
    ws.send(auth_message)

def on_message(ws, message):
    print("Incoming message: ")
    print(message)

def on_error(ws, error):
    print(error)

def on_close(ws):
    print("Closing Socket...")

if __name__ == "__main__":
    logindata = { 'user': 'xxx', 'pass': 'yyy' }
    r = requests.post('http://octopi:80/api/login', json=logindata, verify=False)
    data = r.json()
    session = data['session']
    websocket.enableTrace(True)
    ws = websocket.WebSocketApp(HOST,
        on_open = on_open,
        on_message = on_message,
        on_error = on_error,
        on_close = on_close)
    ws.run_forever()```
2 Likes

(post withdrawn by author, will be automatically deleted in 24 hours unless flagged)