Environment: Ubuntu 16, Apache 2.4
The last three times I tried to setup Apache to serve up Python I run into the same problem: Apache wants to let me download the script instead of running it and serving the html in the browser. Each time I figure it out, it turns out to be a combination of things I can never quite figure out.
For Simplicity:
I have the following shebang at the top of my file: #!/usr/bin/env python2.7
Ran sudo apt-get install libapache2-mod-python
Running a2enmod python returns Module python already enabled
Added all sorts of apache2.conf directives, none of them work:
<Directory /var/www/html>
     Options Indexes FollowSymLinks
     Options ExecCGI
     AllowOverride None
     Order allow,deny
     Allow from all
     AddHandler cgi-script .cgi
</Directory>
According to this link, this is all that should be required:
<Directory /srv/www/yoursite/public_html>
     Options +ExecCGI
     AddHandler cgi-script .py
</Directory>
And, this one works on another machine but not the present:
<Directory /var/www/>
     Options +ExecCGI
     AddHandler cgi-script .py
     PythonHandler mod_python.publisher
     Options Indexes FollowSymLinks
     AllowOverride None
     Require all granted
</Directory>
<Directory /var/www/html/index.py>
     Options +ExecCGI
</Directory>
*Sorry if these apache2.conf's look like a mess, or have redundant lines, I was trying anything and everything.
Running sudo a2enmod cgi returns:
Your MPM seems to be threaded. Selecting cgid instead of cgi. Module cgid already enabled
The .py scripts are executable and are owned by www-data.
Please HELP! This is so frustrating. What have I not tried? I want this to be the last time I have to do this. Every time I approach Apache, I approach it with fear; maybe it can smell it.
FYI: I have tried all of the (troubleshooting) steps at these sites (and many others):
https://www.linux.com/blog/configuring-apache2-run-python-scripts
Why do I get error, Invalid command 'PythonHandler'?
https://superuser.com/questions/174071/apache-serves-py-as-downloadable-file-instead-of-executing-it?utm_medium=organic&utm_source=google_rich_qa&utm_campaign=google_rich_qa (returns errror with their solution)
Apache not handling python scripts (*.py) via browser
UPDATE
So, here it is. I used test.py in /var/www/html/ so as not to change the source directory. Maybe something is wrong with my browser or the way I am accessing it?
$ ls -ltr /var/www/html/test.py
-rwxr-xr-x 1 www-data www-data    71 Mar 31 17:29 test.py
$ cat /var/www/html/test.py 
#!/usr/bin/python2
print("Content-type:text/html\n\n")
print("hello")
$ grep -A 3 '<Directory /var/www/html/>'  /etc/apache2/apache2.conf
<Directory /var/www/html/>
     Options +ExecCGI
     AddHandler cgi-script .py
</Directory>
$ ./test.py
Content-type:text/html
hello
I looked in the log files. Nothing odd in access.log, but error.log had an error about mismatched Python versions. According to this link, it shouldn't be a problem. Regardless, I resolved the error by running:
$ apt-get remove libapache2-mod-python libapache2-mod-wsgi
$ apt-get build-dep libapache2-mod-python libapache2-mod-wsgi
Proof: Script downloading
Still no luck. I noticed there was an apache2 service running even after it was stopped. Thinking it may be a zombie process, I terminated all processes (it kept popping up), uninstalled and purged apache2, restarted and tried again.
