wsgiref — утилиты WSGI и эталонная реализация
Исходный код: Lib/wsgiref
Интерфейс шлюза веб-сервера (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, а псевдоним типа, который можно использовать в аннотациях типов, — в WSGIEnvironment.
-
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 имеет значение 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, и URI, заканчивающиеся на/x/.
-
wsgiref.util.setup_testing_defaults(environ) -
Добавить в environ простые значения по умолчанию для тестирования.
Эта процедура добавляет различные параметры, требуемые WSGI, включая
HTTP_HOST,SERVER_NAME,SERVER_PORT,REQUEST_METHOD,SCRIPT_NAME,PATH_INFOи все переменныеwsgi.*, определённые в PEP 3333. Она только задаёт значения по умолчанию и не заменяет существующие значения этих переменных.Эта процедура предназначена для упрощения настройки фиктивных окружений в модульных тестах серверов и приложений WSGI. Её НЕ следует использовать в реальных серверах или приложениях WSGI, поскольку данные фиктивные!
Пример использования (см. также
demo_app()для другого примера):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) -
Конкретная реализация протокола
wsgiref.types.FileWrapper, используемого для преобразования файловоподобного объекта в итератор. Полученные объекты являются итерируемыми. При переборе объекта необязательный параметр blksize будет многократно передаваться методуread()файловоподобного объекта для получения байтовых строк, которые нужно выдать. Когдаread()возвращает пустую байтовую строку, перебор завершается и возобновить его нельзя.Если у filelike есть метод
close(), у возвращаемого объекта также будет методclose(), который при вызове вызовет методclose()файловоподобного объекта.Пример использования:
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.11: Поддержка метода
__getitem__()удалена.
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(), могут содержать один и тот же ключ несколько раз, если заголовок имеет несколько значений.len()объекта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 – простой HTTP-сервер WSGI
Этот модуль реализует простой 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.Вызываемый объект start_response должен соответствовать протоколу
StartResponse.
-
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() -
Вернуть словарь
WSGIEnvironmentдля запроса. Реализация по умолчанию копирует содержимое атрибута-словаряbase_environобъекта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; отсутствие ошибок, обнаруженных этим модулем, не обязательно означает отсутствие ошибок. Однако если модуль выдаёт ошибку, почти наверняка сервер или приложение не соответствует требованиям на 100%.
Этот модуль основан на модуле paste.lint из библиотеки «Python Paste» Иэна Биккинга.
-
wsgiref.validate.validator(application) -
Обернуть application и вернуть новый объект приложения WSGI. Возвращённое приложение будет перенаправлять все запросы исходному application и проверять, соответствуют ли спецификации WSGI и RFC 2616 как application, так и вызывающий его сервер.
При обнаружении несоответствия возникает исключение
AssertionError; однако способ обработки таких ошибок зависит от сервера. Например,wsgiref.simple_serverи другие серверы на основеwsgiref.handlers(не переопределяющие методы обработки ошибок для выполнения других действий) просто выведут сообщение о возникшей ошибке и трассировку стека вsys.stderrили другой поток ошибок.Эта обёртка также может выводить сообщения с помощью модуля
warnings, указывающие на сомнительное поведение, которое, возможно, не запрещено PEP 3333. Если такие предупреждения не отключены параметрами командной строки Python или API модуляwarnings, они будут записаны в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, если не задан параметр конфигурации allowPathInfo (IIS>=7) или параметр метабазы 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() -
Возвращает объект, совместимый с
InputStreamи подходящий для использования в качествеwsgi.inputтекущего обрабатываемого запроса.
-
get_stderr() -
Возвращает объект, совместимый с
ErrorStreamи подходящий для использования в качестве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, значение этого атрибута используется для установки значения по умолчанию для переменной окружения WSGISERVER_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.exception()и должен передать эту информацию в start_response при его вызове (как описано в разделе «Обработка ошибок» документа PEP 3333). В частности, вызываемый объект start_response должен соответствовать протоколуStartResponse.Реализация по умолчанию использует атрибуты
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, совместимая сwsgiref.types.FileWrapper, или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в строки формата «байты в Unicode» из PEP 3333 и возвращает новый словарь. Эта функция используется вCGIHandlerиIISCGIHandlerвместо прямого использованияos.environ, которое не обязательно соответствует WSGI на всех платформах и веб-серверах, использующих Python 3. В частности, это относится к системам, где фактическое окружение ОС представлено в Unicode (например, Windows), или к системам, где окружение представлено байтами, но системная кодировка, используемая Python для их декодирования, отличается от ISO-8859-1 (например, Unix-системы с UTF-8).Если вы реализуете собственный обработчик на основе CGI, вероятно, вам следует использовать эту функцию, а не просто копировать значения напрямую из
os.environ.Добавлено в версии 3.2.
wsgiref.types – типы WSGI для статической проверки типов
Этот модуль предоставляет различные типы для статической проверки типов, как описано в PEP 3333.
Добавлено в версии 3.11.
-
class wsgiref.types.StartResponse -
typing.Protocol, описывающий вызываемые объекты start_response() (PEP 3333).
-
wsgiref.types.WSGIEnvironment -
Псевдоним типа для словаря окружения WSGI.
-
wsgiref.types.WSGIApplication -
Псевдоним типа для вызываемого объекта приложения WSGI.
-
class wsgiref.types.InputStream -
typing.Protocol, описывающий поток ввода WSGI.
-
class wsgiref.types.ErrorStream -
typing.Protocol, описывающий поток ошибок WSGI.
-
class wsgiref.types.FileWrapper -
typing.Protocol, описывающий обертку файла. См.wsgiref.util.FileWrapper— конкретную реализацию этого протокола.
Примеры
Это работающее приложение WSGI «Hello World»; вызываемый объект start_response должен соответствовать протоколу StartResponse:
"""
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.
"""
from wsgiref.simple_server import make_server
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):
"""
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.
"""
import mimetypes
import os
import sys
from wsgiref import simple_server, util
def app(environ, respond):
# Get the file name and MIME type
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")
mime_type = mimetypes.guess_type(fn)[0]
# Return 200 OK if file exists, otherwise 404 Not Found
if os.path.exists(fn):
respond("200 OK", [("Content-Type", mime_type)])
return util.FileWrapper(open(fn, "rb"))
else:
respond("404 Not Found", [("Content-Type", "text/plain")])
return [b"not found"]
if __name__ == "__main__":
# Get the path and port from command-line arguments
path = sys.argv[1] if len(sys.argv) > 1 else os.getcwd()
port = int(sys.argv[2]) if len(sys.argv) > 2 else 8000
# Make and start the server until control-c
httpd = simple_server.make_server("", port, app)
print(f"Serving {path} on port {port}, control-C to stop")
try:
httpd.serve_forever()
except KeyboardInterrupt:
print("Shutting down.")
httpd.server_close()
© 2001–2024 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.12/library/wsgiref.html