call python script *with non-standard library impo

2019-05-22 14:36发布

问题:

I have searched thru all related questions, there are lots of similar ones, but my question is

how to call, from php, a python script in which I imported some non-standard libraries/modules

To be more specific, I have a .py file, test.py, in which I imported pycurl and bottlenose, which is an amazon API wrapper. Both module are not in the standard library. So the file looks like

import pycurl
import bottlenose
...
print "hello!"

Then I made a php file, test.php

<?
$output = array();
exec("/home/my_user_name/local/Python-2.7/bin/python test.py", $output, $ret_code);
var_dump( $output);
echo $ret_code;
?>

Both test.php and test.py are under the same directory. More importantly if I run

php test.php 

in my terminal, there was no problem with with it. It sucessfully output "hello", and return code is 0, which means program exits with no error

However, when I tested it on my browser, www.someurl.com/test.php, some error occured. I tracked line by line and found the error occurs at the "import pycurl" and "import bottlenose".

I also tried to print out sys.path, it does include the path of bottlenose.

Can someone help?

Thanks!!

回答1:

I would trust the sys.path being correct if you were invoking putenv in the php script before calling the Python program.

From the successful run, take the chance to print the sys.path. Let us call the result of this print as 'x'. Then, try the following:

putenv('PYTHONPATH=x');
exec("/home/my_user_name/local/Python-2.7/bin/python test.py", $output, $ret_code);

Does that help ?



回答2:

Usually, you don't run a web server as my_user_name, but as a special user like httpd or www or nobody. And that user may not have permissions to read the Python modules you've installed, which of course would make the import fail.

To test this, try just opening it before importing it:

try:
    with open('/path/to/bottlenose.py', 'r') as f:
        print('Opened file just fine')
except Exception as e:
    print('Failed to open file: %s' % (e,))

Of course if print doesn't work usefully in your setup, whatever you did to print out the sys.path, do the same thing here.

If this isn't the problem, you could try wrapping the import in a try block to print out the exception and see why it's failing, so we don't have to guess.

If this is the problem, the quick&dirty solution is to give your web server account access to your user's Python modules directory via chmod… but a better solution is to install the modules to a system-wide site-packages directory, or to a directory owned by the web server account.



回答3:

It might be too heavyweight for your case, but have you considered virtualenv?