0

I am using node js for my application as well as react.

I am trying to use child_process to call a python function from my node js code, using this post to guide me. It seems pretty straightforward, until I realized that the child_process was used to call a python script, not a main method with functions.

I am relatively new to Python, so forgive me if I mix up terminology here and there. Here is a very basic version of my python file below:

import sys
# other imports 

def __main__():
     one = function_one()
     two = function_two()
     arr = [one, two]
     print(arr)
     sys.stdout.flush()

def function_one():
     # do stuff, pretend it returns 'hello'
def function_two():
     # do stuff, pretend it returns 'world'

if __name__ == '__main__':
     __main__()

The end result should be ['hello', 'world'], but it seems like I am not getting returned anything. As you can see, I am printing arr and flushing it afterwards, so it should work.

The only way I can get it to work is if my file looks like this:

import sys
print('hello world')
sys.stdout.flush()

As you can see, without the main method or additional functions. Is there a reason to this or am I just implementing it wrongly? Thanks!

EDIT:

After trying a couple different things, I found out that some of my imports were breaking, such as pandas or seaborn. It works if I remove those specific imports, even if I'm calling __main__ through the if statement. Any ideas why?

lve
  • 307
  • 2
  • 5
  • 15
  • Your `__main__` function won't be automatically executed. No matter if you run this script from the CLI, import it in another script, or execute it with Node's `child_process` (which is almost the same thing as executing it from the CLI). You can't call Python functions declared in a .py script directly from a Node.js application without using extra libraries. You can, however, run the whole script as explained in [the post you linked](https://stackoverflow.com/questions/23450534/how-to-call-a-python-function-from-node-js). Simply get rid of `__main__` and move the code to the end of the scrip – Tomasz Kasperczyk Jul 25 '19 at 17:12
  • @TomaszKasperczyk I removed all the code inside `__main__` to the end of my file. I was still not able to make it work. I even altered my code a little to include `print('test')` then `sys.stdout.flush()` above `one = function_one()` and it didn't print that one either. Do you have another idea why? – lve Jul 25 '19 at 17:24

2 Answers2

0

You declare a function called __main__ and then never call it. I think you've mixed things up with a known pattern that prevents code from being executed when a script is imported as a module. The correct implementation of this pattern would look like this:

import sys

def myMainFunction(argv):
    # the code here

if __name__ == "__main__":
    myMainFunction(sys.argv)

__name__ is a special variable in Python. It is automatically set to "__main__" if the script was executed directly. If it was imported, it would hold the module's name instead.

Back to your problem. If you don't plan to import that script as a module, here's a solution I suggested in the comments:

Node.js:

const spawn = require('child_process').spawn;
const pythonProcess = spawn('python', ['script.py']);

pythonProcess.stdout.on('data', (data) => {
    console.log(data.toString());
});

Python:

import sys

def function_one():
    return 'hello'
def function_two():
    return 'world'

one = function_one()
two = function_two()
arr = [one, two]
print(arr)
sys.stdout.flush()
Tomasz Kasperczyk
  • 1,991
  • 3
  • 22
  • 43
  • Thanks for your reply, but I tried your above code and it didn't work. I figured out what is causing the issue is though, see my edit above for further clarification! – lve Jul 25 '19 at 19:21
0

So, my problem was that in my spawn, python was pointing to version 2.7, not 3.6. Just alter the spawn to point to python3.6 and it'll fix the import issues.

lve
  • 307
  • 2
  • 5
  • 15