Apache doesn't let PIL work - php

I wrote "Apache doesn't let PIL work" as title but I'm not sure about if this is the case or not.
I have a php script that sends json data to a py file that will process an image according to this json data. The communication between languages works. But when I add the line for importing PIL to py file, php returns NULL on browser. It's also working when I run the php script with command line but I have to run it on web browser.
This is the php script:
<?php
$result = exec('python somecode.py ' . escapeshellarg(json_encode('897')));
$resultData = json_decode($result, true);
var_dump($resultData);
?>
this is the py file:
import sys, json
data = json.loads(sys.argv[1])
print data
this works just fine and gives me the output of int(897) which is expected. When I add the line of from PIL import Image, it gives NULL on browser but it still can being ran on command line without any problem. I didn't even add the code for processing image, just trying to import PIL.
EDIT: I tried to import numpy, it didn't prevent the code from running. It runs on browser even I import numpy. So, probably problem is related with PIL.

It was about the image's path. I changed it to a proper one, and the problem is fixed.

Related

Python package not imported when executed through PHP

I'm getting a import error for spacy when executing new_api.py through PHP. The python script gets successfully executed when run through the cmd
PHP Code
<?php
$json = file_get_contents('php://input');
$input = json_decode($json, TRUE);
$result = shell_exec('/usr/bin/python3 new_api.py "'.$input['queryResult']['queryText'].'" "'.$input['session'].'" 2>&1');
$output = json_encode(array(
"source" => "source",
"fulfillmentText" => $result
));
print_r($output);
?>
Snippet Of Python Code
import requests
import json
import sqlite3
import spacy
import sys
json_values = sys.argv[1:]
result = (home(json_values[0],json_values[1]))
print(result)
The Output/Error Traceback
{"source":"source","fulfillmentText":"Traceback (most recent call last):\n File \"new_api.py\", line 4, in \n import spacy\nImportError: No module named 'spacy'\n"}
There's two version of python in the server. Both the versions has spacy installed in it and the python script is compatible with both versions.
Things I've tried
Tried using exec() and shell_exec() in php
Tried using which python path to execute the script
Tried running the script which both python and python3
The ImportError Still persists even after trying the combinations of the above steps. Any help would be appreciated.
Probably the user of the server who execute the PHP script does not have enough permissions to access the module.
You can install the module as server user or use venv
I have same problem, and I soleved it just a moment ago. This question is old, but I leave a note for people has same problem, and for me.
"printenv" on shell (your own user).
exec('printenv') from php (probably "apache" user).
Check difference between 1 and 2 results.
In my case, LD_LIBRARY_PATH=/usr/local/pgsql/lib is needed (exist in 1 and not exist in 2). So I modified my code as follows:
exec('LD_LIBRARY_PATH=/usr/local/pgsql/lib python3 test_script.py 2>&1');

Python script won't exec from php when specific library is used

Im trying to execute a Python script to get and set the parameter server in ROS. When I run any other simple python script that for example prints "Hello", I get back the value in PHP. But when I run this code:
#!/usr/bin/env python
import roslib
import rospy
import sys
import re
import string
get = rospy.get_param("param")
print get
I get an empty echo. However this code works fine in the terminal!
All I'm doing in PHP is:
$output = exec("python path/script.py")
echo $output;
I tried shell_exec, I tried with python in the command, and without. I also tried /usr/bin/python still it won't work for this specific code, but everything works for a simple print!
It turns out that Apache's user doesnt have the required environment variables. So you have to add the environment variables paths you need in Apache's.. You can set them out here

Change permissions to allow PHP script in browser to execute matplotlib operations in a python script

