справочник по Python. мм isbn 9785932861578 9 785932 861578
Скачать 4.21 Mb.
|
Welcome $name. You have successfully subscribed to our newsletter. Your confirmation code is $confirmation. Модуль cgi 669 Вызов метода temp.substitute() в сценарии просто замещает символы под- становки в этом файле. Очевидное преимущество этого подхода в том, что при необходимости изменить внешний вид страницы достаточно будет из- менить файл шаблона, не изменяя сам CGI-сценарий. Для языка Python существует множество сторонних реализаций механизмов управления шаблонами; возможно, их даже больше, чем веб-фреймворков. Все они в значительной степени основываются на понятии шаблона. Дополни- тельные подробности вы найдете на странице http://wiki.python.org/moin/ Templating Во-вторых, если имеется необходимость хранения данных для CGI-сцена- риев, старайтесь использовать базу данных. Несомненно, запись данных прямо в файлы выполняется достаточно просто, однако не забывайте, что веб-серверы действуют в многозадачной среде, и если не предпринять до- полнительных усилий по синхронизации доступа к ресурсам, велика ве- роятность повредить эти файлы. Серверы баз данных и соответствующие интерфейсы доступа к ним из программ на языке Python обычно лишены этого недостатка. Поэтому если вам понадобится сохранять данные, попро- буйте задействовать модуль, такой как sqlite3, или сторонний модуль до- ступа к базам данных, например к MySQL. Наконец, если вы вдруг обнаружите, что приходится писать десятки CGI- сце нариев, в которых приходится заниматься обработкой низкоуровневых особенностей протокола HTTP, таких как cookie, аутентификация, коди- HTTP, таких как cookie, аутентификация, коди- , таких как cookie, аутентификация, коди- cookie, аутентификация, коди- , аутентификация, коди- ровка символов и так далее, подумайте об использовании веб-фреймворка. Основная цель фреймворка состоит в том, чтобы избавить вас от необходи- мости задумываться о таких деталях или, по крайней мере, от необходимо- сти глубоко в них погружаться. Не старайтесь повторно изобрести колесо. Примечания • Процедура установки CGI-программы может существенно отличаться, в зависимости от типа используемого веб-сервера. Обычно CGI-про грам- мы помещаются в специальный каталог cgi-bin. Кроме того, может по- требоваться выполнить дополнительные настройки сервера. За допол- нительной информацией вам следует обратиться к документации с опи- санием сервера или к администратору сервера. • В системе UNIX может потребоваться присвоить CGI-программам на язы- UNIX может потребоваться присвоить CGI-программам на язы- может потребоваться присвоить CGI-программам на язы- CGI-программам на язы- -программам на язы- ке Python соответствующие разрешения на выполнение, а сама програм- Python соответствующие разрешения на выполнение, а сама програм- соответствующие разрешения на выполнение, а сама програм- ма должна будет начинаться со строки, аналогичной показанной ниже: #!/usr/bin/env python import cgi ... Чтобы упростить отладку, импортируйте модуль cgitb. Например, до- бавьте инструкции import cgitb; cgitb.enable(). Это изменит обработку исключений так, что все сообщения об ошибках будут отображаться в веб-броузере. • Если CGI-сценарий вызывает внешнюю программу, например с помо- CGI-сценарий вызывает внешнюю программу, например с помо- -сценарий вызывает внешнюю программу, например с помо- щью функции os.system() или os.popen(), будьте особенно вниматель- 670 Глава 23. Веб-программирование ны и не передавайте командной оболочке непроверенные строки, по- лученные от пользователя. Это хорошо известная прореха в системе безопасности, которая может использоваться злоумышленниками для выполнения на сервере произвольных системных команд (потому что команды, передаваемые этим функциям, интерпретируются команд- ной оболочкой UNIX). В частности, никогда не передавайте командной оболочке какие-либо части строки URL или данные из формы, пред- URL или данные из формы, пред- или данные из формы, пред- варительно не проверив их и не убедившись, что строки содержат толь- ко алфавитно-цифровые символы, дефисы, символы подчеркивания и точки. • В системе UNIX никогда не устанавливайте бит setuid для файлов CGI- программ. Это может привести к проблемам с безопасностью, а кроме того, такая возможность поддерживается не во всех системах. • Не импортируйте этот модуль инструкцией ‘from cgi import *’. Модуль cgi объявляет огромное количество символов, которыми не стоит заби- вать пространство имен программы. Модуль cgitb Этот модуль предоставляет альтернативную реализацию механизма об- работки исключений, которая отображает подробные отчеты обо всех не- обработанных исключениях. В отчет включается исходный программный код, значения параметров и локальных переменных. Первоначально этот модуль создавался с целью помочь в отладке CGI-сценариев, но он точно так же может использоваться любыми другими приложениями. enable([display [, logdir [, context [, format]]]]) Разрешает специализированную обработку исключений. В аргументе dis- play передается флаг, разрешающий вывод информации в случае появле- ния ошибки. По умолчанию принимает значение 1. Аргумент logdir опре- деляет каталог, куда должны сохраняться файлы с отчетами, вместо выво- да в поток стандартного вывода. Если аргумент logdir определен, каждый отчет будет сохранен в отдельном файле, созданном с помощью функции tempfile.mkstemp() . В аргументе context передается целое число, определя- ющее количество строк с исходным программным кодом, окружающим строку, где возникло исключение. Аргумент format определяет выходной формат отчетов. Значение ‘html’ (по умолчанию) в аргументе format соответ- ствует формату HTML. Если указать любое другое значение, отчеты будут выводиться в простом текстовом формате. handle([info]) Обрабатывает исключение, используя настройки по умолчанию функции enable() . В аргументе info передается кортеж (exctype, excvalue, tb), где поле exctype представляет тип исключения, excvalue – значение исключе- ния, а поле tb – объект с трассировочной информацией. Этот кортеж обыч- но можно получить вызовом функции sys.exc_info(). Если аргумент info опущен, используется информация о текущем исключении. Поддержка WSGI 671 Примечание Чтобы включить специальный режим обработки исключений в CGI-сценариях, до- CGI-сценариях, до- -сценариях, до- бавьте в начало сценария строку import cgitb; enable(). Поддержка WSGI W SGI (Web Server Gateway Interface – шлюзовой интерфейс веб-серве- ра) – это стандартизованный интерфейс между веб-серверами и веб-прило- жениями, который был разработан для обеспечения независимости при- ложений от типов веб-серверов и фреймворков. Официальное описание стандарта можно найти в документе PEP 333 (http://www.python.org/dev/ peps/pep-0333 ). Дополнительные сведения о стандарте и его использовании можно также найти на сайте http://www.wsgi.org. Пакет wsgiref содержит реализацию вспомогательных функций, которые могут использоваться для тестирования, проверки и упрощения развертывания. Спецификация стандарта WSGI Согласно WSGI, веб-приложение реализуется как функция, или вызывае- WSGI, веб-приложение реализуется как функция, или вызывае- , веб-приложение реализуется как функция, или вызывае- мый объект, webapp(environ, start_response), которая принимает два аргу- мента, где аргумент environ – это словарь с параметрами окружения, кото- рый должен, как минимум, содержать следующие значения, имеющие те же имена и то же назначение, что и в CGI-сценариях: Переменная Описание CONTENT_LENGTH Длина переданных данных CONTENT_TYPE Тип данных запроса HTTP_ACCEPT Типы MIME, принимаемые клиентом HTTP_COOKIE Хранилище значения cookie HTTP_REFERER Ссылающийся адрес URL HTTP_USER_AGENT Информация о броузере клиента PATH_INFO Дополнительная информация о пути QUERY_STRING Строка запроса REQUEST_METHOD Метод (‘GET’ или ‘POST’) SCRIPT_NAME Имя программы SERVER_NAME Имя хоста сервера SERVER_PORT Номер порта сервера SERVER_PROTOCOL Протокол сервера Кроме того, словарь environ должен содержать следующие значения, харак- терные для WSGI: 672 Глава 23. Веб-программирование Переменная Описание wsgi.version Кортеж, представляющий версию WSGI (например, (1,0) для WSGI 1.0). wsgi.url_scheme Строка, содержащая компонент адреса URL с названием про- URL с названием про- с названием про- токола. Например, ‘http’ или ‘https’. wsgi.input Объект, похожий на файл, представляющий поток стандарт- ного ввода. Из этого потока будут читаться дополнительные данные, такие как данные формы или выгружаемый файл. wsgi.errors Объект, похожий на файл, открытый в текстовом режиме и используемый для вывода сообщений об ошибках. wsgi.multithread Логический флаг, значение True в котором разрешает запу- стить приложение в отдельном потоке управления в рамках одного и того же процесса. wsgi.multiprocess Логический флаг, значение True в котором разрешает запу- стить приложение в дочернем процессе процессов. wsgi.run_once Логический флаг; значение True в котором говорит о том, что приложение может запускаться лишь один раз в течение всего времени выполнения процесса. В аргументе start_response передается вызываемый объект вида start_ response( status, headers) , который используется приложением для запуска ответа. В аргументе status этот объект принимает строку с кодом ответа, такую как ‘200 OK’ или ‘404 Not Found’, а в аргументе headers – список корте- жей вида (name, value), соответствующих HTTP-заголовкам, включаемым в ответ, например (‘Content-type’,’text/html’). Данные, или тело ответа, возвращаются функцией веб-приложения в виде итерируемого объекта, воспроизводящего последовательность текстовых строк или строк байтов, содержащих только символы, которые могут быть представлены единственным байтом (например, совместимые с набором символов ISO-8859-1 или Latin-1). Это может быть список строк байтов или функция-генератор, воспроизводящая строки байтов. Если приложению необходимо выполнить кодирование символов, например, в кодировку UTF-8, оно должно делать это самостоятельно. Ниже приводится пример простого приложения WSGI, которое читает зна- WSGI, которое читает зна- , которое читает зна- чения полей формы и производит вывод, подобный тому, что был показан в разделе с описанием модуля cgi: import cgi def subscribe_app(environ, start_response): fields = cgi.FieldStorage(environ[‘wsgi.input’], environ=environ) ёёё name = fields.getvalue(“name”) email = fields.getvalue(“email”) ёёё # Обработка формы ёёё Пакет wsgiref 673 status = “200 OK” headers = [(‘Content-type’,’text/plain’)] start_response(status, headers) ёёё response = [ ‘Hi %s. Thank you for subscribing.’ % name, ‘You should expect a response soon.’ ] return (line.encode(‘utf-8’) for line in response) В этом примере имеется несколько важных моментов. Во-первых, ком- поненты WSGI-приложения не привязаны к какому-либо определенному фреймворку, веб-серверу или набору библиотечных модулей. Здесь ис- пользовался только один библиотечный модуль – cgi, и то лишь потому, что он содержит ряд удобных функций, позволяющих анализировать со- держимое строки запроса. Пример демонстрирует, как использовать функ- цию start_response(), чтобы инициировать ответ и применить заголовки. Сам ответ конструируется как список строк. Последняя инструкция в этом приложении создает выражение-генератор, преобразующее все строки в строки байтов. В Python 3 это очень важный шаг – все WSGI-приложения должны возвращать кодированные строки байтов, а не строки Юникода. Чтобы ввести WSGI-приложение в эксплуатацию, его необходимо зареги- WSGI-приложение в эксплуатацию, его необходимо зареги- -приложение в эксплуатацию, его необходимо зареги- стрировать средствами используемого фреймворка. А для этого следует ознакомиться с соответствующим руководством. Пакет wsgiref Пакет wsgiref содержит реализацию стандарта WSGI, позволяющую тести- WSGI, позволяющую тести- , позволяющую тести- ровать приложения на автономных серверах или выполнять их, как обыч- ные CGI-сценарии. Модуль wsgiref.simple_server Модуль wsgiref.simple_server реализует простой автономный HTTP-сервер, выполняющий единственное WSGI-приложение. В этом модуле существу- WSGI-приложение. В этом модуле существу- -приложение. В этом модуле существу- ют всего две функции, представляющие для нас интерес: make_server(host, port, app) Создает HTTP-сервер, принимающий соединения по указанному адресу. Аргумент host определяет имя хоста, а аргумент port – номер порта. В ар- гументе app передается функция, или вызываемый объект, реализующая WSGI-приложение. Чтобы запустить сервер, необходимо вызвать метод s.serve_forever() , где s – это экземпляр сервера, возвращаемого функцией make_server() demo_app(environ, start_response) Полноценное WSGI-приложение, возвращающее страницу с сообщением «Hello World». Может использоваться в качестве аргумента app функции make_server() для проверки работоспособности сервера. 674 Глава 23. Веб-программирование Н иже приводится пример запуска простого WSGI-сервера: def my_app(environ, start_response): # Некоторое приложение start_response(“200 OK”, [(‘Content-type’,’text/plain’)]) return [‘Hello World’] ёёё if __name__ == ‘__main__’: from wsgiref.simple_server import make_server serv = make_server(‘’,8080, my_app) serv.serve_forever() Модуль wsgiref.handlers Модуль wsgiref.handlers содержит определения классов обработчиков, предназначенных для настройки среды выполнения WSGI, чтобы прило- WSGI, чтобы прило- , чтобы прило- жения могли выполняться под управлением другого веб-сервера (напри- мер, в виде CGI-сценария под управлением веб-сервера Apache). В модуле определено несколько разных классов. CGIHandler() Создает объект-обработчик WSGI, способный выполняться в стандартном окружении CGI. Этот обработчик извлекает информацию из стандартных переменных окружения и потоков ввода-вывода, о которых рассказыва- лось в описании модуля cgi. BaseCGIHandler(stdin, stdout, stderr, environ [, multithread [, multiprocess]]) Создает объект-обработчик WSGI, способный выполняться в окружении CGI, но позволяет переопределять стандартные потоки ввода-вывода и пе- , но позволяет переопределять стандартные потоки ввода-вывода и пе- ременные окружения. В аргументах stdin, stdout и stderr передаются объ- екты, похожие на файлы, которые будут использоваться как стандартные потоки ввода-вывода. В аргументе environ передается словарь с переменны- ми окружения, который должен содержать стандартные переменные окру- жения CGI. В аргументах multithread и multiprocess передаются логические флаги, значения которых будут использоваться для установки значений переменных окружения wsgi.multithread и wsgi.multiprocess. По умолчанию аргумент multithread принимает значение True, а аргумент multiprocess – значение False. SimpleHandler(stdin, stdout, stderr, environ [, multithread [, multiprocess]]) Создает объект-обработчик WSGI, похожий на объект класса BaseCGIHan- dler , но в отличие от последнего обеспечивающий приложению прямой до- ступ к аргументам stdin, stdout, stderr и environ. Объекты этого типа немно- го отличаются от объектов класса BaseCGIHandler, который предоставляет дополнительную логику, обеспечивающую корректную работу некоторых особенностей (например, объекты класса BaseCGIHandler преобразуют коды ответов в заголовки Status:). Все эти обработчики обладают методом run(app), который используется для запуска WSGI-приложения в окружении обработчика. Ниже приво- WSGI-приложения в окружении обработчика. Ниже приво- -приложения в окружении обработчика. Ниже приво- дится пример WSGI-приложения, которое запускается как обычный CGI- сценарий: Пакет wsgiref 675 #!/usr/bin/env python def my_app(environ, start_response): # Некоторое приложение start_response(“200 OK”,[(‘Content-type’,’text/plain’)]) return [‘Hello World’] ёёё from wgiref.handlers import CGIHandler hand = CGIHandler() hand.run(my_app) Модуль wsgiref.validate М одуль wsgiref.validate содержит функции, позволяющие обертывать WSGI-приложения и проверять соответствие стандарту самого приложе- ния и сервера, под управлением которого оно выполняется. validator(app) Создает новое WSGI-приложение, обертывающее WSGI-приложение app. Новое приложение действует точно так же, как и оригинальное приложе- ние app, за исключением того, что к нему добавляются многочисленные проверки на наличие ошибок, позволяющие гарантировать, что само при- ложение и сервер соответствуют требованиям стандарта WSGI. Любое не- WSGI. Любое не- . Любое не- соответствие вызывает появление исключения AssertionError. Ниже приводится пример использования функции validator(): def my_app(environ, start_response): # Некоторое приложение start_response(“200 OK”,[(‘Content-type’,’text/plain’)]) return [‘Hello World’] ёёё if __name__ == ‘__main__’: from wsgiref.simple_server import make_server from wsgiref.validate import validator serv = make_server(‘’,8080, validator(my_app)) serv.serve_forever() Примечание Сведения в этом разделе в первую очередь предназначены пользователям, кото- рым требуется создавать объекты WSGI-приложений. Если же вы собираетесь реа- WSGI-приложений. Если же вы собираетесь реа- -приложений. Если же вы собираетесь реа- лизовать свой фреймворк на языке Python, вам следует обратиться к документу PEP 333, где приводится официальная информация о том, какие функции должны быть реализованы во фреймворке, поддерживающем стандарт WSGI. В случае ис- WSGI. В случае ис- . В случае ис- пользования готовых фреймворков сторонних разработчиков обращайтесь к до- кументации с описанием фреймворка за конкретной информацией о поддержке фреймворком объектов WSGI. Учитывая, что в стандартной библиотеке реализо- вана отличная поддержка официальной спецификации WSGI, для фреймворков становится все более типичным обеспечивать определенный уровень поддержки этого стандарта. 676 Глава 23. Веб-программирование Модуль webbrowser М одуль webbrowser содержит вспомогательные функции, позволяющие открывать документы в веб-броузере платформонезависимым способом. В основном этот модуль используется в процессе разработки и тестирова- ния. Например, при написании сценария, который воспроизводит размет- ку HTML, с помощью функций из этого модуля можно было бы автомати- HTML, с помощью функций из этого модуля можно было бы автомати- , с помощью функций из этого модуля можно было бы автомати- чески вызывать броузер, используемый в системе по умолчанию, для про- смотра результатов. open(url [, new [, autoraise]]) Отображает страницу с адресом url в броузере по умолчанию. Если в ар- гументе new передать значение 0, страница будет открыта в открытом окне броузера, если это возможно. Если в аргументе new передать значение 1, бу- дет открыто новое окно броузера. Если в аргументе new передать значение 2 , страница будет открыта в новой вкладке броузера. Если в аргументе au- toraise передать значение True, окно броузера будет выведено на передний план. open_new(url) Отображает страницу с адресом url в новом окне броузера по умолчанию. Идентична вызову open(url, 1). open_new_tab(url) Отображает страницу с адресом url в новой вкладке броузера по умолча- нию. Идентична вызову open(url, 2). get([name]) Возвращает объект управления броузером. В аргументе name передается имя броузера, которое представлено строкой, такой как ‘netscape’, ‘mozil- mozil- la’ , ‘kfm’, ‘grail’, ‘windows-default’, ‘internet-config’ или ‘command-line’. Воз- вращаемый объект обладает методами open() и open_new(), которые прини- мают те же аргументы и выполняют те же действия, что и две предыдущие функции. При вызове без аргумента name возвращает объект управления броузером по умолчанию. register(name, constructor [, controller]) Регистрирует новый тип броузера для использования в вызове функции get() . В аргументе name передается имя броузера. В аргументе constructor передается функция, которая вызывается без аргументов, – для создания объекта управления броузером. В аргументе controller передается готовый объект управления. Если этот аргумент определен, аргумент constructor иг- норируется и может иметь значение None. Экземпляр объекта управления c, который возвращается функцией get(), обладает следующими методами: c.open(url [, new]) То же, что и функция open(). c.open_new(url) То же, что и функция open_new(). |