2

I am developing a simple website using Flask + gunicorn + nginx on a Raspberry Pi with Rasbian Jessie. I am stuck at launching a process with this Python code:

def which(program):
    def is_exe(fpath):
        return os.path.isfile(fpath) and os.access(fpath, os.X_OK)

    fpath, fname = os.path.split(program)
    if fpath:
        if is_exe(program):
            return program
    else:
        for path in os.environ["PATH"].split(os.pathsep):
            path = path.strip('"')
            exe_file = os.path.join(path, program)
            if is_exe(exe_file):
                return exe_file

    return None


mplayer_path = which("mplayer")

try:
    player = subprocess.Popen([mplayer_path, mp3], stdin=subprocess.PIPE)
except:
    return render_template('no_mp3s.html', mp3_message=sys.exc_info())

"mp3" is the path to an mp3 file while "mplayer_path" is the absolute path to mplayer, as returned by the which function described in this answer.

The code works in development when I launch flask directly. In production, when I access the website through nginx, I get the following error message through the no_mp3s.html template:

type 'exceptions.AttributeError'
AttributeError("'NoneType' object has no attribute 'rfind'",)
traceback object at 0x7612ab98

I suspect a permission issue with nginx, but being very new with Linux I am a bit lost!

Edit: I should add that nowhere in my code (which fits in a single file) I call rfind(). Also, I am sure that the error is caught in this specific try/except because it is the only one that outputs to no_mp3s.html.

Edit: Following blubberdiblub comments I found out that it is the which function that does not work when the app is run in nginx. Hard coding the path to mplayer seems to work!

Community
  • 1
  • 1
Zep
  • 1,541
  • 13
  • 21
  • Where are you trying to call `rfind()`? That's where I would look first. Also, does the traceback mention a line number? If yes, then including the problematic line and a little bit of context might be helpful. – blubberdiblub May 07 '17 at 10:18
  • Hi, I am not calling rfind anywhere! – Zep May 07 '17 at 10:35
  • Well, something apparently is. Maybe in a different module or package. In that case, you might have posted the wrong part of the traceback. In any case, the information you provided is likely not sufficient to help you. – blubberdiblub May 07 '17 at 10:41
  • So you're basically suspecting that the first line you posted returns `None` instead of a path? In that case both the `try`-`except` as well as the traceback would be irrelevant to the question. And I don't think that linking to a different question which is likely to contain a significant part of the problem is a good way to get your question answered. Please provide a [minimal, **complete** and verifiable example](https://stackoverflow.com/help/mcve). – blubberdiblub May 07 '17 at 10:54
  • Good point, it is indeed the which() function that does not work in nginx. I still do not know why, but hard-coding mplayer's path solves the problem. – Zep May 07 '17 at 11:22
  • Hard-coding the absolute path is likely a good thing, as that's what you usually do when you can't be sure of the contents of `PATH`, can't trust it or when it's empty. And it's highly likely that in an application server environment the `PATH` environment variable is either different from what you're used to in the terminal or even completely empty (as you don't want to inadvertently have the wrong programs executed that the user might have installed into funny places). – blubberdiblub May 07 '17 at 11:30

0 Answers0