I am running Ubuntu 14.04 with a locally hosted webpage running on Apache2. I can access index.php fine through my browser, but I want that page to display a graph that is prepared in a python script called graph.py. graph.py will execute fully when the I execute index.php from the terminal, and it will PARTIALLY execute when I access it from the browser. commands from pyplot, used within the graph.py file will not execute when called from the browser.
I have simplified the contents of the files for this question.
Contents of index.php:
<?php
echo exec('whoami');
echo "</br>";
$r = `python graph.py`;
echo($r);
?>
Contents of graph.py:
#!/usr/bin/python2.7
import cgi
import matplotlib.pyplot as plt
print("Initial file parsing successful")
plt.plot([1,2,3,4])
print("File completed operation using pyplot")
The output of index.php from the terminal has what I would expect:
MYUSERNAME</br>Initial file parsing successful
File completed operation using pyplot
The browser never completed the PyPlot operation as shown by its output:
www-data
Initial file parsing successful
After scouring the internet for answers, this post appears to be the most similar to my issue:
Why cannot PHP execute a command from web browser?
As suggested in the responses, it makes sense that I may be dealing with a permissions issue. I used "updatedb" and "locate pyplot" to find every instance the pyplot module appears. On my machine, there are three files in two directories:
/usr/lib/pymodules/python2.7/matplotlib/pyplot.py
/usr/lib/pymodules/python2.7/matplotlib/pyplot.pyc
/usr/share/pyshared/matplotlib/pyplot.py
Since pyplot has other dependencies in the matplotlib directory, I set permissions for every file in both of these directories with "chmod 777." I know I will have to restore these for security reasons once I find where I can scale permissions back, but even allowing that level of access, the php file will not execute when accessed from the browser. Does anyone have any ideas what could be catching this?
AFAIK, when you execute python from the browser the user is www-data. Thus you should change the python script's permissions to a+x. You don't need cgi unless you run PHP in cgi that is unusual. Just put 'graph.py' into the same folder where you keep your index.php. Save your plot into am image and open it in your browser via PHP. That's it.
Python script
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import matplotlib.pyplot as plt
plt.plot([1,2,3,4])
plt.savefig('img.png')
PHP code
<?php
$r = '/usr/bin/python ./graph.py';
exec($r);
$im = imagecreatefrompng("img.png");
header('Content-Type: image/png');
imagepng($im);
imagedestroy($im);
?>
Output:
I was able to make a plot with Python in cgi. No problems. http://wiki.scipy.org/Cookbook/Matplotlib/Using_MatPlotLib_in_a_CGI_script
PHP
<?php
header('Location: cgi-bin/graph.py');
?>
PYTHON
#!/usr/bin/python
import os,sys
import cgi
import cgitb; cgitb.enable()
os.environ[ 'HOME' ] = '/tmp/'
import matplotlib
matplotlib.use( 'Agg' )
import pylab
form = cgi.FieldStorage()
pylab.plot([1,2,3])
print "Content-Type: image/png\n"
pylab.savefig( sys.stdout, format='png')
And here's without cgi. Since PHP is pretty much executable, we don't actually need cgi. I moved the graph.py from cgi-bin to html folder and deleted all the cgi modules from it and even os.environ[ 'HOME' ] = '/tmp/'.
PHP
<?php
$r = '/usr/bin/python ./graph.py';
exec($r);
$im = imagecreatefrompng("img.png");
header('Content-Type: image/png');
imagepng($im);
imagedestroy($im);
?>
PYTHON
#!/usr/bin/python
import matplotlib
matplotlib.use( 'Agg' )
import pylab
pylab.plot([1,2,3])
pylab.savefig('img.png')
AS you see the difference is
matplotlib.use( 'Agg' )
I have no idea what it means. Something important, maybe. Without this opting the script doesn't run.
As per my understanding you will need to configure your webserver to work with python compiler. Any of the web server will by default will not be able to use any compiler installed on your system. Your webserver should understand for a particular file extension which program should be used to run it.
Below is the link where you can find information for it here:
[How do you set up Python scripts to work in Apache 2.0?
But in your case you may need just to run python scripts from php. You can find information about it here : Running a Python script from PHP

Import astropy calling Python from PHP

I'd like to run a Python script from PHP (LAMP). The script imports astropy, and for some reason I am not able to successfully do that. I can reproduce the basic problem with the example files copied below. I don't think it is a permission or Python path problem. I can import numpy, scipy, etc., for example. I can also create a Python script to read and write files on that same directory (/www/var). I have the standard Python on /usr/bin/python and also the Anaconda version. Both have astropy and I get the same problem regardless of which one I use.
I suspect it is something about running the code as myself (which works fine) or as www-data (from the web browser). However, when I do this from the Linux terminal: sudo -u www-data php test.php, the code works as expected.
This is test.php:
<?php
echo "<p>begin test.php</p>";
system("python test.py");
echo "<p>end test.php</p>";
?>
And test.py:
print("this is test.py ...")
import sys, numpy, scipy, matplotlib
print("passed the import sys, numpy, scipy, matplotlib ...")
import astropy
print("passed the import astropy ...")
What I get when I open test.php is this:
begin test.php
this is test.py ... passed the import sys, numpy, scipy, matplotlib ... ERROR: TypeError: coercing to Unicode: need string or buffer, NoneType found [genericpath]
end test.php
What version of Astropy are you running? Incidentally I'm pretty sure this is a known and fixed issue: https://github.com/astropy/astropy/pull/952
Also, current versions of Astropy require you to specify a configuration directory that the library can write to. It doesn't necessarily know that /var/www is the correct "home" directory to use for the webserver, so you need to set the environment variable XDG_CONFIG_HOME=/var/www (make sure the /var/www/astropy directory exists too).
I think there are plans to simply this so that the library is at least importable without this additional setup.

Strange issue running Python script in php in browser

I am using python's nltk to do some interesting things to input strings from php, but I'm experiencing some difficulties in getting it to output to the browser. My code looks like this:
system("python test.py command line arguments");
which outputs correctly in the command line no matter what is in my test.py file. However, in the browser it will work unless specific code is present.
inside test.py:
import string
import sys
from nltk import word_tokenize as wt
from nltk.corpus import wordnet as wn
x = ""
for item in sys.argv: x += item+" "
i = wt(x)
result = ""
wn.morphy(i[0])
print "hello world"
This will not print "hello world" in the browser, but only if the preceding line of code is present. without
wn.morphy
it will run. Unfortunately I need to use wn.morphy. Why would this not work in the browser with that specific line of code in my test.py file? I have already turned off safe mode, which is what allows me to output to the browser with python at all
Actually, this code works for me on the PHP CLI, whether or not I include the wn.morphy line, so I think your problem is elsewhere, or version-related.
Did you remember to download the 'wordnet' corpus? If not, run
>>> import nltk
>>> nltk.download('wordnet')
in Python, and then try again. I could see the script erroring out because it can't get to the corpus.
What is the error? Could it be due to the size of WordNet (which is pretty big) or the time it takes Python/NLTK takes to load it? A live web server is probably going to have tighter quotas than an interactive console session.

Categories