问题
I wrote a simple python program:
# /tmp/src/Code.py
import sys
print sys.path
# /tmp/src/Main.py
import Code
When I run it with python src/Main.py
, it works as expected:
max% cd /tmp
max% setenv PYTHONPATH src
max% python src/Main.py
['/tmp/src',
'/tmp/src',
'/usr/lib/python2.7',
'/usr/lib/python2.7/plat-x86_64-linux-gnu',
'/usr/lib/python2.7/lib-tk',
'/usr/lib/python2.7/lib-old',
'/usr/lib/python2.7/lib-dynload',
'/usr/local/lib/python2.7/dist-packages',
'/usr/lib/python2.7/dist-packages',
'/usr/lib/python2.7/dist-packages/PILcompat',
'/usr/lib/python2.7/dist-packages/gtk-2.0',
'/usr/lib/python2.7/dist-packages/ubuntu-sso-client']
And just to make sure sys.path is working right, I create a file in the working directory:
# /tmp/Code.py
print "I never said to search CWD!!! Your Python is broken."
import sys
print sys.path
And the result is the same as above, as expected.
However, when I run in gunicorn I get:
max% gunicorn Main:app
2017-08-08 10:30:53 [26913] [INFO] Starting gunicorn 17.5
2017-08-08 10:30:53 [26913] [INFO] Listening at: http://127.0.0.1:8000 (26913)
2017-08-08 10:30:53 [26913] [INFO] Using worker: sync
2017-08-08 10:30:53 [26918] [INFO] Booting worker with pid: 26918
I never said to search CWD!!! Your Python is broken.
['/tmp',
'/usr/bin',
'/tmp/src',
'/usr/lib/python2.7',
'/usr/lib/python2.7/plat-x86_64-linux-gnu',
'/usr/lib/python2.7/lib-tk',
'/usr/lib/python2.7/lib-old',
'/usr/lib/python2.7/lib-dynload',
'/usr/local/lib/python2.7/dist-packages',
'/usr/lib/python2.7/dist-packages',
'/usr/lib/python2.7/dist-packages/PILcompat',
'/usr/lib/python2.7/dist-packages/gtk-2.0',
'/usr/lib/python2.7/dist-packages/ubuntu-sso-client']
It appears that gunicorn randomly decided to add PWD to the sys.path. There is nothing in the gunicorn manpage about this.
python configuration:
Flask==0.10.1
Jinja2==2.7.2
MarkupSafe==0.18
PAM==0.4.2
Pillow==2.3.0
Twisted-Core==13.2.0
Twisted-Web==13.2.0
Werkzeug==0.9.4
adium-theme-ubuntu==0.3.4
apt-xapian-index==0.45
argparse==1.2.1
blinker==1.3
chardet==2.0.1
colorama==0.2.5
command-not-found==0.3
debtagshw==0.1
defer==1.0.6
dirspec==13.10
duplicity==0.6.23
gevent==1.0
greenlet==0.4.2
gunicorn==17.5
html5lib==0.999
httplib2==0.8
itsdangerous==0.22
lockfile==0.8
lxml==3.3.3
oauthlib==0.6.1
oneconf==0.3.7.14.04.1
pexpect==3.1
piston-mini-client==0.7.5
pyOpenSSL==0.13
pycrypto==2.6.1
pycups==1.9.66
pygobject==3.12.0
pyinotify==0.9.4
pyserial==2.6
pysmbc==1.0.14.1
python-apt==0.9.3.5ubuntu2
python-debian==0.1.21-nmu2ubuntu2
pyxdg==0.25
reportlab==3.0
requests==2.2.1
sessioninstaller==0.0.0
simplejson==3.3.1
six==1.5.2
software-center-aptd-plugins==0.0.0
ssh-import-id==3.21
system-service==0.1.6
unity-lens-photos==1.0
urllib3==1.7.1
wheel==0.24.0
wsgiref==0.1.2
xdiagnose==3.6.3build2
zope.interface==4.0.5
I know I could remove PWD from the sys.path by searching realpath(p) == realpath('.')
but sometimes we want PWD in the PYTHONPATH. So a more careful solution is needed. Ideally we would try to figure out which piece of software is introducing the bug. It might simply be that the gunicorn manpage is incomplete?
回答1:
Edit /usr/lib/python2.7/dist-packages/gunicorn/app/wsgiapp.py
and change the following line:
sys.path.insert(0, cwd)
to:
sys.path.append(cwd)
Then --pythonpath
works as expected.
回答2:
I switched to BaseHTTPServer
because it's 2X faster (my application has to scale efficiently).
And it's pre-installed in Python 2.7.
And it can stream: Python 2.7: streaming HTTP server supporting multiple connections on one port
And doesn't mess with standard logging settings: time.time() stops the server process silently when using Flask
And doesn't require me to hack WSGI.
And doesn't require 4 packages (gunicorn, gevent, flask, wsgi, werkzeug).
And the code base is much more stable.
And it's easier to understand what it's doing.
And users can just run ./app -arg
instead of /usr/bin/gunicorn 'app:build_app("-arg")'
How many reasons do I need???
来源:https://stackoverflow.com/questions/45574849/gunicorn-is-corrupting-sys-path