Title: Information Infrastructure II
1Information Infrastructure II
- I211 Week 10
- Rajarshi Guha
2Outline
- Writing simple forms
- Writing mod_python programs to handle forms
- Get and Post
- Handling file uploads
3HTML Forms
- A way to allow user input on a web page
- Lots of different types of elements available
- In general, always check what the user provides
- Most important for text boxes and text fields
4Implementing an HTML Form
- Form elements must be enclosed within
tags - Have to specify a URL which will handle the form
- Should have a submit button so that the user can
indicate processing should start - See http//cheminfo.informatics.indiana.edu/rguha
/class/2007/i211/week9/form.html
5An Example HTML Form
An example
form " name"aForm" method"get" name"textfield"
name"cars" Volvo
Saab value"fiat"Fiat value"audi"Audi
ea name"textbox" rows"10" cols"40"
value'Click Me!'
6A mod_python Handler for Forms
- General idea is same as before
- Write a program that has one or more handler
methods - Take a single request object argument
- Return value is shown in the browser
- One of the handlers is provided as the action URL
of the form
7A Simple Form
A simple form action"http//sulu.informatics.indiana.edu/rguha
/w10/pyform.py" name"form1" methodget" type"text" name"textfield" /
name"textbox" rows20 cols"30" ut type"submit" name"submitbutton" value"Click
Me!" /
8A Simple Form
- Weve specified a URL for the action attribute
- The URL is a Python program and does not specify
a method name - One form
- Two input elements
- Text field
- Text box
- Remember to give each element a unique name.
Makes life easier
9How Do We Get Form Data?
- The request object has a property called form
- An object that represents the HTML form
- The object has a method called getfirst which
takes 2 arguments - Name of the form element we want
- A value to return if the element is not present
10Handling the Form
def index(req) value1 req.form.getfirst("te
xtfield", None) value2 req.form.getfirst("t
extbox", None) s '' s """
The value of the text field was
s
and the value of the text area
was
s
""" (value1, value2)
req.content_type 'text/html' return s
11getfirst
- You dont have to to provide the second argument
- But its useful to know what value you have if
the form element does not exist - NOTE - an empty form element is not the same as
a missing form element - An empty form element has the value
- A missing form element will crash your program
unless you provide a default value in the handler - All form elements are handled using getfirst
- So the code does not have to worry too much about
different types of form elements
12Handling a Drop Down List
A simple form action"http//sulu.informatics.indiana.edu/rguha
/w10/pyform.py/listHandler" name"form2"
method"get" value"volvo"Volvo value"saab"Saab value"fiat"Fiat value"audi"Audi type"submit" name"submitbutton" value"Click
Me!" /
13Handling a Drop Down List
def listHandler(req) selected
req.form.getfirst("optionlist", None) s
"""
You selected s
""" (selected)
req.content_type 'text/html' return s
14Handling Check Boxes and Radio Buttons
A simple form action"http//sulu.informatics.indiana.edu/rguha
/w10/pyform.py/buttonHandler" name"form3"
method"get" Some radio buttons
type"radio" name"sex" value"male"
Male
value"female" Female Some checkboxes
I
have a bike value"Bike" /
I have a car type"checkbox" name"vCar" value"Car"
/
value"Click Me!" /
http//sulu.informatics.indiana.edu/rguha/w10/for
m3.html
15Handling Check Boxes and Radio Buttons
def buttonHandler(req) sex
req.form.getfirst("sex", "male") vehicle1
req.form.getfirst("vBike", None) vehicle2
req.form.getfirst("vCar", None) return sex,
vehicle1, vehicle2
- The code will assume that the default value
of sex is mail
- Checkboxes are slightly different from text
boxes - If they are checked the value is that
specified in the HTML - If not, they have no value
- In this case, it is good practice to specify a
value (like None) so that we know that the box
was not checked
16Handling Elements with the Same Name
- You can check multiple boxes
- Usually, check boxes allow you to choose multiple
variants of something - Mode of transportation
- Favorite films
- We could name all the checkbox elements with same
name, but have different values - How does our program differentiate?
17Elements with the Same Name
A simple form action"http//sulu.informatics.indiana.edu/rguha
/w10/pyform.py/cbHandler" name"form3a"
method"get" Some checkboxes
I have a
bike value"Bike" /
I have a car type"checkbox" name"mode" value"Car"
/
value"Click Me!" /
http//sulu.informatics.indiana.edu/rguha/w10/for
m3a.html
18Elements with the Same Name
- getlist(elemName) returns a list of values for
the form elements whose name is elemName - If there are noelements you get an empty list
def cbHandler(req) checked
req.form.getlist("mode") return checked
19Elements with the Same Name
- For a set of checkboxes, if nothing is checked
you get - If some are checked, you get a list of the values
of the checked boxes
def cbHandler(req) checked
req.form.getlist("mode") return checked
20Get and Post?
- When writing an HTML form we have to specify a
method attribute for the form element - Two possible values get or post
- The two methods differ in the way form data is
passed to the CGI program
21Get
- Go to the form1 page on Sulu
- http//sulu.informatics.indiana.edu/rguha/w10/fo
rm1.html - Put some values into the boxes and then click
submit - Look at the URL of the resultant page
- The URL contains the form element names and their
values - Just like the Yahoo finance URL
22Get
- So get sends form data by encoding it in the URL
to the CGI program - Nice to be able to see exactly whats getting
sent - Very useful for interacting with forms that you
did not write - Problem is that if the data being sent is very
big, the browser can crash or the server might
refuse you - HTTP has limits on URL length
23Post
- Go to the form1a page on Sulu
- http//sulu.informatics.indiana.edu/rguha/w10/fo
rm1a.html - Put some values into the boxes and then click
submit - Look at the URL of the resultant page
- The URL just contains the name of the CGI program
- So where did the data go?
24Post
- post encodes the form data in the body of the
HTML request - Does not allow you to easily see what is being
sent - Good for forms where you might be sending a large
amount of data - No limits on data size
25How Does it Affect the CGI?
- A post form or a get form makes no difference to
the mod_python handler - Try it
- Type stuff into form1
- Type stuff into form1a
- Youll see the same output because the handler
doesnt care whether the data is coming in by get
or post
26Which One Do You Use?
- For small forms with small amounts of data,
doesnt matter - get is good for debugging
- For forms with large amounts of data use post
27Accessing Your CGI without a Page
- We saw that form data gets sent to the CGI as a
URLhttp//some.host/chiprog.py?var1val1var2val
2 - You can write a Python program that will
construct the URL and get the data - Handy for testing your CGI, since you dont have
to click through a web page - Since you design the form, you know what the
argument names are!
28Accessing form1 Without a Web Page
def connectToForm1() url
'http//sulu.informatics.indiana.edu/rguha/w10/py
form.py? url url textboxHellotextfield
World' con urllib.urlopen(url) page
con.readlines() page ''.join(page)
print page if __name__ '__main__'
connectToForm1()
29Handling File Uploads
- In many cases, youll want the user to upload a
file - Your handler must be able to get that file
- Usually youll want to copy the file somewhere
and run some checks on it - File size
- Illegal characters
30HTML for File Upload
- The form must use the post method
- Provide an entry box for the filename using the
element, with type file - You also need to provide another attributeof the
form element enctype multipart/form-data - This tells the browser how to send the file to
the CGI
31HTML for File Upload
A simple form for file
upload ana.edu/rguha/w10/pyform.py/formHandler" name"fo
rm4" method"post" enctype"multipart/form-data"
size"15" name"submitbutton" value"Click Me!"
/
http//sulu.informatics.indiana.edu/rguha/w10/for
m4.html
32Handling File Upload in Python
- We get a Field object from the form object
- The form object behaves like a dictionary
- Get the field object by the name you gave to the
file input element - It has a useful method and a useful property
- filename - allows you to copy the file to a local
directory - read() - reads in all the data in the file as a
list of bytes. - For text data, the result is a single string
- Same as the read method for file objects
33Handling File Upload in Python
- A very simple example
- No validation
- Uploading a big file will crash your browser!
- Get the CGI Field object
- Read the data from it
- Do stuff with thedata
def formHandler(req) dataobj
req.form'datafile' dat dataobj.file.read()
return dat
34Did the File Get Uploaded?
- The previous example assumes that the file got
uploaded - What if you lost the network midway?
- No exceptions are thrown
- You should check the filename property of the
Field object - If it is a non-empty string, the file got
uploaded OK - If not, it wasnt uploaded so handle the error
(display error message etc)
35Did the File Get Uploaded?
- The proper way to check for upload errors
- Usually youd return a nice HTML page with an
error message - You should also include validation
- File size
- Empty files
-
def formHandler(req) dataobj
req.form'datafile' if dataobj.filename
dat dataobj.file.read() return dat
else return File did not upload
36Why Bother With HTML Pages?
- Uptil now, weve been writing an HTML page and
then writing code to accept form data - Two separate files, that need to be maintained
- Why not put everything into the Python program?
37Doing Forms in Python
- Reasons you may not want to
- If its a complex page you might design it in
Dreamweaver, Nu or Frontpage - In many cases, the page is pulled from a database
- The Python program can do the database access
- Get the page as a string
- Return the string
- Very useful when the page will have dynamic
information
38Doing Forms in Python
def index(req) req.content_type
'text/html' s """
" method"get"
name"box"
type"submit" value"Click Me!"
"""
return s
39Doing Forms in Python
def myhandler(req) req.content_type
'text/html' txt req.form.getfirst("box",
None) s """
You
entered
s
""" (txt)
return s
40Summary
- Handling form data just requires the getfirst or
getlist methods of the form object - Should provide the second argument, so that you
can know when something is missing or not
selected - The main work is actually doing stuff with the
data you get from a form