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

132

У меня есть учетная запись 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?

Теги:
cgi
wsgi

5 ответов

209
Лучший ответ

Как связаны 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

  • 3
    Я не могу установить mod_wsgi, потому что я на виртуальном хостинге. Все, что у меня есть, это поддержка fcgi. Как я могу по-прежнему запускать приложения WSGI через него?
  • 3
    +1 Это отличный ответ и ответы на многие (но не все) вопросы, которые я имею в виду. Этот ответ еще не завершен. Вы хорошо объяснили о CGI и WSGI, но какова связь и различия между FASTCGI и WSGI? Что лучше? Как они работают? Как mod_python попал в картину?
Показать ещё 5 комментариев
52

Я думаю, Флорианский ответ отвечает на часть вашего вопроса о том, что такое 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.

  • 2
    Чья это глупая идея - не делать язык WSGI независимым? Какой смысл тогда? Можно также отправить весь Python как модуль Apache.
  • 2
    @ SalmanPK Я думаю, что это просто компромисс. Конечно, нелегко (если не невозможно) создать независимый от языка протокол, который можно использовать, просто реализуя функцию на выбранном языке.
22

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

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

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

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

  • 3
    Работает ли WSGI поверх CGI, для чего нужен «flup»? Как флюп связан со схемой?
6

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

4

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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню