wsgiref — Утилиты WSGI и эталонная реализация


Интерфейс шлюза веб-сервера (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 и все PEP 3333-определенные wsgi.* переменные. Он только предоставляет значения по умолчанию и не заменяет существующие настройки для этих переменных.

Эта процедура предназначена для того, чтобы облегчить модульные тесты серверов и приложений 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)

Обертка для преобразования файлоподобного объекта в iterator. Полученные объекты поддерживают стили итерации __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])

Создайте объект типа mapping, обертывающий 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-приложение.

class wsgiref.simple_server.WSGIServer(server_address, RequestHandlerClass)

Создайте экземпляр WSGIServer. server_address должен быть кортежем (host,port), а RequestHandlerClass должен быть подклассом http.server.BaseHTTPRequestHandler, который будет использоваться для обработки запросов.

Обычно вам не нужно вызывать этот конструктор, так как функция make_server() может обработать все детали за вас.

WSGIServer является подклассом http.server.HTTPServer, поэтому доступны все его методы (такие как serve_forever() и handle_request()). WSGIServer также предоставляет эти специфические для WSGI методы:

set_app(application)

Устанавливает вызываемое application в качестве приложения WSGI, которое будет принимать запросы.

get_app()

Возвращает текущую установленную вызываемую программу.

Обычно, однако, вам не нужно использовать эти дополнительные методы, так как set_app() обычно вызывается make_server(), а get_app() существует в основном для пользы экземпляров обработчиков запросов.

class wsgiref.simple_server.WSGIRequestHandler(request, client_address, server)

Создайте обработчик HTTP для заданного запроса (т.е. сокета), адрес_клиента (кортеж (host,port)) и сервер (экземпляр WSGIServer).

Вам не нужно создавать экземпляры этого класса напрямую; они автоматически создаются по мере необходимости объектами WSGIServer. Однако вы можете создать подкласс этого класса и передать его в качестве класса_обработчика в функцию make_server(). Некоторые возможные релевантные методы для переопределения в подклассах:

get_environ()

Возвращает словарь, содержащий среду WSGI для запроса. Реализация по умолчанию копирует содержимое атрибута словаря WSGIServer объекта base_environ, а затем добавляет различные заголовки, полученные из HTTP-запроса. Каждый вызов этого метода должен возвращать новый словарь, содержащий все соответствующие переменные среды CGI, как указано в PEP 3333.

get_stderr()

Возвращает объект, который должен использоваться в качестве потока wsgi.errors. Реализация по умолчанию просто возвращает sys.stderr.

handle()

Обработать HTTP-запрос. Реализация по умолчанию создает экземпляр обработчика, используя класс wsgiref.handlers для реализации фактического интерфейса приложения WSGI.

wsgiref.validate — Программа проверки соответствия WSGI

При создании новых объектов приложений WSGI, фреймворков, серверов или промежуточного программного обеспечения может быть полезно проверить соответствие нового кода с помощью wsgiref.validate. Этот модуль предоставляет функцию, создающую объекты приложений WSGI, которые проверяют связь между сервером или шлюзом WSGI и объектом приложения WSGI, чтобы проверить обе стороны на соответствие протоколу.

Обратите внимание, что эта утилита не гарантирует полного соответствия PEP 3333; отсутствие ошибок в этом модуле не обязательно означает, что ошибок не существует. Однако если этот модуль выдает ошибку, то практически наверняка сервер или приложение не соответствуют требованиям на 100%.

Этот модуль основан на модуле paste.lint из библиотеки Ian Bicking «Python Paste».

wsgiref.validate.validator(application)

Обернуть application и вернуть новый объект приложения WSGI. Возвращаемое приложение будет перенаправлять все запросы исходному приложению, и будет проверять соответствие приложения и вызывающего его сервера спецификации 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 без установки опции config allowPathInfo (IIS>=7) или metabase allowPathInfoForScriptMappings (IIS<7).

