Asterisk 13 AGI Python: No such file or directory

Hello, I installed Asterisk 13 on Raspberry Pi 3 and recently I’m trying to call Python script from Asterisk dialplan. The script contains email sending function and call of that function. I put it in /var/lib/asterisk/agi-bin/ and I gave permission to execute with chmod 777 to whole folder. In dialplan I’ve got this simply example: exten => 190,1,AGI(sendemail.py). When I try to call this extension I’m receiving error like that:

Executing [190@default:1] AGI(“SIP/1235-00000003”, “sendemail.py”) in new stack
– Launched AGI Script /var/lib/asterisk/agi-bin/sendemail.py
sendemail.py: Failed to execute ‘/var/lib/asterisk/agi-bin/sendemail.py’: No such file or directory
– Auto fallthrough, channel ‘SIP/1235-00000003’ status is ‘UNKNOWN’

What does mean “No such file or directory”?
I just want to execute python script from asterisk dialplan, nothing more. We are not talking about programming asterisk from python.
When I do the same with bash file: exten => 88,1,AGI(/home/pi/opendoor.sh) it executes without any error! Opendoor script is changing state of GPIO pin to turn on/off relay for door.

Any help would be appreciated.

Double check the name of your script. Here you have senemail.py:

But your CLI output shows the invocation as sendemail.py. Note that d in the output.

Is it supposed to be sendmail.py?

Yes, sorry it’s just a mistake here in post, need to be corrected. I checked it now in program/console and everything is right.

AGI doesn’t do anything fancy when spawning the script. It forks the process, then calls execv to execute the file:

	if ((pid = ast_safe_fork(1)) < 0) {
		ast_log(LOG_WARNING, "Failed to fork(): %s\n", strerror(errno));
		return AGI_RESULT_FAILURE;
	}
	if (!pid) {
               ... a bunch of environment set up ...


		/* Close everything but stdin/out/error */
		ast_close_fds_above_n(STDERR_FILENO + 1);

		/* Execute script */
		/* XXX argv should be deprecated in favor of passing agi_argX paramaters */
		execv(script, argv);
		/* Can't use ast_log since FD's are closed */
		ast_child_verbose(1, "Failed to execute '%s': %s", script, strerror(errno));
		/* Special case to set status of AGI to failure */
		fprintf(stdout, "failure\n");
		fflush(stdout);
		_exit(1);
	}

execv is what is returning the error you’re seeing - namely that the file or directory doesn’t exist. That implies that - for whatever reason - your system doesn’t believe that sendemail.py exists. At that point, Asterisk is completely out of the loop in finding or executing the file.

I would triple check that:

  • You have the file name and directory correct
  • The file is executable
  • The file has sufficient permissions to be executed by the user/group that Asterisk is running under
  • The directory path to the file has sufficient permissions to be found by the user/group that Asterisk is running under

Could it also produce the error if the #! line contains the wrong name for the Python interpreter?

It definitely wouldn’t work if the interpreter specified is wrong. I’m not sure what error it would kick back. From the man page:

Interpreter scripts

An interpreter script is a text file that has execute permission enabled and whose first line is of the form:
#! interpreter [optional-arg]
The interpreter must be a valid pathname for an executable which is not itself a script. If the filename argument of execve() specifies an interpreter script, then interpreter will be invoked with the following arguments:
interpreter [optional-arg] filename arg…
where arg… is the series of words pointed to by the argv argument of execve().

How can I check user/group that Asterisk is running under?
And how to add file to this group if so?

ps, although you will need to look up the options, or simply look at what you configured it to run as;

chown

See their man pages for details.