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

10
  • "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? Commented Jul 6, 2020 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 Commented Jul 6, 2020 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? Commented Jul 7, 2020 at 0: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 Commented Jul 7, 2020 at 0:21
  • I didn't ask whether the objects are identical. I asked what value process has. Please share that information with us. Commented Jul 7, 2020 at 0:23

1 Answer 1

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.

Sign up to request clarification or add additional context in comments.

2 Comments

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 :)
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 might find something useful. There's always the good old <audio> tag if you can pre-record audio and just play it back.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.