PHP exec python not working - php

hey yall. Im running python on a webserver from dreamhost. I am using their install of python and am using a lastfm module that can be found here: http://code.google.com/p/python-lastfm/
to get it to import properly i do this
import sys
sys.path.append("/home/myusername/build/Python-2.5/Lib/site-packages/")
import lastfm
since the lastfm module is installed there.
When I use putty to ssh into my server, i can simply run python test.py and it works perfectly. But when i run it from a php script with
exec("python test.py");
it suppossedly does not work and the script doesnt run. it runs perfectly fine when i do
import lastfm
and then have other things after,
but when i actually try to do something with the module like:
import lastfm
api=lastfm.Api(api_key)
it does not run. once again i can run the script using the same python install in a shell and it executes fine. So something must be happening that goes wrong when i run it from the php script. I figured it would be running the exact same python and everything. I checked other posts and they say it may be something with file permissions, but ive put every file to 777 and it still doesnt work. idk what the problem could be. thanks in advance everyone.

Try using the full path to the python executable. For example:
exec("/usr/bin/python test.py")
You can find the full path from the command line using the which command:
$ which python
/usr/bin/python

Whatever error python is raising would be going to the child's stderr. Try either telling php to read from stderr, or (in python) do this:
import sys
sys.stderr = sys.stdout

For Windows users:
$output = null;
exec('C:\\Python27\\python.exe C:\\sud.py', $output);
echo var_export($output, TRUE);
The code i was searching whole day ^^
That's why - hope it'll help somebody.

For Windows User -
Thanks to Karlisup my PHP file could read python.
I'm using BITNAMI WAMP in EC2 Amazon, my python file (leadatos.py) and php file are on htdocs folder.
My calling was
<?php
passthru('C:\\Python27\\python.exe leadatos.py');
?>
The last line of my Python file was print "message".
Hope it words!

Related

Python script not executing properly from Php

I'm trying to run a python script with Php but it's not running properly when I launch it with Php. This script, here "bot.py" interracts with the instagram api and writes the output as a text file in 'bot1.txt'.
Here is the Php code :
shell_exec("python automation/bot.py");
And here is the python snippet that writes in the file :
with open('../botlog/bot1.txt', 'a') as the_file:
the_file.write('Followed')
My problem is that when I launch it with Php the script runs but doesn't write in the file bot1.txt. When I run the python script with the command line everything works perfectly so I don't understand what's the deal here.
I'm working with MAMP on a local server.
Thank you !
Maybe you should specify your path to php.
$myPHPScriptPath = realpath(dirname(__FILE__));
Then specify the relative path to your python script.
Hope it helps

Using PHP to call Virtualenv’ed Python Script

