Как веб-фреймворки Python, WSGI и CGI подходят друг другу

У меня есть учетная запись Bluehost, где я могу запускать скрипты Python как CGI. Я думаю, это самый простой CGI, потому что для запуска я должен определить следующее в .htaccess:

Options +ExecCGI
AddType text/html py
AddHandler cgi-script .py

Теперь, когда я просматриваю веб-программирование с помощью Python, я много слышал о WSGI и о том, как большинство фреймворков его используют. Но я просто не понимаю, как все это сочетается, особенно когда мой веб-сервер предоставляется (Apache работает на главной машине), а не с чем-то, с чем я действительно могу играть (кроме определения команд .htaccess).

Как WSGI, CGI и все связанные структуры? Что мне нужно знать, устанавливать и делать, если я хочу запустить веб-фреймворк (скажем web.py или CherryPy) в моей базовой конфигурации CGI? Как установить поддержку WSGI?

Ответ 1

Как связаны WSGI, CGI и фреймворки?

Apache прослушивает порт 80. Он получает HTTP-запрос. Он анализирует запрос, чтобы найти способ ответить. У Apache есть много вариантов ответа. Один из способов ответа - использовать CGI для запуска script. Другой способ ответить - просто подать файл.

В случае CGI Apache подготавливает среду и вызывает script через протокол CGI. Это стандартная ситуация с Unix Fork/Exec - подпроцесс CGI наследует среду ОС, включая сокет и stdout. Подпроцесс CGI пишет ответ, который возвращается к Apache; Apache отправляет этот ответ в браузер.

CGI примитивен и раздражает. В основном потому, что он создает подпроцесс для каждого запроса, а подпроцесс должен выйти или закрыть stdout и stderr, чтобы обозначить конец ответа.

WSGI - это интерфейс, основанный на шаблоне проектирования CGI. Это не обязательно CGI - ему не нужно разветвлять подпроцесс для каждого запроса. Это может быть CGI, но это не обязательно.

WSGI добавляет к шаблону проектирования CGI несколькими важными способами. Он анализирует заголовки HTTP-запросов для вас и добавляет их в среду. Он поставляет любой POST-ориентированный ввод в качестве файлового объекта в среде. Он также предоставляет вам функцию, которая будет формулировать ответ, избавив вас от множества деталей форматирования.

Что мне нужно знать/устанавливать/делать, если я хочу запустить веб-фреймворк (скажем, web.py или cherrypy) в моей базовой конфигурации CGI?

Напомним, что форматирование подпроцесса дорого. Существует два способа обойти это.

  • Встроенный mod_wsgi или mod_python внедряет Python внутри Apache; процесс не разветвляется. Apache запускает приложение Django напрямую.

  • Daemon mod_wsgi или mod_fastcgi позволяет Apache взаимодействовать с отдельным демоном (или "длительным процессом" ), используя протокол WSGI. Вы начинаете свой долгий процесс Django, а затем настраиваете Apache mod_fastcgi для связи с этим процессом.

Обратите внимание, что mod_wsgi может работать в любом режиме: встроенный или демон.

Когда вы читаете mod_fastcgi, вы увидите, что Django использует flup для создания WSGI-совместимого интерфейса из информации предоставляется mod_fastcgi. Трубопровод работает следующим образом.

Apache -> mod_fastcgi -> FLUP (via FastCGI protocol) -> Django (via WSGI protocol)

Django имеет несколько "django.core.handlers" для различных интерфейсов.

Для mod_fastcgi Django предоставляет manage.py runfcgi, который объединяет FLUP и обработчик.

Для mod_wsgi есть основной обработчик для этого.

Как установить поддержку WSGI?

Следуйте этим инструкциям.

https://code.google.com/archive/p/modwsgi/wikis/IntegrationWithDjango.wiki

Для фона см. это

http://docs.djangoproject.com/en/dev/howto/deployment/#howto-deployment-index

Ответ 2

Я думаю, Флорианский ответ отвечает на часть вашего вопроса о том, что такое WSGI, особенно если вы читаете PEP.

Что касается вопросов, которые вы задаете ближе к концу:

