Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spawning python script in nodejs on heroku

Summary Question: Why does Heroku indicate os.system('say ...') is "not found" and how can I fix it?

I have a Node.js app where I am using child_process to spawn a Python script that reads out audio when it's given a specific word. I know that it works when I run my server on localhost:5000, but when I deploy it on Heroku I get an error in the picture at the bottom of this post. I have tried adding the heroku/python buildpack but this has not worked either.

My JS code in Node.js looks like this:

app.get('/perform/:word', readOut)
function readOut(req, res) {

    var spawn = require("child_process").spawn;

    var process = spawn('python', ["./readout.py", req.params.word]);

    res.send("Action completed!")
}

Note that the "Action completed" does get sent back to my client, so it is running through the code.

I realized there was an error by capturing the stderr and printing it to the console. This is only happening with Heroku and I'm not sure what it means. I'm not quite sure how there could be an error with the python script when it works normally on localhost, but then again, I think that lack of realization is what my downfall is.

This is what my Python file looks like:

import os
import sys

os.system('say {}'.format(sys.argv[1]))

The error message is this:

stderr: sh: 1: say: not found

Anyone know why this is happening with Heroku? Am I missing a certain package or anything? How do I let Heroku know about os.system() calls?

Edit: I actually added a piece of code to the Python script that says

os.system('date')

and it correctly logged to the stdout. It must be a specific problem with os.system('say').

like image 780
tsnakejake Avatar asked Nov 06 '22 06:11

tsnakejake


1 Answers

There are at least two issues here:

  1. It looks like macOS has a say command, but this doesn't exist on Linux. Heroku doesn't run macOS.

  2. Even if say were available, it wouldn't do anything useful. It would try to say whatever it's told to say on the server, in a data center somewhere. The server probably doesn't have the hardware to play any audio, and if it does, nobody is going to hear it.

    This only seems to work on your local machine because your client and server are on the same machine. If you're expecting to hear something on your client machine you'll have to do it with client-side JavaScript.

    See What is the difference between client-side and server-side programming?

Finally, Python isn't doing anything useful here. If say was available and did what you want, you could just call it with spawn() or something in your JavaScript code.

like image 109
Chris Avatar answered Nov 12 '22 17:11

Chris