How can I use websockets in a Webapp?

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

Welcome!

It looks like you're new here. Sign in or register to get started.

Answers

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

    Why do you want to use websockets in a webapp?

  • 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.

  • 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")

  • 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)

  • 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: 
  • 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>
  • 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.

Welcome!

It looks like you're new here. Sign in or register to get started.

Welcome!

It looks like you're new here. Sign in or register to get started.