wsgiref — Утилиты WSGI и эталонная реализация
Интерфейс Web Server Gateway Interface (WSGI) — это стандартный интерфейс между веб-серверным программным обеспечением и веб-приложениями, написанными на Python. Наличие стандартного интерфейса упрощает использование приложения, поддерживающего WSGI, с различными веб-серверами.
Только авторы веб-серверов и программных фреймворков должны знать все детали и частные случаи конструкции WSGI. Вам не нужно понимать все детали WSGI, просто чтобы установить приложение WSGI или написать веб-приложение, используя существующий фреймворк.
wsgiref является эталонной реализацией спецификации WSGI, которая может быть использована для добавления поддержки WSGI к веб-серверу или фреймворку. Она предоставляет утилиты для обработки переменных среды WSGI и заголовков ответа, базовые классы для реализации WSGI-серверов, демонстрационный HTTP-сервер, который обслуживает WSGI-приложения, и инструмент проверки, который проверяет WSGI-серверы и приложения на соответствие спецификации WSGI (PEP 3333).
Дополнительную информацию о WSGI, а также ссылки на учебные пособия и другие ресурсы см. на странице https://wsgi.readthedocs.org/.
21.4.1. 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», «да» или «вкл.» при получении запроса через SSL. Таким образом, эта функция возвращает «https», если такое значение найдено, и «http» в противном случае.
-
wsgiref.util.request_uri(environ, include_query=True) -
Возвращает полный URI запроса, необязательно включая строку запроса, используя алгоритм, описанный в разделе «Восстановление URL» в PEP 3333. Если include_query равно False, строка запроса не включается в результирующий 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от тех, которые заканчиваются/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)
21.4.2. wsgiref.headers — Инструменты заголовков ответа WSGI
Этот модуль предоставляет единственный класс Headers для удобной работы с заголовками ответа WSGI с помощью интерфейса, подобного отображению.
-
class wsgiref.headers.Headers([headers]) -
Создайте объект, похожий на отображение, обертывающий заголовки, которые должны быть списком кортежей имени/значения заголовка, как описано в PEP 3333. Значение по умолчанию для заголовков — это пустой список.
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: Параметр заголовки является необязательным.
-
21.4.3. 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-приложением, которое возвращает текстовую страницу, содержащую сообщение «Привет, мир!» и список пар ключ/значение, предоставленных в параметре 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 для заданного запроса (т.е. сокета), адреса_клиента (кортеж
(host,port)) и сервера (WSGIServerэкземпляр).Вам не нужно создавать экземпляры этого класса напрямую; они автоматически создаются по мере необходимости объектами
WSGIServer. Однако вы можете унаследовать от этого класса и предоставить его как handler_class функцииmake_server(). Некоторые, возможно, релевантные методы для переопределения в подклассах:-
get_environ() -
Возвращает словарь, содержащий WSGI-среду для запроса. По умолчанию реализация копирует содержимое словаря атрибута
base_environобъектаWSGIServerи добавляет различные заголовки, полученные из HTTP-запроса. Каждый вызов этого метода должен возвращать новый словарь, содержащий все соответствующие переменные среды CGI, как указано в PEP 3333.
-
get_stderr() -
Возвращает объект, который должен использоваться в качестве потока
wsgi.errors. По умолчанию реализация просто возвращаетsys.stderr.
-
handle() -
Обработать HTTP-запрос. По умолчанию реализация создает экземпляр обработчика, используя класс
wsgiref.handlers, для реализации фактического интерфейса WSGI-приложения.
-
21.4.4. wsgiref.validate — Проверка соответствия WSGI
При создании новых объектов WSGI-приложений, фреймворков, серверов или среднего программного обеспечения может быть полезно проверить соответствие нового кода с помощью wsgiref.validate. Этот модуль предоставляет функцию, которая создает объекты WSGI-приложений, которые проверяют связь между WSGI-сервером или шлюзом и объектом WSGI-приложения, чтобы проверить обе стороны на соответствие протоколу.
Обратите внимание, что эта утилита не гарантирует полное соответствие PEP 3333; отсутствие ошибок в этом модуле не обязательно означает, что ошибок нет. Однако, если этот модуль выдает ошибку, то практически наверняка либо сервер, либо приложение не соответствуют требованиям на 100%.
Этот модуль основан на модуле paste.lint из библиотеки «Python Paste» Иана Бикинга.
-
wsgiref.validate.validator(application) -
Оборачивает приложение и возвращает новый объект WSGI-приложения. Возвращаемое приложение будет перенаправлять все запросы на исходное приложение и проверит, что и приложение, и вызывающий его сервер соответствуют спецификации 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()
21.4.5. 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-приложения, который вы хотите вызвать.New in version 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. По умолчанию вBaseHandlerоно равно true, но в других подклассах может быть другое значение по умолчанию (или быть установленным конструктором).
-
wsgi_multiprocess -
Значение, которое будет использоваться для переменной среды
wsgi.multiprocess. По умолчанию вBaseHandlerоно равно true, но в других подклассах может быть другое значение по умолчанию (или быть установленным конструктором).
-
wsgi_run_once -
Значение, которое будет использоваться для переменной среды
wsgi.run_once. По умолчанию вBaseHandlerоно равно false, ноCGIHandlerустанавливает его по умолчанию в true.
-
os_environ -
Переменные среды по умолчанию, которые будут включены в среду WSGI каждого запроса. По умолчанию это копия
os.environна момент импортаwsgiref.handlers, но подклассы могут создавать свои собственные на уровне класса или экземпляра. Обратите внимание, что словарь следует рассматривать как только для чтения, поскольку значение по умолчанию совместно используется между несколькими классами и экземплярами.
-
server_software -
Если атрибут
origin_serverустановлен, значение этого атрибута используется для установки значения переменной среды WSGI по умолчаниюSERVER_SOFTWARE, а также для установки заголовка по умолчанию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:заголовке.По умолчанию этот атрибут равен true в
BaseHandler, но false вBaseCGIHandlerиCGIHandler.
-
http_version -
Если
origin_serverимеет значение true, этот строковый атрибут используется для установки HTTP-версии ответа, отправленного клиенту. По умолчанию он равен"1.0".
-
-
wsgiref.handlers.read_environ() -
Преобразует CGI-переменные из
os.environв строки PEP 3333 «байты в unicode», возвращая новый словарь. Эта функция используется вCGIHandlerиIISCGIHandlerвместо непосредственного использованияos.environ, что не всегда соответствует WSGI на всех платформах и веб-серверах с Python 3 — особенно на системах, где окружение ОС является Unicode (например, Windows), или где окружение является байтами, но кодировка системы, используемая Python для его декодирования, отличается от ISO-8859-1 (например, Unix-системы с UTF-8).Если вы реализуете собственный обработчик CGI, вам, вероятно, следует использовать эту функцию вместо непосредственного копирования значений из
os.environ.Добавлена в версии 3.2.
21.4.6. Примеры
Это рабочее 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 (see PEP 333).
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()
© 2001–2020 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.6/library/wsgiref.html