WSGI, CGI, FastCGI и т.д. - все протоколы для веб-сервера для запуска кода и доставки динамического контента, который создается. Сравните это со статическим веб-сервисом, где обычный HTML файл в основном поставляется как есть для клиента.

CGI, FastCGI и SCGI являются языковыми агностиками. Вы можете писать сценарии CGI в Perl, Python, C, bash, что угодно. CGI определяет, какой исполняемый файл будет вызываться на основе URL-адреса, и как он будет вызываться: аргументы и среда. Он также определяет, как возвращаемое значение должно быть возвращено на веб-сервер после завершения вашего исполняемого файла. Эти вариации в основном являются оптимизациями, позволяющими обрабатывать больше запросов, уменьшать задержку и т.д.; базовая концепция одинаков.

WSGI - только Python.. Вместо агностического протокола языка определена стандартная сигнатура функции:

def simple_app(environ, start_response):
    """Simplest possible application object"""
    status = '200 OK'
    response_headers = [('Content-type','text/plain')]
    start_response(status, response_headers)
    return ['Hello world!\n']

Это полное (если ограниченное) приложение WSGI. Веб-сервер с поддержкой WSGI (например, Apache с mod_wsgi) может вызывать эту функцию всякий раз, когда приходит запрос.

Причина, по которой это так здорово, заключается в том, что мы можем избежать беспорядочного перехода от HTTP GET/POST к CGI на Python и снова вернуться на выход. Это гораздо более прямая, чистая и эффективная связь.

Это также упрощает работу с многолетними фреймворками, работающими за веб-серверами, если все, что нужно сделать для запроса, - вызов функции. С простым CGI вы должны запустить всю свою структуру для каждого отдельного запроса.

Чтобы иметь поддержку WSGI, вам необходимо установить модуль WSGI (например, mod_wsgi) или использовать веб-сервер с WSGI (например CherryPy). Если ни один из них невозможен, вы можете использовать мост CGI-WSGI, указанный в PEP.

Ответ 3

Вы можете запустить WSGI через CGI, как показано в примере Pep333. Однако каждый раз, когда возникает запрос, запускается новый интерпретатор Python, и весь контекст (соединения с базой данных и т.д.) Должен быть построен, и все это занимает время.

Лучше всего, если вы хотите запустить WSGI, было бы, если бы ваш хост установил mod_wsgi и сделал соответствующую конфигурацию для отсрочки контроля над приложением ваш.

Flup - это еще один способ запускать WSGI для любого веб-сервера, который может говорить FCGI, SCGI или AJP. Из моего опыта работает только FCGI, и его можно использовать в Apache либо через mod_fastcgi, либо если вы можете запустить отдельный демон Python с mod_proxy_fcgi.

WSGI - это протокол, похожий на CGI, который определяет набор правил взаимодействия веб-сервера и Python-кода, он определяется как Pep333. Это позволяет, что многие различные веб-серверы могут использовать множество различных фреймворков и приложений, используя один и тот же протокол приложений. Это очень полезно и делает его настолько полезным.

Ответ 4

Если вы неясны на всех терминах в этом пространстве и можете встретить это, его запутанный сокращенный аббревиатурой, там также есть хороший справочный читатель в форме официального Python HOWTO, который обсуждает CGI и FastCGI vs. WSGI и т.д.: http://docs.python.org/howto/webservers.html

Ответ 5

Это простой уровень абстракции для Python, сродни тому, что спецификация Servlet для Java. В то время как CGI действительно низкий уровень и просто сбрасывает материал в среду процесса и стандартное вход/выход, приведенные выше два спецификатора моделируют HTTP-запрос и ответ как конструкции на языке. Мое впечатление, однако, заключается в том, что в Python люди не совсем обосновались в де-факто реализациях, поэтому у вас есть сочетание эталонных реализаций и других библиотек типа утилит, которые предоставляют другие возможности наряду с поддержкой WSGI (например, Paste). Конечно, я могу ошибаться, я новичок в Python. Сообщество "веб-скриптов" сталкивается с проблемой в другом направлении (совлокальный хостинг, наследие CGI, проблемы с разделением привилегий), чем люди из Java имели возможность начать с (запуск одного корпоративного контейнера в выделенной среде против статически скомпилированных и развернутых код).