Calling a Javascript function from flask / python

Viewed 13719

I know Python very well, but I'm new to web-stuff and JavaScript. I found a post about Calling a python function from button on website (Flask).

I want to do the following: I want to add a new row to an HTML table. The data will be coming from Python. I already found out that refreshing the site isn't a good way to do it, instead it seems JavaScript should be used. Say I have the following HTML code:

<table class="table" id="myTable">
  <thead>
    <tr>
      <th colspan="2">This is a table</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>entry 1</td>
      <td>entry 2</td>
    </tr>
  </tbody>
</table>
<script src="js/scripts.js"></script>

and in the scripts.js I have the following function (from the linked post):

function appendRow(table_id) {
  var table_ref = document.getElementById(table_id).getElementsByTagName('tbody')[0];
  var new_row = table_ref.insertRow(table_ref.rows.length);
  var new_cell = new_row.insertCell(0);
  var new_text = document.createTextNode('New row');
  new_cell.appendChild(new_text);
}

Now disregarding the details how the function works / what can be optimized etc. my real question is: How can I call this function from Python / flask?

Additionally: How can I pass data (say a JSON-structure) to the JavaScript function?

Many thanks in advance!

2 Answers

You could use socket.io.

The python implementation would be the server side, and it can be done using python-socketio.

This code is a basic implementation starting the socket server at localhost:5000

import eventlet
import socketio
import json

sio = socketio.Server()
app = socketio.WSGIApp(sio)

@sio.event
def connect(sid, environ):
    print('connect ', sid)

@sio.event
async def message(sid, data):
    print("message ", data, json.loads(data))
    # send a reply to the sender client socket 
    # await sio.emit('reply', room=sid)

@sio.event
def disconnect(sid):
    print('disconnect ', sid)

if __name__ == '__main__':
    eventlet.wsgi.server(eventlet.listen(('', 5000)), app)

The your client in the javascript side, using socket.io client api

<script src="/socket.io/socket.io.js"></script>
<script>
  const socket = io('http://localhost:5000');
  var to_python = {
    title: "this is just",
    body: "sample data to send to python"
    user: {
      "name": "",
      "email": "" 
    }
  }
  socket.emit('message', JSON.stringify(to_python));
</script>

I use this implementation in several applications, mind that, the socket.io protocol implementation must be compatible in both client-side (js) and server-side (python).

Related