5

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').

ChrisGPT was on strike
  • 127,765
  • 105
  • 273
  • 257
tsnakejake
  • 187
  • 1
  • 2
  • 8
  • "I have tried adding a heroku/python buildpack but this has not worked either"—so what happened? Did you get an error message? What did it say? – ChrisGPT was on strike Jul 06 '20 at 23:54
  • It just simply didn't do anything. The buildpack was added to the app but it didn't aid in anything, it was just the same result. The function readOut was called but the process did not happen and the message was sent back through res.send – tsnakejake Jul 06 '20 at 23:56
  • "It just simply didn't do anything"—well, what did it return? What value did `process` have in the code you shared? – ChrisGPT was on strike Jul 07 '20 at 00:05
  • I just chaned it so instead of res.send("Action completed!") I did res.send(process) so I could view the object and both objects are identical when I look at the localhost:5000 that works and the heroku that doesn't. They both return objects with fields like connected, stderr, stdin, but either way they're the same. It's not like process returns null or anything – tsnakejake Jul 07 '20 at 00:21
  • I didn't ask whether the objects are identical. I asked what value `process` has. Please share that information with us. – ChrisGPT was on strike Jul 07 '20 at 00:23
  • I attempted to include a screenshot in the original post. It's hard to screenshot the entire thing but I could include more if helpful – tsnakejake Jul 07 '20 at 00:26
  • What does the spawned process _do_ on Heroku? Have you registered code to capture its `stdout` or `stderr`? Its return code? Please see https://nodejs.org/api/child_process.html#child_process_child_process_spawn_command_args_options – ChrisGPT was on strike Jul 07 '20 at 00:31
  • "It must be a specific problem with os.system('say')"—what is `say` supposed to do? That's not a standard command. – ChrisGPT was on strike Jul 07 '20 at 12:09
  • When I run my server on local host, the command os.system('say hello') has the computer read aloud "hello" – tsnakejake Jul 07 '20 at 16:02
  • ...okay, but what is that command? Where does it come from? And what do you expect to happen if you're able to get it to run on Heroku? That would just read "hello" aloud in a data center somewhere or, more likely, not do anything due to a lack of speaker hardware. It looks like maybe this is a macOS thing? Heroku doesn't run macOS. – ChrisGPT was on strike Jul 07 '20 at 16:07

1 Answers1

1

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.

ChrisGPT was on strike
  • 127,765
  • 105
  • 273
  • 257
  • Ohh, that actually makes a lot of sense. It would run on some Heroku server instead. Thank you!! Do you have any suggestions of things that might work on the server? Just to learn more but not necessary :) – tsnakejake Jul 07 '20 at 16:27
  • Product recommendations are off-topic here, and I don't know enough about your use case to give one, nor do I have experience with text to speech. [A search](https://duckduckgo.com/?q=javascript+client-side+text+to+speech) might find something useful. There's always the good old [` – ChrisGPT was on strike Jul 07 '20 at 16:30