Я бы очень хотел, чтобы вы утомили меня подробностями о том, что и почему, о конкретных приложениях и т. Д.
Хо. Ну, вы просили об этом!
Как и Даниэль, я лично использую Apache с mod_wsgi. Он по-прежнему достаточно новый, поэтому его развертывание в некоторых средах может быть проблематичным, но если вы все равно все компилируете, это довольно просто. Я нашел это очень надежным, даже ранние версии. Реквизит Грэму Дамплтону для того, чтобы держать его под контролем.
Однако для меня важно, чтобы приложения WSGI работали на всех возможных серверах. На данный момент в этой области есть небольшая дыра: у вас есть стандарт WSGI, сообщающий вам, что делает вызываемое WSGI (приложение), но нет стандартизации развертывания; нет единого способа сообщить веб-серверу, где найти приложение. Также нет стандартизированного способа заставить сервер перезагрузить приложение, когда вы его обновили.
Подход, который я принял, заключается в следующем:
вся логика приложения в модулях / пакетах, предпочтительно в классах
все настройки, специфичные для веб-сайта, которые должны выполняться путем создания подклассов основного приложения и переопределяющих членов
все настройки развертывания для конкретного сервера (например, фабрика соединений с базой данных, настройки ретрансляции почты) в качестве параметров класса __init __ ()
один сценарий верхнего уровня «application.py», который инициализирует класс Application с правильными настройками развертывания для текущего сервера, а затем запускает приложение таким образом, чтобы оно могло работать, развернутое как сценарий CGI, mod_wsgi WSGIScriptAlias (или Passenger, который, по-видимому, работает так же), или с ним можно взаимодействовать из командной строки
вспомогательный модуль, который решает вышеуказанные проблемы развертывания и позволяет перезагрузить приложение, когда модули, на которые полагается приложение, изменяются
Итак, как выглядит application.py в конце концов, что-то вроде:
#!/usr/bin/env python
import os.path
basedir= os.path.dirname(__file__)
import MySQLdb
def dbfactory():
return MySQLdb.connect(db= 'myappdb', unix_socket= '/var/mysql/socket', user= 'u', passwd= 'p')
def appfactory():
import myapplication
return myapplication.Application(basedir, dbfactory, debug= False)
import wsgiwrap
ismain= __name__=='__main__'
libdir= os.path.join(basedir, 'system', 'lib')
application= wsgiwrap.Wrapper(appfactory, libdir, 10, ismain)
wsgiwrap.Wrapper проверяет каждые 10 секунд, чтобы увидеть, был ли обновлен какой-либо из модулей приложения в libdir, и если да, то какая-нибудь противная магия sys.modules надежно выгружает их все. Затем appfactory () будет вызван снова, чтобы получить новый экземпляр обновленного приложения.
(Вы также можете использовать инструменты командной строки, такие как
./application.py setup
./application.py daemon
для запуска любых хуков установки и фоновых задач, предоставляемых вызываемым приложением - немного похоже на то, как работает distutils. Он также реагирует на запуск / останов / перезапуск, как сценарий инициализации.)
Еще одна хитрость, которую я использую, заключается в том, чтобы поместить параметры развертывания для нескольких серверов (разработка / тестирование / производство) в один и тот же сценарий application.py и отнюдь "socket.gethostname ()", чтобы решить, какой набор параметров для конкретного сервера следует выполнить. использовать.
В какой-то момент я мог бы упаковать wsgiwrap и выпустить его должным образом (возможно, под другим именем). В то же время, если вам интересно, вы можете увидеть версию для разработки dogfood в http://www.doxdesk.com/file/software/py/v/wsgiwrap-0.5.py.