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