extrabacon / python-shell

Run Python scripts from Node.js with simple (but efficient) inter-process communication through stdio
2.12k stars 224 forks source link

How to return python output after running python-shell. #275

Closed mazarady closed 1 year ago

mazarady commented 2 years ago

The Question: I'm having difficulty getting the output from the python shell. I expect it to be returned from the

shell.on("message", function (message) {
    console.log(message);
  });

but I never see the message consoled.

Any relevant python/javascript code:

JS Code:

import { PythonShell } from "python-shell";
import fs from "fs";

export default async (req, res) => {
  const { code, input } = JSON.parse(req.body);
  fs.writeFileSync("test.py", JSON.stringify(code));

  const shell = new PythonShell("test.py");

  shell.send("There");

  shell.on("message", function (message) {
    console.log(message);
  });

  shell.end(function (err, code, signal) {
    if (err) throw err;
    console.log("The exit code was: " + code);
    console.log("The exit signal was: " + signal);
    console.log("finished");
  });

The code that I have that i'm passing in:

import sys
x = input('Hello: ')
print(x)
sys.stdout.flush()

Ultimately, I am attempting return the expected output, There, by doing something like, res.status(200).send(data), but I don't even know how to access said data after the python-shell is instantiated. Any help here would be much appreciated.

mazarady commented 2 years ago

For context, I'm using @monaco-editor/react in the front-end and nextjs in the backend. The code works as expected when I utilize the following snippet

PythonShell.run('test.py', options, function (err, result){
          if (err) throw err;
          // result is an array consisting of messages collected
          //during execution of script.
          console.log('result: ', result.toString());
          res.send(result.toString())
    });

but as I attempt to support stdin, I realized I couldn't rely on the snippet above and had to make use of the .send method.

Soo kinda stuck.

Almenon commented 2 years ago

The below code works for me, so not sure what your bug is. Maybe something with whatever webserver framework you're using.

Sidenote: Allowing dynamic input from a public website is insecure. Hackers could pass in whatever python code they wanted and take control of your system. Make sure you don't make your website public.

import fs from "fs";
import { PythonShell } from "python-shell";

const code = `
import sys
x = input('Hello: ')
print(x)
sys.stdout.flush()`

fs.writeFileSync("C:\\Users\\Caleb\\dev\\candel\\test.py", code);

const shell = new PythonShell("C:\\Users\\Caleb\\dev\\candel\\test.py");

shell.send("There");

shell.on("message", function (message) {
    console.log(message);
});

shell.end(function (err, code, signal) {
if (err) throw err;
    console.log("The exit code was: " + code);
    console.log("The exit signal was: " + signal);
    console.log("finished");
});
Almenon commented 1 year ago

No response, closing. The issue is still open to comments if you have a reply.