Яйцо Python найдено интерактивно, но не в fastcgi

В соответствии с этим вопросом, и его ответ. Я добавил путь яйца, и это сработало. Однако, когда я запускаю python в интерактивном режиме и импортирую flup, он работает без каких-либо проблем или дополнительной спецификации пути. Где разница?

Редактировать: кажется, что при работе с fastcgi файлы .pth не анализируются, но это только предположение. Нужно больше официальных заявлений.


person Stefano Borini    schedule 06.09.2009    source источник


Ответы (4)


После более тщательного анализа я думаю, что понял, что здесь происходит.

Когда Python запускается, он устанавливает sys.path (все это как часть инициализации интерпретатора).

В настоящее время среда используется для определения того, где найти файлы .pth. Если в это время PYTHONPATH не определен, он не найдет ваши модули, установленные в sys.prefix. Кроме того, поскольку easy-install.pth, вероятно, установлен в каталог с вашим пользовательским префиксом, он не обнаружит этот файл .pth для анализа.

Добавление переменных среды в os.environ или sys.path после инициализации интерпретатора не приведет к повторному анализу файлов .pth. Вот почему вы вынуждены вручную делать то, что, как вы ожидаете, Python будет делать естественным образом.

Я думаю, что правильное решение состоит в том, чтобы убедиться, что пользовательский путь доступен интерпретатору Python во время запуска интерпретатора (то есть до выполнения mysite.fcgi).

Я искал варианты добавления переменной среды PYTHONPATH в mod_fastcgi, но не вижу такой возможности. Возможно, это общая опция Apache, поэтому она не задокументирована в mod_fastcgi, или, возможно, невозможно установить статическую переменную в конфигурации mod_fastcgi.

Учитывая это, я считаю, что вы могли бы найти обходной путь со следующим:

  1. Создайте скрипт-оболочку (скрипт оболочки или другой скрипт Python), который будет вашим новым обработчиком FastCGI.
  2. В этом скрипте-оболочке установите переменную среды PYTHONPATH на ваш префиксный путь (точно так же, как вы установили в своей пользовательской среде, которая работает).
  3. Пусть скрипт-оболочка запускает процесс Python для исходного обработчика fastcgi (mysite.fcgi) с измененной средой.

Хотя у меня нет подходящей среды для тестирования, я думаю, что сценарий оболочки-оболочки будет выглядеть примерно так:

#!/bin/sh
export PYTHONPATH=/your/local/python/path
/path/to/python /path/to/your/fastcgi/handler  # this line should be similar to what was supplied to mod_fastcgi originally

Могут быть рассмотрены альтернативные обходные пути.

  • Из mysite.fgci заставьте Python повторно обработать sys.path на основе новой, измененной среды. Я не знаю, как это будет сделано, но это может быть чище, чем сценарий-оболочка.
  • Найдите параметр Apache/mod_fastcgi, который позволяет указать переменную среды (PYTHONPATH) для процесса fastcgi.
person Jason R. Coombs    schedule 06.09.2009

Программы, запускаемые или код, выполняемый на веб-сервере, имеют ограниченную среду по сравнению с тем, что вы используете в интерактивном режиме. Скорее всего, разница связана с разницей между вашей интерактивной средой и средой FastCGI. Чего я не могу вам сказать, так это того, какая разница является критической в ​​данном контексте.

person Jonathan Leffler    schedule 06.09.2009

Я столкнулся с аналогичной проблемой при запуске приложений Python в IIS (Windows). Я обнаружил, что при работе под ISAPI яйца не читаются, потому что setuptools меняет разрешения на заархивированные яйца, а также потому, что приложение ISAPI запускается под учетной записью с ограниченными правами.

Вы можете столкнуться с такой же ситуацией в FastCGI. Если у процесса FastCGI нет разрешения на чтение яиц или расширение яиц по мере необходимости, у вас могут возникнуть проблемы. Кроме того, я обнаружил, что установка переменной среды PYTHON_EGG_CACHE в каталог, доступный для записи процессом, также необходима для некоторых яиц (в частности, для яиц с двоичными модулями/расширениями или ресурсами, доступ к которым должен осуществляться в виде файлов).

person Jason R. Coombs    schedule 06.09.2009
comment
дело в том, что яйца уже развернуты в моей директории site-packages. Я не вижу причин, по которым это не должно работать, за исключением того, что файлы .pth полностью игнорируются. - person Stefano Borini; 06.09.2009

Я согласен с тем, что даже с определенной переменной среды PYTHONPATH файлы .pth не интерпретируются при запуске python в среде FastCGI. Я не знаю, почему это так, но у меня есть предложение по обходному пути.

Используйте site.addsitedir. Он будет интерпретировать файлы .pth, что позволит вам затем импортировать яйца просто по имени, не добавляя полный путь к каждому из них.

#!/user/bin/python2.6

import site

# adds a directory to sys.path and processes its .pth files
site.addsitedir('/home/mhanney/.local/lib/python2.6/site-packages/')

# avoids permissions error writing to system egg-cache
os.environ['PYTHON_EGG_CACHE'] = '/home/mhanney/.local/egg-cache'

Нет необходимости использовать виртуальную среду. У моего провайдера виртуального хостинга я просто устанавливаю яйца в ~/.local, используя

python setup.py install --prefix=~/.local

Вот вариация примера «Hello World» для вывода переменных среды, пути и модулей, полезная для отладки FastCGI.

#!/usr/bin/python2.6
import sys, os, site, StringIO
from pprint import pprint as p

# adds a directory to sys.path and processes its .pth files
site.addsitedir('/home/mhanney/.local/lib/python2.6/site-packages/')

# avoids permissions error writing to system egg-cache
os.environ['PYTHON_EGG_CACHE'] = '/home/mhanney/.local/egg-cache'

def test_app(environ, start_response):
    output = StringIO.StringIO()
    output.write("Environment:\n")
    for param in os.environ.keys():
        output.write("%s %s\n" % (param,os.environ[param]))
    output.write("\n\nsys.path:\n")
    p(sys.path, output)
    output.write("\n\nsys.modules:\n")
    p(sys.modules, output)
    start_response('200 OK', [('Content-Type', 'text/plain')])
    yield output.getvalue()

if __name__ == '__main__':
    from flup.server.fcgi import WSGIServer
    WSGIServer(test_app).run()
person mhanney    schedule 20.09.2010