I am trying to set up a website for my school where users can run some python code and the executing part of the code is working fine but, the only problem is that python-shell waits for the code to be complete then send-out the output.
What current output looks like:

What I am trying to achieve

:
Python-Shell config:
let {
PythonShell
} = require('python-shell')
var run = 1;
pyshell: PythonShell
constructor(); {
this.pyshell = new PythonShell(__dirname + "/physics.py")
pythonPath: '/usr/bin/python3';
pythonOptions: ['i', ]
if (run == 1) {
socket.on("hello", function(pyinput2) {
var input = pyinput2
console.log(input, "sending");
this.pyshell.send(input)
console.log(input, "sent")
});
}
this.pyshell.on("message", (...args) => {
console.log(args)
socket.send(args)
this.pyshell.end
})
this.pyshell.on('message', function(message) {
// received a message sent from the Python script (a simple "print" statement)
console.log(message + "\n");
});
Here is the Python script im using for testing:
# Program make a simple calculator
# This function adds two numbers
def add(x, y):
return x + y
# This function subtracts two numbers
def subtract(x, y):
return x - y
# This function multiplies two numbers
def multiply(x, y):
return x * y
# This function divides two numbers
def divide(x, y):
return x / y
print("Select operation.")
print("1.Add")
print("2.Subtract")
print("3.Multiply")
print("4.Divide")
while True:
# take input from the user
choice = input("Enter choice(1/2/3/4): ")
# check if choice is one of the four options
if choice in ('1', '2', '3', '4'):
num1 = float(input("Enter first number: "))
num2 = float(input("Enter second number: "))
if choice == '1':
print(num1, "+", num2, "=", add(num1, num2))
elif choice == '2':
print(num1, "-", num2, "=", subtract(num1, num2))
elif choice == '3':
print(num1, "*", num2, "=", multiply(num1, num2))
elif choice == '4':
print(num1, "/", num2, "=", divide(num1, num2))
# check if user wants another calculation
# break the while loop if answer is no
next_calculation = input("Let's do next calculation? (yes/no): ")
if next_calculation == "no":
break
I'm new to javascript so sorry if I lack some knowledge... any help would be greatly appreciated - Thanks
EDIT - Here is my full code:
Server.js
const app = require('express')();
const http = require('http').Server(app);
const io = require('socket.io')(http);
const {
exec
} = require("child_process");
const {
stdout
} = require('process');
// const { spawn } = require('child_process');
var async = require("async");
app.get('/', function(req, res) {
res.sendfile('index.html');
});
//Whenever someone connects this gets executed
io.on('connection', function(socket) {
console.log('A user connected');
//Whenever someone disconnects this piece of code executed
socket.on('disconnect', function() {
console.log('A user disconnected');
});
});
io.sockets.on('connection', function(socket) {
socket.on('message', function(message) {
// console.log(message,);
});
var data = 1
socket.on('my other event', function(data) {
// console.log(data);
var command = JSON.stringify(data)
console.log(command)
console.log(command)
/* var options = {
mode: 'text',
pythonPath: '/usr/bin/python',
pythonOptions: ['-u',],
// make sure you use an absolute path for scriptPath
scriptPath: '/home/compile',
//args: ['value1', 'value2', 'value3']
};
PythonShell.run('physics.py', options, function (err, results) {
this.pyshell.send("1")
this.pyshell.send("2")
this.pyshell.send("3")
this.pyshell.send("no")
if (err) throw err;
// results is an array consisting of messages collected during execution
console.log('results: %j', results);
}); */
let {
PythonShell
} = require('python-shell')
var run = 1;
pyshell: PythonShell
constructor(); {
this.pyshell = new PythonShell(__dirname + "/physics.py")
pythonPath: '/usr/bin/python3';
pythonOptions: ['i', ]
if (run == 1) {
socket.on("hello", function(pyinput2) {
var input = pyinput2
console.log(input, "sending");
this.pyshell.send(input)
console.log(input, "sent")
});
}
this.pyshell.on("message", (args) => {
console.log(args + "hi")
socket.send(args)
this.pyshell.end
})
this.pyshell.on('message', function(message) {
// received a message sent from the Python script (a simple "print" statement)
console.log(message + "hello\n");
});
/* this.pyshell.end((err, code, signal) => {
console.log("The error was: " + err)
console.log("The exit code was: " + code)
console.log("The exit signal was: " + signal)
console.log("finished")
}) */
}
});
});
io.sockets.on('connection', function(socket) {
socket.on('clicked', function(msg) {
// console.log("button clicked");
var pyinput2 = msg
var input = ''
var input = JSON.stringify(pyinput2)
// console.log(input, "is this input?")
var run = 0
});
socket.on('run', function(hello) {
var run = 1
console.log(run)
/*if (run == 0) {
run = 1
console.log(run)
} else if (run == 1) {
run = 0
console.log(run)
} */
});
});
var go = 1
if (go == 1) {
let {
PythonShell
} = require('python-shell')
pyshell: PythonShell
constructor(); {
this.pyshell = new PythonShell(__dirname + "/physics.py")
//pythonOptions: ['i',]
this.pyshell.send("1")
console.log("sent1")
this.pyshell.send("2")
console.log("sent2")
this.pyshell.send("3")
console.log("sent3")
this.pyshell.on("message", (args) => {
console.log(args, "hello")
this.pyshell.end
})
}
};
http.listen(8080, function() {
console.log('listening on *:8080');
});
Here is index.html:
<!DOCTYPE html>
<html>
<style>
body,
html {
margin-left: 1%;
margin-right: 1%;
margin-bottom: 1%;
margin-top: 1%;
width: 98%;
height: 98%;
}
</style>
<head>
<title>LC</title>
</head>
<script src="/socket.io/socket.io.js"></script>
<script src="https://cdn.jsdelivr.net/npm/jquery@3.3.1/dist/jquery.min.js"></script>
<script src='https://cdn.jsdelivr.net/xterm/2.3.2/xterm.js' type="text/javascript"></script>
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/fomantic-ui@2.8.8/dist/semantic.min.css">
<script src="https://cdn.jsdelivr.net/npm/fomantic-ui@2.8.8/dist/semantic.min.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/xterm/2.3.2/xterm.css" />
<script>
const socket = io();
</script>
<body>
<br />
<h1 style="color: #2D2E2C"><em style="color: #5DA5D5">web</em></h1>
<br />
<! <input type="text" id="myText" value="Some text...">
<! <button onclick="myFunction()"></button>
<div class="ui input"><input type="text" id="input" value=""> </div>
<button class="ui primary button" onclick="input()">input</button>
<button class="ui button" onclick="run()">run</button>
<script>
function run() {
socket.emit('run')
socket.send(run)
}
function input() {
var pyinput = ''
var pyinput = document.getElementById("input").value;
//socket.emit('clicked', pyinput);
}
</script>
<p id="demo"></p>
<script type="text/javascript">
var lol = 1
var data = 'poopy was here'
function myFunction() {
var lol = document.getElementById("myText").value;
document.getElementById("demo").innerHTML = lol;
}
//socket.emit('my other event', { lol });
</script>
<script>
function pooFunction() {
var lol = document.getElementById("myText").value;
//socket.emit('my other event', lol );
socket.send('hi');
}
socket.emit('my other event', {
my: data
});
socket.on('message', function(message) {
console.log(message);
var out = message
document.getElementById("out").innerHTML = out;
});
</script>
<p id="out"></p>
<div id="terminal"></div>
<script>
var term = new Terminal({
cursorBlink: "block"
});
term.open(document.getElementById('terminal'));
var curr_line = "";
var entries = [];
// term.open(document.getElementById("terminal"));
term.write("web shell $ ");
//term.write('Hello from lollolol \x1B[1;3;31mxterm.js\x1B[0m $ ')
socket.on('message', function(message) {
console.log(message);
var out = JSON.stringify(message)
term.write(out + "\r\n")
});
term.prompt = () => {
if (curr_line) {
let data = {
method: "command",
command: curr_line
};
ws.send(JSON.stringify(data));
}
};
term.prompt();
// term.write("web shell $ ");
// Receive data from socket
term.on("key", function(key, ev) {
//Enter
if (ev.keyCode === 13) {
if (curr_line) {
entries.push(curr_line);
console.log(curr_line)
socket.emit('hello', curr_line);
term.write("\r\n");
curr_line = "";
term.write("web shell $ ");
term.prompt();
}
} else if (ev.keyCode === 8) {
// Backspace
if (curr_line) {
curr_line = curr_line.slice(0, curr_line.length - 1);
term.write("\b \b");
}
} else {
curr_line += key;
term.write(key);
}
});
</script>
</body>
</html>
List of dependencies:
"dependencies": {
"express": "^4.17.3",
"jquery": "^3.6.0",
"linerstream": "^0.2.0",
"python-shell": "^3.0.1",
"xterm": "^4.18.0"
},
"devDependencies": {
"socket.io": "^4.4.1"
}
Also I am running this on a centos server and have also tested it on fedora server, behavior occurred on both machines.
I am trying to set up a website for my school where users can run some python code and the executing part of the code is working fine but, the only problem is that python-shell waits for the code to be complete then send-out the output.
What current output looks like:
What I am trying to achieve

:
Here is the Python script im using for testing:
I'm new to javascript so sorry if I lack some knowledge... any help would be greatly appreciated - Thanks
EDIT - Here is my full code:
Server.js
const app = require('express')(); const http = require('http').Server(app); const io = require('socket.io')(http); const { exec } = require("child_process"); const { stdout } = require('process'); // const { spawn } = require('child_process'); var async = require("async"); app.get('/', function(req, res) { res.sendfile('index.html'); }); //Whenever someone connects this gets executed io.on('connection', function(socket) { console.log('A user connected'); //Whenever someone disconnects this piece of code executed socket.on('disconnect', function() { console.log('A user disconnected'); }); }); io.sockets.on('connection', function(socket) { socket.on('message', function(message) { // console.log(message,); }); var data = 1 socket.on('my other event', function(data) { // console.log(data); var command = JSON.stringify(data) console.log(command) console.log(command) /* var options = { mode: 'text', pythonPath: '/usr/bin/python', pythonOptions: ['-u',], // make sure you use an absolute path for scriptPath scriptPath: '/home/compile', //args: ['value1', 'value2', 'value3'] }; PythonShell.run('physics.py', options, function (err, results) { this.pyshell.send("1") this.pyshell.send("2") this.pyshell.send("3") this.pyshell.send("no") if (err) throw err; // results is an array consisting of messages collected during execution console.log('results: %j', results); }); */ let { PythonShell } = require('python-shell') var run = 1; pyshell: PythonShell constructor(); { this.pyshell = new PythonShell(__dirname + "/physics.py") pythonPath: '/usr/bin/python3'; pythonOptions: ['i', ] if (run == 1) { socket.on("hello", function(pyinput2) { var input = pyinput2 console.log(input, "sending"); this.pyshell.send(input) console.log(input, "sent") }); } this.pyshell.on("message", (args) => { console.log(args + "hi") socket.send(args) this.pyshell.end }) this.pyshell.on('message', function(message) { // received a message sent from the Python script (a simple "print" statement) console.log(message + "hello\n"); }); /* this.pyshell.end((err, code, signal) => { console.log("The error was: " + err) console.log("The exit code was: " + code) console.log("The exit signal was: " + signal) console.log("finished") }) */ } }); }); io.sockets.on('connection', function(socket) { socket.on('clicked', function(msg) { // console.log("button clicked"); var pyinput2 = msg var input = '' var input = JSON.stringify(pyinput2) // console.log(input, "is this input?") var run = 0 }); socket.on('run', function(hello) { var run = 1 console.log(run) /*if (run == 0) { run = 1 console.log(run) } else if (run == 1) { run = 0 console.log(run) } */ }); }); var go = 1 if (go == 1) { let { PythonShell } = require('python-shell') pyshell: PythonShell constructor(); { this.pyshell = new PythonShell(__dirname + "/physics.py") //pythonOptions: ['i',] this.pyshell.send("1") console.log("sent1") this.pyshell.send("2") console.log("sent2") this.pyshell.send("3") console.log("sent3") this.pyshell.on("message", (args) => { console.log(args, "hello") this.pyshell.end }) } }; http.listen(8080, function() { console.log('listening on *:8080'); });Here is index.html:
<!DOCTYPE html> <html> <style> body, html { margin-left: 1%; margin-right: 1%; margin-bottom: 1%; margin-top: 1%; width: 98%; height: 98%; } </style> <head> <title>LC</title> </head> <script src="/socket.io/socket.io.js"></script> <script src="https://cdn.jsdelivr.net/npm/jquery@3.3.1/dist/jquery.min.js"></script> <script src='https://cdn.jsdelivr.net/xterm/2.3.2/xterm.js' type="text/javascript"></script> <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/fomantic-ui@2.8.8/dist/semantic.min.css"> <script src="https://cdn.jsdelivr.net/npm/fomantic-ui@2.8.8/dist/semantic.min.js"></script> <link rel="stylesheet" href="https://cdn.jsdelivr.net/xterm/2.3.2/xterm.css" /> <script> const socket = io(); </script> <body> <br /> <h1 style="color: #2D2E2C"><em style="color: #5DA5D5">web</em></h1> <br /> <! <input type="text" id="myText" value="Some text..."> <! <button onclick="myFunction()"></button> <div class="ui input"><input type="text" id="input" value=""> </div> <button class="ui primary button" onclick="input()">input</button> <button class="ui button" onclick="run()">run</button> <script> function run() { socket.emit('run') socket.send(run) } function input() { var pyinput = '' var pyinput = document.getElementById("input").value; //socket.emit('clicked', pyinput); } </script> <p id="demo"></p> <script type="text/javascript"> var lol = 1 var data = 'poopy was here' function myFunction() { var lol = document.getElementById("myText").value; document.getElementById("demo").innerHTML = lol; } //socket.emit('my other event', { lol }); </script> <script> function pooFunction() { var lol = document.getElementById("myText").value; //socket.emit('my other event', lol ); socket.send('hi'); } socket.emit('my other event', { my: data }); socket.on('message', function(message) { console.log(message); var out = message document.getElementById("out").innerHTML = out; }); </script> <p id="out"></p> <div id="terminal"></div> <script> var term = new Terminal({ cursorBlink: "block" }); term.open(document.getElementById('terminal')); var curr_line = ""; var entries = []; // term.open(document.getElementById("terminal")); term.write("web shell $ "); //term.write('Hello from lollolol \x1B[1;3;31mxterm.js\x1B[0m $ ') socket.on('message', function(message) { console.log(message); var out = JSON.stringify(message) term.write(out + "\r\n") }); term.prompt = () => { if (curr_line) { let data = { method: "command", command: curr_line }; ws.send(JSON.stringify(data)); } }; term.prompt(); // term.write("web shell $ "); // Receive data from socket term.on("key", function(key, ev) { //Enter if (ev.keyCode === 13) { if (curr_line) { entries.push(curr_line); console.log(curr_line) socket.emit('hello', curr_line); term.write("\r\n"); curr_line = ""; term.write("web shell $ "); term.prompt(); } } else if (ev.keyCode === 8) { // Backspace if (curr_line) { curr_line = curr_line.slice(0, curr_line.length - 1); term.write("\b \b"); } } else { curr_line += key; term.write(key); } }); </script> </body> </html>List of dependencies:
"dependencies": { "express": "^4.17.3", "jquery": "^3.6.0", "linerstream": "^0.2.0", "python-shell": "^3.0.1", "xterm": "^4.18.0" }, "devDependencies": { "socket.io": "^4.4.1" }Also I am running this on a centos server and have also tested it on fedora server, behavior occurred on both machines.