По умолчанию IIS выдает PATH_INFO, который дублирует SCRIPT_NAME впереди, что создает проблемы для приложений WSGI, которые хотят реализовать маршрутизацию. Этот обработчик удаляет любой такой дублированный путь.

IIS можно настроить на передачу правильного значения PATH_INFO, но это вызывает другую ошибку, когда PATH_TRANSLATED передается неправильно. К счастью, эта переменная используется редко и не гарантируется WSGI. Однако на IIS<7 эта настройка может быть выполнена только на уровне vhost, что влияет на все остальные сопоставления скриптов, многие из которых ломаются при воздействии ошибки 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 «origin servers». Если вы пишете реализацию протокола шлюза (например, CGI, FastCGI, SCGI и т.д.), который использует заголовок Status: для отправки статуса HTTP, вы, вероятно, захотите использовать этот подкласс вместо SimpleHandler.

class wsgiref.handlers.SimpleHandler(stdin, stdout, stderr, environ, multithread=True, multiprocess=False)

Аналогичен BaseCGIHandler, но предназначен для использования с серверами HTTP origin. Если вы пишете реализацию 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)

Буферизация байтов данных для передачи клиенту. Нет ничего страшного, если этот метод действительно передает данные; BaseHandler просто разделяет операции write и flush для большей эффективности, когда базовая система действительно имеет такое различие.

_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. В BaseHandler по умолчанию она имеет значение false, но CGIHandler по умолчанию устанавливает значение true.

os_environ

Переменные среды по умолчанию, которые должны быть включены в среду WSGI каждого запроса. По умолчанию это копия os.environ на момент импорта wsgiref.handlers, но подклассы могут создавать свои собственные на уровне класса или экземпляра. Обратите внимание, что словарь следует считать доступным только для чтения, поскольку значение по умолчанию является общим для нескольких классов и экземпляров.

server_software

Если установлен атрибут origin_server, значение этого атрибута используется для установки переменной среды WSGI по умолчанию SERVER_SOFTWARE, а также для установки заголовка по умолчанию Server: в ответах HTTP. Он игнорируется для обработчиков (таких как BaseCGIHandler и CGIHandler), которые не являются HTTP-серверами происхождения.

Изменено в версии 3.3: Термин «Python» заменяется термином, специфичным для конкретной реализации, например, «CPython», «Jython» и т.д.

get_scheme()

Возвращает схему URL, используемую для текущего запроса. Реализация по умолчанию использует функцию guess_scheme() из wsgiref.util, чтобы определить, должна ли схема быть «http» или «https», основываясь на переменных environ текущего запроса.

setup_environ()

Установите атрибут environ на полностью заполненную среду WSGI. Реализация по умолчанию использует все вышеперечисленные методы и атрибуты, плюс методы get_stdin(), get_stderr(), add_cgi_vars() и атрибут wsgi_file_wrapper. Она также вставляет ключ SERVER_SOFTWARE, если он отсутствует, при условии, что атрибут origin_server имеет значение true, а атрибут 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 «Optional Platform-Specific File Handling»:

wsgi_file_wrapper

Фабрика wsgi.file_wrapper или None. Значением по умолчанию этого атрибута является класс wsgiref.util.FileWrapper.

sendfile()

Переопределение для реализации передачи файлов в зависимости от платформы. Этот метод вызывается только в том случае, если возвращаемое значение приложения является экземпляром класса, указанного атрибутом wsgi_file_wrapper. Он должен возвращать значение true, если удалось успешно передать файл, так что код передачи по умолчанию не будет выполнен. Реализация этого метода по умолчанию просто возвращает значение false.

Различные методы и атрибуты:

origin_server

Этот атрибут должен быть установлен в значение true, если _write() и _flush() обработчика используются для связи непосредственно с клиентом, а не через CGI-подобный протокол шлюза, который хочет получить статус HTTP в специальном заголовке Status:.

По умолчанию этот атрибут имеет значение true в BaseHandler, но false в 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()
Вернуться на верх