Python script that doesn't work with ImportError when run as CGI

Question: Question:

I'm new to python, so if you're saying something wrong, please point it out.
I've been worried for the past week, and I'd appreciate it if anyone could give me a hint.

Current environment

# /usr/bin/python -V
Python 3.5.1

# /usr/local/pyenv/shims/pip3 list
pip (8.1.1)
PyMySQL (0.7.2)
setuptools (18.2)

The program I made

test2.py

#!/usr/bin/python
# -*- coding: utf-8 -*-
import pymysql.cursors

of

/usr/bin/python test2.py

Then, the error does not occur,

When accessing from a browser via Apache, an Internal Server Error occurs and
The following is output to the Apache error log.

  File "/var/www/python.hogehoge.com/public_html/test2.py", line 3, in <module>
    import pymysql.cursors
ImportError: No module named 'pymysql'
Premature end of script headers: test2.py
Traceback (most recent call last):, referer: http://python.hogehoge.com/test2.py
  File "/var/www/python.hogehoge.com/public_html/test2.py", line 3, in <module>, referer: http://python.hogehoge.com/test2.py
    import pymysql.cursors, referer: http://python.hogehoge.com/test2.py
ImportError: No module named 'pymysql', referer: http://python.hogehoge.com/test2.py
Premature end of script headers: test2.py, referer: http://python.hogehoge.com/test2.py

* In the above, the header part of the error log such as the date has been deleted.
All are preceded by [Thu Apr 07 19:53:54 2016] [error] [client 111.111.11.11].

The server environment is Sakura Internet VPS, and Apache has some virtual hosts turned off and put them in one of them.
We apologize for the inconvenience, but thank you.

2016/04/08 02:29 Addendum

In the apache settings,

<Directory "/var/www/*******/public_html/">
    Options +ExecCGI
    AddHandler cgi-script .py
</Directory>

I wanted to say that it works as CGI. > Via Apache

# which httpd
/usr/sbin/httpd
# ps auxw | grep /usr/sbin/httpd
root     20000  0.0  0.0 100004   912 pts/1    S+   02:23   0:00 grep /usr/sbin/httpd

apache runs as root.

Answer: Answer:

If it works with one execution method but not with another execution method, the Python being executed may be different in the first place.
To have the target script output information about Python running itself, for example:

import sys, os
print("sys.executable: ", sys.executable)
print("executable_link: ", os.readlink(sys.executable))
print("sys.path: ", sys.path)
print("sys.version_info: ", sys.version_info)
print("sys.api_version: ", sys.api_version)

import sysconfig
for p in sysconfig.get_path_names():
    print("sysconfig:path:" + p + ": " + sysconfig.get_path(p))

Modules may have different search paths, even if they are running in the same Python.
In the questioner's example, import failed, so sys.path may be different.

Even if the import is successful, an unintended module may be loaded.
In that case, check where the module object __path__ or __file__ is loaded from.

# PILモジュールの例
# ビルトインのモジュールは __path__ や __file__ を持っていません
import PIL
print(PIL.__path__, PIL.__file__, PIL.__package__, PIL.__loader__)
Scroll to Top