Скрипты CGI на Питоне.

Введение в CGI.

CGI означает Common Gateway Interface и является мощным средством динамической генерации Веб страниц. CGI скрипты вызываются веб-сервером, а результат их работы отправляется на клиентский броузер. Таким образом, CGI скрипты способны выполнять любые запросы клиента на сервере и отправлять клиенту результаты запроса.



Для написания CGI скриптов пригоден любой интерпретируемый или компилируемый язык программирования, в том числе и Питон. Типичная CGI программа состоит из двух частей: из передачи HTTP заголовков и передачи HTML данных. Веб-сервер связывает вывод CGI скрипта со вводом у броузера. Всё, что выводится CGI скриптом передаётся на клиентскую машину. Обратная связь осуществляется передачей данных от сервера клиенту путём передачи параметров.



Вот пример типичной CGI программы:

вначале выводятся заголовки

print "Content-Type: text/html" # Определение типа HTML

print # Пустая строка означает окончание передачи заголовков

теперь выводим основной текст в формате HTML

print "<TITLE>CGI script output</TITLE>"

print "<H1>This is my first CGI script</H1>"

print "Hello, world!"



При этом учтите, что нельзя передавать заголовки после вывода текста или внутри него. Так что заголовки выводятся только вначале текста, иначе они считаются просто текстом! Наверное, Вам интересно знать об основной области применения CGI – для обработки информации из форм.

Итак передача параметров в CGI скрипт осуществляется двумя методами: прямой передачей параметров в имени URL в формате “http://адрес_скрипта?имя_параметра1=значение_параметра1&имя_параметра2=значение2...”

при этом способе в программе становятся доступными переменные имя_параметра и им присваиваются переданные значения; второй способ состоит в передаче параметров через HTML форму. Во втором случае необходимо применение модуля CGI:

import cgi

Затем, чтобы включить обработку ошибок полезно вставить в начало следующие строчки:

import cgitb; cgitb.enable()

Если же Вы не хотите, чтобы ошибки Вашего скрипта передавались в броузер клиента, а передавались в log файл, то сделайте следующее:

import cgitb; cgitb.enable(display=0, logdir="/tmp")

Итак, во-первых разберёмся с формами. В модуле CGI есть полезный класс: FieldStorage, который содержит в себе переданную в форме информацию. По сути дела этот класс представляет из себя словарь, обладающий теми же свойствами, что и обычный питоновский словарь, например методами has_key и key(), также можно определить его длину функцией len(). По умолчанию FieldStorage не содержит тех значений, которые в форме остались пустыми (например пустое поле ввода). Чтобы FieldStorage включал все переменные формы сделайте так:

form = cgi.FieldStorage(keep_blank_values=true)

Покажем пример работы с формой:

#Передали заголовки ранее

form = cgi.FieldStorage() #Здесь пустых значений нет!

if not (form.has_key("name") and form.has_key("addr")): #А есть ли такие поля?

print "<H1>Error</H1>" #Плохая форма

print "Please fill in the name and addr fields."

return

print "<p>name:", form["name"].value

print "<p>addr:", form["addr"].value #Дальше обрабатываем форму

Учтите, если в форме присутствует несколько элементов с одним именем, то form.getvalue() вернёт список значений всех элементов с этим именем. Для того чтобы понять, элемент это или список удобно использовать функцию type. Как обычно, приведу пример:

from types import ListType



value = form.getvalue("username", "")

if isinstance(value, ListType):

# Это список

usernames = ",".join(value)

else:

# Или это просто переменная или полная лажа ;-)

usernames = value

Ну что ещё можно сказать? Хотел бы отметить использование File Upload если в форме есть переменная, представляющая собой файл, то при вызове form.getvalue() этот файл будет загружен из сети в память. Переменная же представляет собой обычный файл и его можно читать, используя методы модуля file:

fileitem = form["userfile"]

if fileitem.file:

# Это и вправду файл!

linecount = 0

while 1:

line = fileitem.file.readline()

if not line: break

linecount = linecount + 1



Далее будут рассмотрены все методы модуля cgi, а пока ограничимся этим :-(