WSGI (интерфейс шлюза веб-сервера) — это стандарт взаимодействия веб-приложений Python с веб-серверами. Одна из мантр синтаксиса Python заключается в том, что должен быть один, а лучше всего один способ сделать это — и WSGI стал способом ответа на HTTP-запросы в коде Python.
Что насчет mod_python?
В отличие от mod_python , WSGI не зависит от сервера : mod_wsgi реализует стандартную спецификацию для Apache, но вы можете выбрать другие модули для других серверов или даже серверы, которые просто реализуют WSGI, если вам нужно только запустить веб-приложения Python.
Таким образом, соответствие WSGI позволяет вам отложить решение о том, какой хостинг-сервер или сервер следует развернуть, не добавляя сложности дополнительного уровня абстракции.
mod_wsgi также считается легковесным по отношению к mod_python, поэтому даже в Apache есть несколько явных причин для предпочтения mod_python сегодня.
С другой стороны, код Python, все платформы Python обеспечивают поддержку WSGI, даже Zope, начиная с его версии 3.x.
mod_python также больше не разрабатывается , и с момента его перемещения на чердаке Apache новых выпусков не будет . Если вы являетесь пользователем mod_python, это не повлияет на вас, так как mod_python не исчезнет в ближайшие годы (учитывая, что Cobol все еще существует;), но WSGI является стандартным выбором для каждого нового веб-приложения.
Установка
WSGI — это не библиотека, а спецификация : поэтому есть только реализации оболочек WSGI, которые связывают веб-сервер с вашим кодом Python.
Например, если вы используете Ubuntu (или производные Debian) и хотите обслуживать приложение в Apache, пакет libapache2-mod-wsgi установит и включит mod_wsgi. Это будет наша справочная реализация для остальной части этой статьи.
Hello World не может быть пропущен здесь
WSGI определяет одну точку входа для приложения: вызываемое имя * application *, принимающее два параметра.
- среда будет содержать переменные GET и другие параметры CGI.
- start_response будет функцией для вызова, когда вы хотите начать отправку ответа. Он принимает код состояния HTTP и список заголовков (представлен в виде 2-х кортежей).
Вызываемое приложение должно возвращать список строк, которые должны быть объединены для построения ответа.
def application(environ, start_response): status = '200 OK' output = 'Hello World!' response_headers = [('Content-type', 'text/plain'), ('Content-Length', str(len(output)))] start_response(status, response_headers) return [output]
Этот код Python переносим на любой веб-сервер, где есть привязка модуля для OSGI.
Вместо этого конфигурация зависит от вашего сервера. Например, это минимальная конфигурация Apache, которую вы можете поместить в раздел VirtualHost, предполагая, что application.py содержит код, указанный выше.
WSGIScriptAlias /hello /var/www/wsgi/application.py
Для mod_wsgi доступно еще много директив :
- WSGIPythonPath указывает любые каталоги, где искать модули Python.
- WSGICallableObject переопределяет вызываемое имя для функции фронт-контроллера. Когда не указано, оно остается «приложением».
Рамки: Джанго
Если вы используете платформу Python, вполне вероятно, что вы уже можете соответствовать WSGI, используя код, предоставленный самой платформой.
Например, привязка Django WSGI импортирует несколько библиотек и обеспечивает возможность вызова приложения путем получения предопределенной библиотеки Django вместо ее определения заново:
import os, sys sys.path.append('/usr/local/django') os.environ['DJANGO_SETTINGS_MODULE'] = 'mysite.settings' import django.core.handlers.wsgi application = django.core.handlers.wsgi.WSGIHandler()
Django реализует вызываемый объект как объект с __call __ () вместо функции. Эти два варианта полностью эквивалентны:
class WSGIHandler(base.BaseHandler): initLock = Lock() request_class = WSGIRequest def __call__(self, environ, start_response): ... start_response(status, response_headers) return response
Google App Engine
Google App Engine также предлагает вам определить вызываемый WSGI и предоставляет его через собственную веб-инфраструктуру webapp2 (или webapp для более старых версий Python); не то чтобы вы не могли запустить Django Однако создание внешнего интерфейса для списка обработчиков — это самый простой способ запустить приложение, построенное на webapp2:
import webapp2 app = webapp2.WSGIApplication([('/', MainPage), ('/newentry', NewEntry), ('/editentry', EditEntry), ('/deleteentry', DeleteEntry), ], debug=True)
MainPage и другие классы обработчиков определяются в соответствии с контрактами webapp2, но интерфейс по-прежнему WSGI. На самом деле, благодаря этому стандартному webapp2 даже не привязан к Google App Engine: вы можете перенести свое приложение в другое место, не изменяя приведенный выше код.
Вывод
Фреймворк, вероятно, скроет от вас немного сложности, присущей вызовам WSGI; тем не менее HTTP является наименьшим общим знаменателем между веб-приложениями, и полезно знать, как сервер и инфраструктура взаимодействуют под прикрытием, особенно когда дела идут не так, как надо, и вам необходимо выяснить, в чем проблема.
Кроме того, при развертывании веб-приложения всегда выбирается сервер с поддержкой WSGI, включается его и добавляется конфигурация, необходимая для поиска вызываемой и соответствующей инфраструктуры (например, всех ваших модулей Python).