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, а псевдоним типа, который можно использовать в аннотациях типов, см. в WSGIEnvironment.
-
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от 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) -
Конкретная реализация протокола
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(), могут содержать один и тот же ключ более одного раза, если заголовок имеет несколько значений. Длина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-приложение, которое возвращает текстовую страницу с сообщением «Привет, мир!» и списком пар ключ/значение, предоставленных в параметре 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() -
Возвращает словарь
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 и проверяет, что и application, и вызывающий его сервер соответствуют спецификации WSGI и RFC 2616.
Любое обнаруженное несоответствие приводит к тому, что возникает
AssertionError; однако то, как эти ошибки обрабатываются, зависит от сервера. Например,wsgiref.simple_serverи другие серверы, основанные наwsgiref.handlers(которые не переопределяют методы обработки ошибок, чтобы сделать что-то другое), просто выведут сообщение об ошибке и выведут трассировку стека вsys.stderrили в какой-то другой поток ошибок.Этот обертка также может генерировать вывод с использованием модуля
warningsдля указания сомнительных поведений, которые фактически могут не быть запрещены PEP 3333. Все такие предупреждения будут записаны вsys.stderr(неwsgi.errors, если они не окажутся одним и тем же объектом), если они не подавлены с помощью командной строки Python или APIwarnings.Пример использования:
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() -
Возвращает объект, совместимый с
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установлен, значение этого атрибута используется для установки значения переменной среды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.exception(), и должен передать эту информацию в 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, совместимая сwsgiref.types.FileWrapper, или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в строки PEP 3333 «байты в строках Unicode», возвращая новый словарь. Эта функция используется в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»:
"""
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