wsgiref — Утилиты WSGI и реализация по умолчанию
Исходный код: Lib/wsgiref
Интерфейс Web Server Gateway Interface (WSGI) — это стандартный интерфейс между веб-серверным программным обеспечением и веб-приложениями, написанными на Python. Наличие стандартного интерфейса упрощает использование приложения, поддерживающего WSGI, с различными веб-серверами.
Только авторы веб-серверов и фреймворков должны знать все подробности и частные случаи реализации WSGI. Вам не нужно понимать все подробности WSGI, чтобы просто установить приложение WSGI или написать веб-приложение, используя существующий фреймворк.
wsgiref — это реализация по умолчанию спецификации WSGI, которая может быть использована для добавления поддержки WSGI к веб-серверу или фреймворку. Она предоставляет утилиты для работы с переменными среды WSGI и заголовками ответа, базовые классы для реализации WSGI-серверов, демонстрационный HTTP-сервер, который обслуживает WSGI-приложения, и инструмент валидации, который проверяет WSGI-серверы и приложения на соответствие спецификации WSGI (PEP 3333).
Дополнительную информацию о WSGI, а также ссылки на учебные пособия и другие ресурсы можно найти на сайте wsgi.readthedocs.io.
wsgiref.util — Утилиты для работы со средой WSGI
Этот модуль предоставляет различные вспомогательные функции для работы со средой WSGI. Среда WSGI — это словарь, содержащий переменные HTTP-запроса, как описано в PEP 3333. Все функции, принимающие параметр environ, ожидают, что будет предоставлен словарь, соответствующий спецификации WSGI; подробную спецификацию см. в PEP 3333.
-
wsgiref.util.guess_scheme(environ) -
Возвращает предположение о том, должно ли быть
wsgi.url_scheme«http» или «https», проверяя наличие переменной средыHTTPSв словаре environ. Возвращаемое значение — строка.Эта функция полезна при создании шлюза, который оборачивает CGI или протокол, похожий на CGI, такой как FastCGI. Обычно серверы, предоставляющие такие протоколы, включают переменную
HTTPSсо значением «1», «yes» или «on», когда запрос получен через SSL. Таким образом, эта функция возвращает «https», если такое значение найдено, и «http» в противном случае.
-
wsgiref.util.request_uri(environ, include_query=True) -
Возвращает полный URI запроса, необязательно включая строку запроса, используя алгоритм, описанный в разделе «Восстановление URL» в PEP 3333. Если include_query ложно, строка запроса не включается в результирующий URI.
-
wsgiref.util.application_uri(environ) -
Аналогично
request_uri(), за исключением того, что переменныеPATH_INFOиQUERY_STRINGигнорируются. Результатом является базовый URI объекта приложения, на который указывает запрос.
-
wsgiref.util.shift_path_info(environ) -
Перемещает единственное имя из
PATH_INFOвSCRIPT_NAMEи возвращает это имя. Словарь environ изменяется на месте; используйте копию, если вам нужно сохранить исходныйPATH_INFOилиSCRIPT_NAMEнеизменными.Если в
PATH_INFOбольше нет сегментов пути, возвращаетсяNone.Обычно эта процедура используется для обработки каждого фрагмента пути URI запроса, например, для обработки пути как серии ключей словаря. Эта процедура изменяет переданную среду, чтобы сделать ее подходящей для вызова другого WSGI-приложения, расположенного в целевом URI. Например, если WSGI-приложение находится по адресу
/foo, а путь URI запроса —/foo/bar/baz, и WSGI-приложение по адресу/fooвызываетshift_path_info(), оно получит строку «bar», а среда будет обновлена, чтобы стать подходящей для передачи WSGI-приложению по адресу/foo/bar. То есть,SCRIPT_NAMEизменится с/fooна/foo/bar, аPATH_INFOизменится с/bar/bazна/baz.Когда
PATH_INFO— просто «/», эта процедура возвращает пустую строку и добавляет конечный слэш кSCRIPT_NAME, даже несмотря на то, что пустые сегменты пути обычно игнорируются, аSCRIPT_NAMEобычно не заканчивается слэшем. Это преднамеренное поведение, чтобы гарантировать, что приложение может отличить URI, заканчивающиеся/xот URI, заканчивающихся/x/, при использовании этой процедуры для обхода объектов.
-
wsgiref.util.setup_testing_defaults(environ) -
Обновляет environ с тривиальными значениями по умолчанию для целей тестирования.
Эта процедура добавляет различные параметры, необходимые для WSGI, включая
HTTP_HOST,SERVER_NAME,SERVER_PORT,REQUEST_METHOD,SCRIPT_NAME,PATH_INFO, и все переменные, определенные в PEP 3333. Она только предоставляет значения по умолчанию и не заменяет существующие настройки для этих переменных.Эта процедура предназначена для упрощения создания тестовых сред WSGI-серверов и приложений. Она НЕ должна использоваться реальными WSGI-серверами или приложениями, так как данные являются фиктивными!
Пример использования:
from wsgiref.util import setup_testing_defaults from wsgiref.simple_server import make_server # A relatively simple WSGI application. It's going to print out the # environment dictionary after being updated by setup_testing_defaults def simple_app(environ, start_response): setup_testing_defaults(environ) status = '200 OK' headers = [('Content-type', 'text/plain; charset=utf-8')] start_response(status, headers) ret = [("%s: %s\n" % (key, value)).encode("utf-8") for key, value in environ.items()] return ret with make_server('', 8000, simple_app) as httpd: print("Serving on port 8000...") httpd.serve_forever()
Помимо функций среды, перечисленных выше, модуль wsgiref.util также предоставляет следующие вспомогательные функции:
-
wsgiref.util.is_hop_by_hop(header_name) -
Возвращает
Trueесли ‘header_name’ — это заголовок HTTP/1.1 «Hop-by-Hop», как определено в RFC 2616.
-
class wsgiref.util.FileWrapper(filelike, blksize=8192) -
Оборачивает объект, похожий на файл, в итератор. Полученные объекты поддерживают как
__getitem__(), так и__iter__()стили итерации для совместимости с Python 2.1 и Jython. По мере итерации по объекту, необязательный параметр blksize будет многократно передаваться методуread()объекта filelike, чтобы получить байтовые строки, которые будут возвращаться. Когдаread()возвращает пустую байтовую строку, итерация завершается и не может быть возобновлена.Если у filelike есть метод
close(), у возвращаемого объекта также будет методclose(), и он вызовет методclose()объекта filelike при вызове.Пример использования:
from io import StringIO from wsgiref.util import FileWrapper # We're using a StringIO-buffer for as the file-like object filelike = StringIO("This is an example file-like object"*10) wrapper = FileWrapper(filelike, blksize=5) for chunk in wrapper: print(chunk)Устарело начиная с версии 3.8: Поддержка
sequence protocolустарела.
wsgiref.headers – Инструменты для заголовков ответа WSGI
Этот модуль предоставляет единственный класс, Headers, для удобной работы с заголовками ответа WSGI с использованием интерфейса, похожего на отображение.
-
class wsgiref.headers.Headers([headers]) -
Создает объект, похожий на отображение, который оборачивает headers, который должен быть списком кортежей имён/значений заголовков, как описано в PEP 3333. Значение по умолчанию для headers — это пустой список.
Headersобъекты поддерживают типичные операции с отображениями, включая__getitem__(),get(),__setitem__(),setdefault(),__delitem__()и__contains__(). Для каждой из этих методов ключ — это имя заголовка (обрабатывается без учета регистра), а значение — первое значение, связанное с этим именем заголовка. Установка заголовка удаляет все существующие значения для этого заголовка, а затем добавляет новое значение в конец обернутого списка заголовков. Общий порядок заголовков сохраняется, новые заголовки добавляются в конец обернутого списка.В отличие от словаря,
Headersобъекты не генерируют ошибку, когда вы пытаетесь получить или удалить ключ, который не содержится в обернутом списке заголовков. Получение несуществующего заголовка возвращаетNone, а удаление несуществующего заголовка ничего не делает.Headersобъекты также поддерживаютkeys(),values(), иitems()методы. Список, возвращаемыйkeys()иitems(), может содержать один и тот же ключ более одного раза, если заголовок имеет несколько значений. Количество элементовHeadersобъекта равно длине егоitems(), что равно длине обернутого списка заголовков. Фактически, методitems()просто возвращает копию обернутого списка заголовков.Вызов
bytes()дляHeadersобъекта возвращает отформатированную строку байтов, подходящую для передачи в качестве заголовков ответа HTTP. Каждый заголовок размещается в строке со своим значением, разделенными двоеточием и пробелом. Каждая строка завершается символами возврата каретки и перевода строки, а строка байтов завершается пустой строкой.В дополнение к их интерфейсу отображения и функциям форматирования,
Headersобъекты также имеют следующие методы для запроса и добавления заголовков с несколькими значениями, а также для добавления заголовков с параметрами MIME:-
get_all(name) -
Возвращает список всех значений для указанного заголовка.
Возвращаемый список будет отсортирован в порядке их появления в исходном списке заголовков или добавления в этот экземпляр и может содержать дубликаты. Любые удаленные и повторно вставленные поля всегда добавляются в конец списка заголовков. Если для данного имени нет полей, возвращается пустой список.
-
add_header(name, value, **_params) -
Добавляет заголовок (возможно, с несколькими значениями), с необязательными параметрами MIME, указанными через ключевые аргументы.
name — поле заголовка для добавления. Ключевые аргументы могут быть использованы для установки параметров MIME для поля заголовка. Каждый параметр должен быть строкой или
None. Подчеркивания в именах параметров преобразуются в дефисы, поскольку дефисы недопустимы в идентификаторах Python, но многие имена параметров MIME включают дефисы. Если значение параметра является строкой, оно добавляется к параметрам значения заголовка в форматеname="value". Если этоNone, добавляется только имя параметра. (Это используется для параметров MIME без значения.) Пример использования:h.add_header('content-disposition', 'attachment', filename='bud.gif')Выше будет добавлен заголовок, который выглядит так:
Content-Disposition: attachment; filename="bud.gif"
Изменено в версии 3.5: Параметр headers является необязательным.
-
wsgiref.simple_server – простой сервер WSGI HTTP
Этот модуль реализует простой HTTP-сервер (на основе http.server), обслуживающий WSGI-приложения. Каждый экземпляр сервера обслуживает одно WSGI-приложение на заданном хосте и порту. Если вам нужно обслуживать несколько приложений на одном хосте и порту, вы должны создать WSGI-приложение, которое анализирует PATH_INFO для выбора приложения, которое нужно вызвать для каждого запроса. (Например, используя функцию shift_path_info() из wsgiref.util.)
-
wsgiref.simple_server.make_server(host, port, app, server_class=WSGIServer, handler_class=WSGIRequestHandler) -
Создает новый WSGI-сервер, прослушивающий host и port, принимающий подключения для app. Возвращаемое значение — экземпляр предоставленного server_class, который будет обрабатывать запросы с использованием указанного handler_class. app должен быть объектом WSGI-приложения, как определено в PEP 3333.
Пример использования:
from wsgiref.simple_server import make_server, demo_app with make_server('', 8000, demo_app) as httpd: print("Serving HTTP on port 8000...") # Respond to requests until process is killed httpd.serve_forever() # Alternative: serve one request, then exit httpd.handle_request()
-
wsgiref.simple_server.demo_app(environ, start_response) -
Эта функция — небольшое, но полное WSGI-приложение, которое возвращает текстовую страницу с сообщением «Hello world!» и списком пар «ключ-значение», предоставленных в параметре environ. Она полезна для проверки того, что WSGI-сервер (например,
wsgiref.simple_server) может правильно запускать простое WSGI-приложение.
-
class wsgiref.simple_server.WSGIServer(server_address, RequestHandlerClass) -
Создает экземпляр
WSGIServer. server_address должен быть кортежем(host,port), а RequestHandlerClass — подклассомhttp.server.BaseHTTPRequestHandler, который будет использоваться для обработки запросов.Вам обычно не нужно вызывать этот конструктор, так как функция
make_server()может справиться со всеми подробностями за вас.WSGIServerявляется подклассомhttp.server.HTTPServer, поэтому все его методы (такие какserve_forever()иhandle_request()) доступны.WSGIServerтакже предоставляет эти методы, специфичные для WSGI:-
set_app(application) -
Устанавливает вызываемый объект application как WSGI-приложение, которое будет получать запросы.
-
get_app() -
Возвращает текущий установленный вызываемый объект приложения.
Однако обычно вам не нужно использовать эти дополнительные методы, так как
set_app()обычно вызываетсяmake_server(), аget_app()существует в основном для удобства экземпляров обработчиков запросов. -
-
class wsgiref.simple_server.WSGIRequestHandler(request, client_address, server) -
Создает обработчик HTTP для заданного request (т. е. сокета), client_address (кортеж
(host,port)) и server (WSGIServer).Вам не нужно создавать экземпляры этого класса напрямую; они автоматически создаются по мере необходимости объектами
WSGIServer. Однако вы можете создать подкласс этого класса и предоставить его как handler_class функцииmake_server(). Некоторые, возможно, релевантные методы для переопределения в подклассах:-
get_environ() -
Возвращает словарь, содержащий WSGI-среду для запроса. По умолчанию реализация копирует содержимое словаря атрибута
WSGIServerи добавляет различные заголовки, полученные из HTTP-запроса. Каждый вызов этого метода должен возвращать новый словарь, содержащий все соответствующие переменные среды CGI, как указано в PEP 3333.
-
get_stderr() -
Возвращает объект, который должен использоваться как поток
wsgi.errors. По умолчанию реализация просто возвращаетsys.stderr.
-
handle() -
Обрабатывает HTTP-запрос. По умолчанию реализация создает экземпляр обработчика с использованием класса
wsgiref.handlersдля реализации фактического интерфейса WSGI-приложения.
-
wsgiref.validate — Проверятель соответствия WSGI
При создании новых объектов WSGI-приложений, фреймворков, серверов или промежуточного программного обеспечения полезно проверять соответствие нового кода с помощью wsgiref.validate. Этот модуль предоставляет функцию, которая создает объекты WSGI-приложений, которые проверяют коммуникацию между WSGI-сервером или шлюзом и объектом WSGI-приложения, чтобы проверить обе стороны на соответствие протоколу.
Обратите внимание, что эта утилита не гарантирует полное соответствие PEP 3333; отсутствие ошибок в этом модуле не обязательно означает, что ошибок нет. Однако, если этот модуль выдает ошибку, то практически наверняка сервер или приложение не полностью соответствует спецификации.
Этот модуль основан на модуле paste.lint из библиотеки «Python Paste» Иана Бикинга.
-
wsgiref.validate.validator(application) -
Оборачивает application и возвращает новый объект WSGI-приложения. Возвращаемое приложение будет пересылать все запросы исходному application и проверяет, что как application, так и вызывающий его сервер соответствуют спецификации WSGI и RFC 2616.
Любое выявленное несоответствие приводит к тому, что возникает исключение
AssertionError; однако, как обрабатываются эти ошибки, зависит от сервера. Например,wsgiref.simple_serverи другие серверы, основанные наwsgiref.handlers(которые не переопределяют методы обработки ошибок, чтобы сделать что-то другое), просто выведут сообщение об ошибке и отобразят отладочную информацию вsys.stderrили в каком-то другом потоке ошибок.Этот обёртный класс также может генерировать вывод с использованием модуля
warningsдля указания поведения, которое вызывает сомнения, но которое может не быть запрещено PEP 3333. Если эти предупреждения не подавлены с помощью опций командной строки Python или APIwarnings, любые такие предупреждения будут записаны вsys.stderr(неwsgi.errors, если они не являются одним и тем же объектом).Пример использования:
from wsgiref.validate import validator from wsgiref.simple_server import make_server # Our callable object which is intentionally not compliant to the # standard, so the validator is going to break def simple_app(environ, start_response): status = '200 OK' # HTTP Status headers = [('Content-type', 'text/plain')] # HTTP Headers start_response(status, headers) # This is going to break because we need to return a list, and # the validator is going to inform us return b"Hello World" # This is the application wrapped in a validator validator_app = validator(simple_app) with make_server('', 8000, validator_app) as httpd: print("Listening on port 8000....") httpd.serve_forever()
wsgiref.handlers – базовые классы серверов/шлюзов
Этот модуль предоставляет базовые классы обработчиков для реализации WSGI-серверов и шлюзов. Эти базовые классы обрабатывают большую часть работы по взаимодействию с WSGI-приложением, если им предоставлена среда, похожая на CGI, а также входные, выходные и потоки ошибок.
-
class wsgiref.handlers.CGIHandler -
Вызов на основе CGI с помощью
sys.stdin,sys.stdout,sys.stderrиos.environ. Это полезно, когда у вас есть WSGI-приложение, и вы хотите запустить его как CGI-скрипт. Просто вызовитеCGIHandler().run(app), гдеapp— объект WSGI-приложения, который вы хотите вызвать.Этот класс является подклассом
BaseCGIHandler, который устанавливаетwsgi.run_onceв true,wsgi.multithreadв false иwsgi.multiprocessв true и всегда используетsysиosдля получения необходимых CGI-потоков и среды.
-
class wsgiref.handlers.IISCGIHandler -
Специализированная альтернатива
CGIHandlerдля использования при развертывании на веб-сервере Microsoft IIS без установки параметра config allowPathInfo (IIS>=7) или metabase allowPathInfoForScriptMappings (IIS<7).По умолчанию IIS предоставляет
PATH_INFO, который дублируетSCRIPT_NAMEв начале, что вызывает проблемы для WSGI-приложений, которые хотят реализовать маршрутизацию. Этот обработчик удаляет любой такой дублированный путь.IIS можно настроить на передачу правильного
PATH_INFO, но это приводит к другой ошибке, гдеPATH_TRANSLATEDнеправильный. К счастью, эта переменная редко используется и не гарантируется WSGI. Однако в IIS<7 настройка может быть выполнена только на уровне виртуального хоста, влияя на все другие сопоставления скриптов, многие из которых выходят из строя при воздействии ошибкиPATH_TRANSLATED. По этой причине IIS<7 почти никогда не развертывается с исправлениями (даже IIS7 редко его использует, поскольку для него до сих пор нет графического интерфейса).Нет способа для CGI-кода определить, был ли параметр установлен, поэтому предоставляется отдельный класс обработчика. Он используется так же, как
CGIHandler, то есть вызываяIISCGIHandler().run(app), гдеapp— объект WSGI-приложения, который вы хотите вызвать.Новое в версии 3.2.
-
class wsgiref.handlers.BaseCGIHandler(stdin, stdout, stderr, environ, multithread=True, multiprocess=False) -
Аналогично
CGIHandler, но вместо использования модулейsysиosсреда CGI и потоки ввода/вывода задаются явно. Значения multithread и multiprocess используются для установки флаговwsgi.multithreadиwsgi.multiprocessдля любых приложений, запускаемых экземпляром обработчика.Этот класс является подклассом
SimpleHandler, предназначенным для использования с программным обеспечением, отличным от HTTP-«серверов-источников». Если вы пишете реализацию протокола шлюза (такого как CGI, FastCGI, SCGI и т. д.), которая использует заголовокStatus:для отправки HTTP-кода состояния, вы, вероятно, захотите унаследовать от него вместоSimpleHandler.
-
class wsgiref.handlers.SimpleHandler(stdin, stdout, stderr, environ, multithread=True, multiprocess=False) -
Аналогично
BaseCGIHandler, но предназначен для использования с HTTP-серверами-источниками. Если вы пишете реализацию HTTP-сервера, вы, вероятно, захотите унаследовать от него вместоBaseCGIHandler.Этот класс является подклассом
BaseHandler. Он переопределяет методы__init__(),get_stdin(),get_stderr(),add_cgi_vars(),_write(), и_flush()для поддержки явного задания среды и потоков через конструктор. Предоставленная среда и потоки хранятся в атрибутахstdin,stdout,stderr, иenviron.Метод
write()объекта stdout должен записывать каждый фрагмент полностью, как вio.BufferedIOBase.
-
class wsgiref.handlers.BaseHandler -
Это абстрактный базовый класс для запуска WSGI-приложений. Каждый экземпляр будет обрабатывать один HTTP-запрос, хотя в принципе можно создать подкласс, который можно использовать для нескольких запросов.
BaseHandlerэкземпляры имеют только один метод, предназначенный для внешнего использования:-
run(app) -
Запустить указанное WSGI-приложение, app.
Все остальные методы
BaseHandlerвызываются этим методом в процессе запуска приложения, и, следовательно, существуют в основном для возможности настройки процесса.Следующие методы ОБЯЗАТЕЛЬНО должны быть переопределены в подклассе:
-
_write(data) -
Буферизовать байты data для передачи клиенту. В порядке вещей, если этот метод фактически передаёт данные;
BaseHandlerпросто разделяет операции записи и сброса буфера для большей эффективности, когда подлежащая система на самом деле имеет такое различие.
-
_flush() -
Принудительно передать данные из буфера клиенту. В порядке вещей, если этот метод является пустой операцией (т.е., если
_write()фактически отправляет данные).
-
get_stdin() -
Возвращает объект потока ввода, подходящий для использования в качестве
wsgi.inputобрабатываемого запроса.
-
get_stderr() -
Возвращает объект потока вывода, подходящий для использования в качестве
wsgi.errorsобрабатываемого запроса.
-
add_cgi_vars() -
Вставляет переменные CGI для текущего запроса в атрибут
environ.
Вот некоторые другие методы и атрибуты, которые вам, возможно, захочется переопределить. Этот список — лишь краткое описание, и он не включает все методы, которые можно переопределить. Для дополнительной информации перед попыткой создания настраиваемого подкласса
BaseHandlerследует обратиться к строкам документации и исходному коду.Атрибуты и методы для настройки WSGI-окружения:
-
wsgi_multithread -
Значение, используемое для переменной окружения
wsgi.multithread. По умолчанию оно равно true вBaseHandler, но может иметь другое значение по умолчанию (или быть установлено конструктором) в других подклассах.
-
wsgi_multiprocess -
Значение, используемое для переменной окружения
wsgi.multiprocess. По умолчанию оно равно true вBaseHandler, но может иметь другое значение по умолчанию (или быть установлено конструктором) в других подклассах.
-
wsgi_run_once -
Значение, используемое для переменной окружения
wsgi.run_once. По умолчанию оно равно false вBaseHandler, ноCGIHandlerустанавливает его по умолчанию в true.
-
os_environ -
Переменные окружения по умолчанию, которые должны быть включены в WSGI-окружение каждого запроса. По умолчанию это копия
os.environна момент импортаwsgiref.handlers, но подклассы могут либо создать свои собственные на уровне класса или экземпляра. Обратите внимание, что словарь следует рассматривать как неизменяемый, так как значение по умолчанию используется несколькими классами и экземплярами.
-
server_software -
Если атрибут
origin_serverустановлен, значение этого атрибута используется для установки значения переменной окруженияSERVER_SOFTWAREWSGI, а также для установки значения заголовкаServer:в HTTP-ответах. Он игнорируется для обработчиков (таких какBaseCGIHandlerиCGIHandler), которые не являются HTTP-серверами-источниками.Изменено в версии 3.3: Термин «Python» заменён на термин, специфичный для реализации, такой как «CPython», «Jython» и т.д.
-
get_scheme() -
Возвращает используемую схему URL для текущего запроса. Реализация по умолчанию использует функцию
guess_scheme()изwsgiref.utilдля определения того, должна ли схема быть «http» или «https», на основе переменныхenvironтекущего запроса.
-
setup_environ() -
Устанавливает атрибут
environв полностью заполненную WSGI-среду. Реализация по умолчанию использует все вышеперечисленные методы и атрибуты, а также методыget_stdin(),get_stderr()иadd_cgi_vars(), и атрибутwsgi_file_wrapper. Также вставляет ключSERVER_SOFTWARE, если он отсутствует, при условии, что атрибутorigin_serverимеет истинное значение и атрибутserver_softwareустановлен.
Методы и атрибуты для настройки обработки исключений:
-
log_exception(exc_info) -
Записать кортеж exc_info в журнале сервера. exc_info — это кортеж
(type, value, traceback). Реализация по умолчанию просто записывает трассировку стека в потокwsgi.errorsзапроса и сбрасывает его. Подклассы могут переопределить этот метод, чтобы изменить формат или перенаправить вывод, отправить трассировку стека администратору или выполнить любое другое действие, которое может считаться подходящим.
-
traceback_limit -
Максимальное количество кадров, включаемых в трассировки стека, выводимые методом по умолчанию
log_exception(). ЕслиNone, включаются все кадры.
-
error_output(environ, start_response) -
Этот метод является WSGI-приложением для генерации страницы ошибки для пользователя. Он вызывается только в том случае, если ошибка возникает до отправки заголовков клиенту.
Этот метод может получить доступ к текущей информации об ошибке, используя
sys.exc_info(), и должен передать эту информацию в start_response при вызове (как описано в разделе «Обработка ошибок» в PEP 3333).Реализация по умолчанию просто использует атрибуты
error_status,error_headersиerror_bodyдля генерации страницы вывода. Подклассы могут переопределить этот метод, чтобы обеспечить более динамичный вывод ошибок.Однако с точки зрения безопасности не рекомендуется выводить диагностические данные любому пользователю; в идеале вы должны сделать что-то специальное, чтобы включить вывод диагностических данных, поэтому реализация по умолчанию не включает ничего такого.
-
error_status -
HTTP-статус, используемый для ответов об ошибках. Это строка статуса, как определено в PEP 3333; по умолчанию используется код 500 и сообщение.
-
error_headers -
HTTP-заголовки, используемые для ответов об ошибках. Это должен быть список заголовков WSGI-ответа (кортежи
(name, value)), как описано в PEP 3333. По умолчанию список устанавливает тип содержимого вtext/plain.
-
-
error_body -
Тело ответа об ошибке. Оно должно быть строкой байтов HTTP-ответа. По умолчанию установлено значение «Произошла ошибка сервера. Обратитесь к администратору».
Методы и атрибуты для функции «Дополнительная платформа-специфичная обработка файлов» из PEP 3333:
-
wsgi_file_wrapper -
Фабрика
wsgi.file_wrapper, илиNone. Значение этого атрибута по умолчанию — классwsgiref.util.FileWrapper.
-
sendfile() -
Переопределите для реализации платформо-специфической передачи файла. Этот метод вызывается только если возвращаемое значение приложения является экземпляром класса, указанного в атрибуте
wsgi_file_wrapper. Он должен вернуть истинное значение, если передача файла прошла успешно, чтобы код по умолчанию не был выполнен. По умолчанию этот метод возвращает ложное значение.
Разные методы и атрибуты:
-
origin_server -
Этот атрибут должен быть установлен в истинное значение, если обработчик
_write()и_flush()используются для прямого взаимодействия с клиентом, а не через прокси-сервер CGI, который требует HTTP-статус в специальномStatus:заголовке.Значение этого атрибута по умолчанию истинно в
BaseHandler, но ложно вBaseCGIHandlerиCGIHandler.
-
http_version -
Если
origin_serverистинно, эта строковая переменная используется для установки HTTP-версии ответа, отправленного клиенту. По умолчанию установлено значение"1.0".
-
-
wsgiref.handlers.read_environ() -
Преобразует CGI-переменные из
os.environв строки «байты в Unicode» из PEP 3333, возвращая новый словарь. Эта функция используетсяCGIHandlerиIISCGIHandlerвместо прямого использованияos.environ, что не обязательно является WSGI-совместимым на всех платформах и веб-серверах с Python 3 — особенно там, где окружение ОС является Unicode (например, Windows), или там, где окружение является байтами, но кодировка системы, используемая Python для декодирования, отличается от ISO-8859-1 (например, Unix-системы с UTF-8).Если вы реализуете обработчик CGI, вам, вероятно, следует использовать эту функцию вместо прямого копирования значений из
os.environ.New in version 3.2.
Примеры
Это работающее WSGI-приложение «Hello World»:
from wsgiref.simple_server import make_server
# Every WSGI application must have an application object - a callable
# object that accepts two arguments. For that purpose, we're going to
# use a function (note that you're not limited to a function, you can
# use a class for example). The first argument passed to the function
# is a dictionary containing CGI-style environment variables and the
# second variable is the callable object.
def hello_world_app(environ, start_response):
status = '200 OK' # HTTP Status
headers = [('Content-type', 'text/plain; charset=utf-8')] # HTTP Headers
start_response(status, headers)
# The returned object is going to be printed
return [b"Hello World"]
with make_server('', 8000, hello_world_app) as httpd:
print("Serving on port 8000...")
# Serve until process is killed
httpd.serve_forever()
Пример WSGI-приложения, обслуживающего текущую директорию, принимающего необязательные директорию и номер порта (по умолчанию: 8000) в командной строке:
#!/usr/bin/env python3
'''
Small wsgiref based web server. Takes a path to serve from and an
optional port number (defaults to 8000), then tries to serve files.
Mime types are guessed from the file names, 404 errors are raised
if the file is not found. Used for the make serve target in Doc.
'''
import sys
import os
import mimetypes
from wsgiref import simple_server, util
def app(environ, respond):
fn = os.path.join(path, environ['PATH_INFO'][1:])
if '.' not in fn.split(os.path.sep)[-1]:
fn = os.path.join(fn, 'index.html')
type = mimetypes.guess_type(fn)[0]
if os.path.exists(fn):
respond('200 OK', [('Content-Type', type)])
return util.FileWrapper(open(fn, "rb"))
else:
respond('404 Not Found', [('Content-Type', 'text/plain')])
return [b'not found']
if __name__ == '__main__':
path = sys.argv[1] if len(sys.argv) > 1 else os.getcwd()
port = int(sys.argv[2]) if len(sys.argv) > 2 else 8000
httpd = simple_server.make_server('', port, app)
print("Serving {} on port {}, control-C to stop".format(path, port))
try:
httpd.serve_forever()
except KeyboardInterrupt:
print("Shutting down.")
httpd.server_close()
© 2001–2023 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.10/library/wsgiref.html