How can I use websockets in a Webapp?

ArnoM
ArnoM Registered Posts: 4 ✭✭
edited January 23 in Using Dataiku

I would like to make a custom Webapp where the Python backend talks to the frontend and vice versa. I see that the Dataiku Answers webapp uses websockets and I would like to do the same. My current attempts using Flask-SocketIO did not work unfortunately, as it seems to use Werkzeug under the hood and I cannot start the server myself using socketio.run(app).

Could you please explain how I could use websockets in Webapps with a Python backend?

Operating system used: Windows 11

Answers

  • Turribeach
    Turribeach Dataiku DSS Core Designer, Neuron, Dataiku DSS Adv Designer, Registered, Neuron 2023 Posts: 2,248 Neuron

    Why do you want to use websockets in a webapp?

  • ArnoM
    ArnoM Registered Posts: 4 ✭✭

    I want to send multiple data packets from the server to the client without the client having to continuously poll the server.

  • Loic
    Loic Registered Posts: 3 ✭✭✭

    Hi ArnoM,

    You can definitely use websockets with a Dataiku WebApp.
    Dataiku webapp backend is a WSGI Flask application, so Flask-SocketIO is definitely a suitable solution for it.
    The Flask application is passed to your script so you can use it directly to augment it with web sockets.

    Here is a code example to get you started:

    from flask import Flask
    from flask_socketio import SocketIO
    
    def setup_socketio_event_handler(socket: SocketIO):
        socket.on_event('connect', your_connect_handler)
        socket.on_event('disconnect', your_disconnect_handler)
        socket.on_event('custom_event', your_custom_event_handler)
        
    def register_api_route(app: Flask):
        @app.route("/alive", methods=["GET"])
        def is_alive():
            return {"status": "ok"}
        
    
    def create_app():
        socketio = SocketIO(app, cors_allowed_origins='*', path="/socket.io")
        setup_socketio_event_handler(socketio)
        return app, socketio
        
        
    create_app()
    
    

    The backend can be accessible from the webapp frontend through getWebAppBackendUrl("/path")

  • Loic
    Loic Registered Posts: 3 ✭✭✭

    I forgot to add that you should run the Webapp backend in multithread mode (by setting the number of processes to 0)

  • ArnoM
    ArnoM Registered Posts: 4 ✭✭

    I tried your code, but unfortunately I get this error in de backend logs:

    raise RuntimeError('You need to use the eventlet server. '
    RuntimeError: You need to use the eventlet server. See the Deployment section of the documentation for more information.

    In the browser console I see this kind of error:

    WebSocket connection to 'ws://localhost:11200/html-apps-backends/DZZdlLaw/socket.io/?EIO=4&transport=websocket&sid=WtqY1keEl_g-ZUASAAAG' failed: 
    
  • Loic
    Loic Registered Posts: 3 ✭✭✭

    here is an exemple that is working:

    Python

    import dataiku
    import pandas as pd
    from flask import Flask, request
    from flask_socketio import SocketIO, emit
    
    
    def test_connect(auth):
        emit('my response', {'data': 'Connected'})
     
    def test_disconnect(reason):
        print('Client disconnected, reason:', reason)
        
    def handle_message(data):
        print('received message: ' + data)
    
    def setup_socketio_event_handler(socket: SocketIO):
        socket.on_event('connect', test_connect)
        socket.on_event('disconnect', test_disconnect)
        socket.on_event('custom_event', handle_message)
        
    def register_api_route(app: Flask):
        @app.route("/alive", methods=["GET"])
        def is_alive():
            return {"status": "ok"}
        
    
    def create_app():
        socketio = SocketIO(app, cors_allowed_origins='*', path="/socket.io")
        setup_socketio_event_handler(socketio)
        register_api_route(app)
        return app, socketio
        
        
    create_app()
    
    

    JS

    const backend = getWebAppBackendUrl('/')
    console.log({backend})
    
    var socket = io(backend, {path: backend+'socket.io'});
    socket.on('connect', function() {
        socket.emit('custom_event', {data: 'I\'m connected!'});
    });
    


    HTML

    <script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.0.1/socket.io.js" integrity="sha512-q/dWJ3kcmjBLU4Qc47E4A9kTB4m3wuTY7vkFJDTZKjTs8jhyGQnaUrxa0Ytd0ssMZhbNua9hE+E7Qv1j+DyZwA==" crossorigin="anonymous"></script>
    
  • ArnoM
    ArnoM Registered Posts: 4 ✭✭

    I tried the code but I got the same error.

    I only changed io(backend, …) with io(window.location.host), otherwise I got an error even earlier in the code.

    Connecting works (I put a console.log inside the on connect function), but sending/receiving messages does not.

Setup Info
    Tags
      Help me…