I'm experiencing an odd issue. I have a Python script that I'm calling from a PHP script. This is all running on an Apache server on Ubuntu 18.04. Part of the Python script uses the Google Drive API. EDIT: See the bottom After a lot of testing and replication,I've concluded that simply having the following Google Drive Python libraries and dependencies imported:
from __future__ import print_function
from googleapiclient import discovery
from httplib2 import Http
from oauth2client import file, client, tools
from googleapiclient.http import MediaIoBaseDownload
Messes up the script when it is called from the web. By that I mean the Python script does not seem to execute, and any shell output that I should be getting through print statements do not make their way back to the PHP script. When calling the script locally (python myscript.py), it works just fine.
The weird part is that when I remove these import statements from the Python script, it executes just fine from both PHP, and from directly launching the script from a browser. In both of those cases I am also able to get the shell output back to the PHP script. I have given the proper permissions for the Python script, and I have configured Apache to be able run CGI scripts. Here is what my Python script looks like:
#!/usr/bin/env python3
import cgitb
from __future__ import print_function
from googleapiclient import discovery
from httplib2 import Http
from oauth2client import file, client, tools
from googleapiclient.http import MediaIoBaseDownload
cgitb.enable()
print("Hello World")
And here is what my PHP script looks like:
<?php
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
$output = shell_exec("python path_to_my_script/myscript.py");
echo $output;
?>
EDIT:
I ran a couple of tests using another 3rd party Python library that I installed with pip, and this actually seems to be an issue with importing any 3rd party library when executing the script via PHP.
Your issue is a user permissions issue. You should run the Apache server as the user that owns your python environment, or allow the user running the server execute permissions in your python environment.
This answer should help you figure out your best setup for the server.
Also read about Apache VirtualHosts Configuration
I Figured this out. Hopefully this will help anyone with a similar issue. When you execute a Python or shell script from a PHP script served on an Apache server, the script will be ran as the user, www-data by default.
By running the command sudo -u www-data (running the following command as the www-data user) python myscript.py, I got a traceback error that exclaimed that the 3rd party modules could not be found. What's happening is that by default pip (python package manager) installs its packages on a user level basis. That's fine for most applications, but causes a problem in this case as the www-data user understandably cannot find the installed packages, and the script crashes. This becomes particularly tricky from the perspective of the PHP script, as it doesn't understand this and the output is just null.
I understand that installing pip packages with sudo is not preferred as it can cause conflict issues in some cases; however, this is the easiest way to solve the problem for most packages. For cases where this does not work, check out this answer from infinigrove:
How to install Python Package for global use by all users (incl. www-data)
Finally, from what I could see in order to install a pip package as the www-data user (sudo -u www-data pip install package), www-data would have to be granted sudo permissions, which is definitely not a recommended solution.
Related
I'm currently attempting to make a Jira plugin that contains a Java servlet that calls my Python script with ProcessBuilder to do some frontend work, which works perfectly on localhost.
Except, whenever I deploy it onto the online Jira server, my python script doesn't get called and hence the HTML isn't updated. I've deduced that it is most likely because the plugin or machine running the Jira server responsible for calling my script probably doesn't have anything in it to execute python.
As a result, I've tried to do some process builder things and install Python onto the server, to no avail. I found out that the system running the server is a Linux machine and have tried to "sudo apt-get install python" and even tried to just run python3 myscript.py to no avail. It keeps erroring out and throwing me a NullPointerException whenever I start any process that has to do with installing Python.
Anyone have any ideas?
So I want to get into React Native development and have decided Python to be my backend, but for some reason I cannot configure the Apache correctly. The only way to successfully get the result from the request is to include path to python.exe at the start of the document like so:
!C:\Users\Name\PycharmProjects\AppName\venv\Scripts\python.exe
But the problem is that the file is than executed by the Python console, and if I want to access it via mobile phone I get this error:
The server encountered an internal error and was unable to complete your request. Either the server is overloaded or there was an error in a CGI script.
So my question is:
Is there any way in which I can configure Apache to execute a file, without the requirement of the py console, so the request might be handled by devices, which doesn't have a Python console installed?
if you connect from mobile device to http://192.168.1.3/HelloWorld.py on server with CGI then code should be executed on server, not on mobile device. If CGI doesn't work then server may try to send code as normal file and then mobile mdevice ay try to run it locally but it is wrong - CGI server should run code on server.
At start I would put code in subfolder cgi-bin to run it as http://192.168.1.3/cgi-bin/HelloWorld.py because most CGI servers as default run code only in this subfolder.
On Linux script would need shebang
#!/usr/bin/env python
in first line and it should be executable
chmod a+x script.py
CGI has also some rules how to generate data which it will send to client. It may need at start extra information for HTTP protocol - and using only print("Hello World") may generate wrong data and it may have problem to send it. You should have it in any tutorial for CGI scripts. See module cgi
To run Python's code Apache needs module mod_cgi, mod_fcgi or mod_python
mod_cgi and mod_fcgi can run scripts in different languages: Python, Perl, Ruby, etc. and even Bash, PHP or C/C++/Java
Python3 has standard module http which can be used also as simple server
python3 -m http.server --cgi
and it will serve all files in folder in which you run it. And it runs files from subfolder cgi-bin/ - see doc: http
I have spent hours banging my head against the wall on this one!
I am running Python 2.7.10 on a Mac. I have a few Python scripts that I have written which run inside the Atom editor.
I have been trying to run these scripts on a local web server to speed up development. I have tried MAMP (which just throws 500 Internal Server Errors), and now "python -m SimpleHTTPServer" which just displays the python code in the browser and doesn't seem to execute it.
I have chmod +x my .py files. I start the web server in the folder that contains the .py files.
Here is an example...
hello.py
print("hello world")
When I browse to http://localhost:8000/hello.py I get the raw code displayed in the browser.
print("hello world")
If I use terminal and enter "python hello.py" it runs and displays the correct output...
MacBook-Pro-3:folder dj$ python hello.py
hello world
I have tried dozens of tutorials and suggested solutions, but none seem to help. Am I missing something fundamental here?
Thanks!
D
The server that python -m SimpleHTTPServer (or, for future readers, python -m http.server on Python 3) spins will not execute any file. It is merely a server that serves files as the documentation suggests:
The SimpleHTTPServer module can be used in the following manner in order to set up a very basic web server serving files relative to the current directory.
In order to get a server that will actually execute Python code, you'll need to use another tool. I'd start with bottle or flask.
I have been using the mysql.connector module with Python 2.7 and testing locally using XAMPP. Whenever I upload my script to the server, I am getting an import error for the mysql.connector module. I am assuming this is because, unlike my local machine, I have not installed the mysql.connector module on the server.
My question is: can I somehow use the mysql.connector module on the server or is this something only for local development? I have looked into it, and apparently do not have SSH access for my server, only for the database. As well, if I cannot use the mysql.connector module, how do I connect to my MySQL database from my Python script on the server?
You can use mysql.connector on the server. However, you will have to install it first. Do you have root (admin) access? If no, you might need help from the server admin.
So you can use the mysql.connector on the server, and it can be done without SSH or any special access!
Download it from here: https://dev.mysql.com/downloads/connector/python/2.1.html
(Click on the "Development Releases" tab and download the zip archive)
After you unzip, take the entire "mysql" folder from the lib directory and upload it to the server (wherever your other Python files are, e.g. cgi-bin or similar).
Change the entire mysql directory permission to 755 recursively.
Now you can use it in any Python script on the server by using "import mysql.connector as conn" (or name it whatever you want to)
Each time I upload my app to Google App Engine, the logs always show this warning:
WARNING appengine_rpc.py:435 ssl module not found. Without the ssl
module, the identity of the remote host cannot be verified, and
connections may NOT be secure. To fix this, please install the ssl
module from http://pypi.python.org/pypi/ssl .
I'm running a virtualenv with Python 2.7. When I'm in it, I try to run
$ pip install ssl
but this produces an error:
ValueError: This extension should not be used with Python 2.6 or later
(already built in), and has not been tested with Python 2.3.4 or earlier.
If ssl is built in to Python 2.7, how do I tell the local development server to use the built in ssl module?
It sounds like appcfg.py is not using your virtualenv correctly. You can try editing the appcfg.py script so that it prints sys.version and sys.path, to confirm that it's using your virtualenv correctly. (The shebang line is "#!/usr/bin/env python", so that should use your active environment, but it's worth checking.)
If you're using the Launcher, you need to tell it explicitly where to look for your virtualenv's Python. Go to Preferences, and set the Python Path to your virtualenv's Python 2.7. The Launcher prints which Python path it is using in the Logs (at least when starting the dev server).