Last night I spent 5.5 hours trying make PHP execute and receive the output of Virtualenv’ed Python script. Nothing worked; except for scripts that were not Virtualenv’ed.
What I am trying to do:
I am trying to make PHP call a virtualenv’d install of the Newspaper lib output text when I call it.
What I have now:
PHP: (updated)
<?php
$output = exec('newspaper2/bin/python3 /var/www/html/components/python/test.py 2>&1', $output2);
print_r(error_get_last());
echo $output2;
echo $output;
…this works when using a non-virtualenv script
Python: (updated)
from newspaper import Article
url = 'http://example.com/'
article = Article(url)
article.download()
article.html
article.parse()
article.authors
article.publish_date
string = article.text
print(string)
What the issue is:
I can run the script that PHP is running from the command line and it outputs just fine.
What I have tried:
With PHP, (I have tried all the “exec” calls for PHP) it cannot seem to open the virtual environment and returns nothing.
Before the script I have called “python3” and a few other things to no avail.
Yes, I have chmoded it to be executable…
I feel like this should be so simple.
I have tried suggestions on other posts and all over the web to no avail.
Questions:
Did I set up the virtualenv wrong?
At the top of the Python script, instead of the “#!/usr/bin/env python3” should I call something else?
If so, where do I find it? Should I start from scratch and will that
help?
Thank you for your help;
PS: I am running Ubuntu16, PHP7 and I need to use Python3
In the virtualenv'ed scripts (i.e. installed via the setuptools' entry-points), you should not touch the shebang (#!... first line). It is populated by the virtualenv & setuptools & related tools.
If you specify your own shebang, then it is not virtualenv'ed script. In that case, call python directly:
exec('/path/to/venv/bin/python3 /var/www/html/components/python/testing.py');
Alternatively, you can put the absolute path to the virtualenv's python binary to the py-script, but this does not look a good idea.
Also, remember that virtualenvs are non-relocatable. So they should stay in the path where they were created.
Also note that exec() returns only the last line of the output. You probably want shell_exec() or exec('...', $output) to get the whole output.
Also, it is unclear what happens with your script, and what is being printed on stderr. Try this command to see what is the error:
exec('/path/to/script 2>&1', $output)
#OR:
exec('/path/to/venv/bin/python3 /path/to/script 2>&1', $output)
OK, I finally figured it out and learned a lot in the process. The newspaper lib that I am using by default tries to write to the base of the users home directory. In this case, it was attempting to write to www-data, /var/www.
To fix this:
Go to the settings.py file in the newspaper library.
Edit the variable DATA_DIRECTORY = '.newspaper_scraper' and change it to DATA_DIRECTORY = '.path/to/writable/directory'
Save the file and you should be good to go.
I have no idea why it was not returning the errors that would have explained this sooner.
Hope this helps anyone else.
Thank you so much Sergey Vasilyev for your help. I appreciate it greatly.

how to execute a source command from php in a server

I am unable to execute a source command in linux using php.All other commands are working except this one. I need to execute the following command.
source /root/Envs/ate/bin/activate
This activates the ate-Automatic Test Equipment.Once I activate it then I need to run a python script as the script accesses the remote server.
I am able to manually run it but I am creating a tool which will automatically do it.
<?php
exec("source /root/Envs/ate/bin/activate", $output, $return);
echo "Command returned $return, and output:\n";
echo exec("python box_upgrade-pradeepa.py");
?>
The above commands returns 1 which means there is an error.But I am not sure how to run the 'source command'. The python script will run only if the source command is successful.(the python command is correct as I replaced hello.py and it ran fine.)
Could you pls help me as I am really stuck for a week?
Thanks a lot..
I found out the error. Since I am doing it using php (for a web tool) the user is Apache. 'Apache' user is unable to access the script in root folder. Moving it to another directory, I am able to run the script fine.
Thanks all..

"no such file or directory" in python script calling other python script in debian linux

Hi I've got the following written in a python script pythonscript1.py in linux debian in the directory /home/user/a/:
import subprocess
subprocess.call(["python" /home/user/b/phpcall.py"])
where the phpcall.py script contains:
import subprocess
subprocess.call(["php", "/home/user/b/phpscript1.php"])
individually called from console all scripts function perfectly, but when I use the first script whilst the 2nd script calls/looks for a file in directory b, rather than a, It yields the following error:
"PHP warning: include_once(something.php): failed to open stream: no such file in /home/user/b/phpschript1.php on line 25
Now it is quite clear to me the problem is that it cannot reach out of it's original directory. But I don't know what command I should add to the first script to allow the 2nd script to look in folder b.
So far google results have suggested something with "include_path='include'" but I don't know how/where to incorporate the statement succesfully.
Any suggestions on the correct syntax would be appreciated!
you can try this program:
import subprocess
import sys
proc = subprocess.Popen(
[sys.executable, '/home/user/b/phpcall.py'],stdin=subprocess.PIPE)
proc.communicate()
i think it's work. if not let know.
If the php script works only if you start it from the directory with the python script then you could use cwd parameter to change the working directory for the subprocess:
#!/usr/bin/env python
from subprocess import check_call
check_call(["php", "/home/user/b/phpscript1.php"], cwd="/home/user/b")
I've added the shebang #!/usr/bin/env python so that you could run the script directly as /path/to/phpcall.py assuming it is executable (chmod +x phpcall.py).
Note: if you want to run the python script as user user then you could specify the path using ~:
#!/usr/bin/env python
import os
from subprocess import check_call
script_dir = os.path.expanduser("~/b")
check_call(["php", os.path.join(script_dir, "phpscript1.php")], cwd=script_dir)
To avoid hardcoding the script directory, you could find it dynamically:
#!/usr/bin/env python
import os
from subprocess import check_call
script_dir = get_script_dir()
check_call(["php", os.path.join(script_dir, "phpscript1.php")], cwd=script_dir)
where get_script_dir().
For future reference the code that directly called the php script from python within was:
import os
os.chdir("/home/user/b")
os.system("php /home/user/b/phpscript1.php")
.Thanks Marc B
& I love the dynamic approach Sebastian, thank you :)

Accessing python nltk with php fails

Im trying to call a python file containing a sentence/word tokenizer from my php file like this:
$output = shell_exec('python tokenizer.py $sentence')
I've tried single exec, full paths to python and tokenizer.py, wrapping $sentence in double quotes. But logically, It should not be the problem because calling print(1) at the beginning of python the python code before actually using any nltk packages makes $output equal to '1'. So I came to conclusion that the problem here is the nltk itself, like the path to the modules is not correct or something...
But, calling python from the shell using the same command as above gives me fully tokenized output! To conclude: looks like when calling python from php magically 'turns off' nltk, while it fully works when executed from the shell.
Here's the part of the python code I am using:
import sys
import nltk
from nltk.tokenize import sent_tokenize
sample_text2 = sys.argv[1]
gust = sent_tokenize(sample_text2)
#print(1) here doesn't work, but everywhere above (before calling sent_tokenize) it does.
The server's running on CentOS (Linux), I am accessing it via SSH.
Obvious question: What am I doing wrong here with PHP? Or generally? Any alternatives?
EDIT
As visible in dvhh's answer and its comments, the situation happened because there were two versions installed on the server (2.6 and 2.7), while the www user had access to 2.6 and through console, the default version was 2.7. The solution was to change the default python to 2.7 for both cases and to put the nltk modules to one of the dependency folders. (Or append the dependency directory using sys.path.append)
Your php script is executed by the www user.
You could check if the python script interpreter is correctly called, it is usually in one of the directory in the PATH environment variable (like /usr/bin/python), but the www user don't have a PATH environment variable set.
Solution specify the whole path to your python interpreter in your shell_exec call ( also specify the full path to your script when you're at it )
What about the path the nltk library is installed, you could check if the python interpreter would correctly look for it by looking at the sys.path while running python with the www user.
Diagnostic : use the shell_exec call to run a python script to print the sys.path values
Solution : append the library path to the sys.path in your python script before the import nltk
These would be the most obvious solutions considering the information provided in the question.
Update :
As there is 2 version version of python installed (on that haven't got the library installed ), it is recommended to specify the path to the desired interpreter. The first solution help correct the issue.
In unix like system I would recommend using which python command to determine the path of your default python interpreter.
Option 1
Setup a simple python httpserver listening on localhost. This old answer might help but there are plenty of howtos out there. The advantage is that you don't have the overhead of starting the python interpreter each time the ntlk stuff needs to be executed and you don't have to worry about shell script executions, permissions etc. Disadvantage is a little of extra work and a little overhead.
Option 2
Using a task queue. Whatever said and done it's not safe to execute commands from your web facing PHP scripts. If you are already using RabbitMQ or something similar you can use that here. Or else if you are using redis you can use the lpush, rpop methods to make redis behave like a queue. Disadvantage: the result is not immidiately available.
Option 3
Anbother strategy for your php script to enter the data into a table and setup your python script to run as a cron job to check the table once a minute. Disadvantage: the result is not immidiately available.
Option 4
Your current choice but please make sure that you have escaped the data properly by #lafor if this option is chosen #dvhh 's answer ought to work.
In my case it wasn't problem of python version but problem (as I soon found) of the nltk_data folder. First I thought it was as permission problem, so I changed the permissions to 777, but that didn't work.
I had to copy the folder.
First you have to find where was the nltk folder installed. You will find it by running python3 command from your bash and then put following lines:
import nltk
nltk.download('punkt')
nltk.download('averaged_perceptron_tagger')
It will say something like:
[nltk_data] Downloading package punkt to /root/nltk_data...
[nltk_data] Package punkt is already up-to-date!
Now you know you have it installed eg in /root folder (i had it there).
Then put in your python script which is called by php this:
import nltk
print(nltk.data.path)
It will output something like: (note the folders are another if you run it from php script or if you call it from command line)
['/var/www/nltk_data', '/usr/nltk_data', '/usr/share/nltk_data', '/usr/lib/nltk_data', '/usr/share/nltk_data', '/usr/local/share/nltk_data', '/usr/lib/nltk_data', '/usr/local/lib/nltk_data']
Now just copy your original folder to any of the above folders. I did:
cp /root/nltk_data /var/www/nltk_data -r
Voila. It works now.

Categories