Parsing the Request - GetΒΆ
Run the environment.py
script again and this time call it like this:
http://localhost:8051/?age=10&hobbies=software&hobbies=tunning
Check the QUERY_STRING
and the REQUEST_METHOD
variables in the environ
dictionary:
QUERY_STRING: age=10&hobbies=software&hobbies=tunning
REQUEST_METHOD: GET
When the request method is GET
the form variables will be sent in the URL in the part called query string, that is, everything after the ?
Notice the hobbies
variable appears two times. It can happen when there are checkboxes in the form or when the user type the same variable more than once in the URL.
It is possible to write code to parse the query string and retrieve those values but it is easier to use the cgi.parse_qs()
function which returns a dictionary with the values as lists.
Always beware of the user input. Sanitise it to avoid script injection. The cgi.escape()
function can be used for that.
The HTML’s form
tag in this script
instructs the browser to do a GET
request (method="get"
):
#!/usr/bin/env python
from wsgiref.simple_server import make_server
from cgi import parse_qs, escape
html = """
<html>
<body>
<form method="get" action="">
<p>
Age: <input type="text" name="age" value="%(age)s">
</p>
<p>
Hobbies:
<input
name="hobbies" type="checkbox" value="software"
%(checked-software)s
> Software
<input
name="hobbies" type="checkbox" value="tunning"
%(checked-tunning)s
> Auto Tunning
</p>
<p>
<input type="submit" value="Submit">
</p>
</form>
<p>
Age: %(age)s<br>
Hobbies: %(hobbies)s
</p>
</body>
</html>
"""
def application (environ, start_response):
# Returns a dictionary in which the values are lists
d = parse_qs(environ['QUERY_STRING'])
# As there can be more than one value for a variable then
# a list is provided as a default value.
age = d.get('age', [''])[0] # Returns the first age value
hobbies = d.get('hobbies', []) # Returns a list of hobbies
# Always escape user input to avoid script injection
age = escape(age)
hobbies = [escape(hobby) for hobby in hobbies]
response_body = html % { # Fill the above html template in
'checked-software': ('', 'checked')['software' in hobbies],
'checked-tunning': ('', 'checked')['tunning' in hobbies],
'age': age or 'Empty',
'hobbies': ', '.join(hobbies or ['No Hobbies?'])
}
status = '200 OK'
# Now content type is text/html
response_headers = [
('Content-Type', 'text/html'),
('Content-Length', str(len(response_body)))
]
start_response(status, response_headers)
return [response_body]
httpd = make_server('localhost', 8051, application)
# Now it is serve_forever() in instead of handle_request()
httpd.serve_forever()
Listening at http://localhost:8051
As the server above will run forever (serve_forever
) it is necessary to interrupt it possibly with a Ctrl-C