wsgiref — утилиты WSGI и эталонная реализация
Исходный код: Lib/wsgiref
Предупреждение
wsgiref — эталонная реализация, не предназначенная для использования в производственной среде. Модуль реализует только базовые проверки безопасности.
Интерфейс шлюза веб-сервера (WSGI) — это стандартный интерфейс между программным обеспечением веб-сервера и веб-приложениями, написанными на Python. Наличие стандартного интерфейса упрощает использование приложения, поддерживающего WSGI, с различными веб-серверами.
Все детали и особые случаи проектирования WSGI необходимо знать только разработчикам веб-серверов и программных фреймворков. Чтобы установить приложение WSGI или написать веб-приложение с помощью существующего фреймворка, не нужно разбираться во всех деталях WSGI.
wsgiref — эталонная реализация спецификации WSGI, которую можно использовать для добавления поддержки WSGI в веб-сервер или фреймворк. Она предоставляет утилиты для работы с переменными среды WSGI и заголовками ответа, базовые классы для реализации серверов WSGI, демонстрационный HTTP-сервер для приложений 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()объекта 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.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, возвращающее текстовую страницу с сообщением «Hello world!» и списком пар «ключ/значение», переданных в параметре 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; отсутствие ошибок, выявленных этим модулем, не обязательно означает, что ошибок нет. Однако если модуль обнаруживает ошибку, то почти наверняка сервер или приложение не полностью соответствует спецификации.
Этот модуль основан на модуле paste.lint из библиотеки «Python Paste» Яна Бикинга.
-
wsgiref.validate.validator(application) -
Оборачивает application и возвращает новый объект приложения WSGI. Возвращённое приложение перенаправляет все запросы исходному 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; для получения необходимых потоков CGI и окружения всегда используютсяsysиos.
-
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. Для обработчиков, не являющихся HTTP-серверами источника (например,BaseCGIHandlerиCGIHandler), этот атрибут игнорируется.Изменено в версии 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. Кроме того, если атрибутorigin_serverимеет истинное значение, а атрибутserver_softwareзадан, метод добавляет ключ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 «Привет, мир!», в котором вызываемый объект 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_file_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 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.14/library/wsgiref.html