So far pretty much everything we have done up to this point in the book has been what we call flat HTML. We place an HTML document in a file and we can look at that file from our laptop or put the file up on a web server and view the HTML from the Web. When you are working with flat HTML, a server is optional.
Our browser will (1) make the
POST request to our web server, and the web
server will (2) run our Python program, which will produce (3) the HTTP
response with the new HTML for display on the browser, as shown in Figure 4-9.
So now we need to make a simple App Engine program. For instructions on how to set up and start App Engine on your system, see the appendixes.
This application will consist of two files. The first file is app.yaml, which names the application and decides how to route the incoming URLs, as follows:
ae-01-guessversion: 1 runtime: python api_version: 1 handlers: - url: /.* script: index.py
In the handlers section, we keep things really simple and
route all the incoming document URLs (
/.*) to a program file called index.py. The app.yaml file is in a format called Yet Another Markup Language (YAML).
YAML uses a simple syntax to represent keywords and values and
structured data using colons (:) and indenting.
We do the main work in the index.py file. Through the magic of the App
Engine framework, the code in index.py is started when a request comes into
the server and runs from top to bottom for each request. The
POST data is available to us as standard
input, which we access using a built-in feature of Python called
The basic outline of the program is to check any
POST data and parse the
POST data to find the numeric value of the
guess. Then we check to see whether the guess is correct, high, or low,
and print out an appropriate message, and then print out the HTML for
<form>, so the user can
submit a new guess if they like:
import sys print 'Content-Type: text/html' print '' print '<pre>' # Read the form input which is a single line # guess=25 guess = -1 data = sys.stdin.read() # print data try: guess = int(data[data.find('=')+1:]) except: guess = -1 print 'Your guess is', guess answer = 42 if guess < answer : print 'Your guess is too low' if guess == answer: print 'Congratulations!' if guess > answer : print 'Your guess is too high' print '</pre>' print '''<form method="post" action="/"> Enter Guess: <input type="text" name="guess"><br> <input type="submit"> </form>'''
Stepping through the code, here’s a description of what is happening at each step:
In the first line, we do an
sys to make the “sys” library available to us so that we
can read the standard input. The “sys” library is a collection of
functions that come with Python.
We print out a header line indicating the content type and a blank line to signal the start of the actual HTML. You will notice when you view source later that you do not see any the header line(s). This is because the header lines are part of the HTTP response but not part of the HTML document.
Then we use
sys.stdin.read() to pull in the raw
POST data from the incoming
request. If this is a
request, we will not get any data on
Then we use Python string functions to split the
guess=25 string into parts and pull out
the number after the equals sign and convert it from a string to an
integer (see Chapter 3 for details on the string
parsing in this line of code). Because we may have no data or
improperly formatted data, we put the string parsing and conversion
except block. If
anything goes wrong, we set the
guess variable to –1.
Next we use a series of
if statements to
check whether the incoming guess is correct, high, or low, and then
print out an appropriate message.
At the end of the program, we print out the text of the HTML
form using Python multiline string syntax. In Python, if you start a
string with triple quotes (
the string continues until it finds a matching set of triple
quotes—even if the string continues for multiple lines.
This program runs for every request regardless of whether it is a
GET request or a
To run this application, create a folder named ae-01-guess and put the app.yaml and index.py files into the folder as shown previously. Assuming that you have installed App Engine following the instructions in the appropriate appendix, you should be able to start App Engine in the command or terminal window by typing the following command in the folder above the ae-01-guess folder:
apps csev$ dev_appserver.py ae-01-guess/ INFO 2008-12-27 14:30:27,023 appcfg.py] Server: appengine.google.com INFO 2008-12-27 14:30:27,386 dev_appserver_main.py] Running application ae-01-guess on port 8080: http://localhost:8080
Once the application is running, we can navigate to
http://localhost:8080/ by typing the URL into our
browser. When we enter the URL, the browser makes an HTTP
GET request to retrieve the document. As there
POST data, the code in the
try block will fail and
guess will be
-1, so the first screen will look as shown in
If you view the source of this page, you will see the following HTML, which was generated by our Python program:
<pre> Your guess is -1 Your guess is too low </pre> <form method="post" action="/"> <p>Enter Guess: <input type="text" name="guess"/></p> <p><input type="submit"></p> </form>
This HTML is simply the accumulated output of all the
If we enter a guess such as 100 and click Submit, our browser
sends an HTTP
POST to our
application. This time the standard input contains the string
guess=100, so the code in the
try block succeeds in parsing the input guess
GET the output shown in Figure 4-11.
As we continue to make guesses, the browser sends
POST requests to our server program and we
GET responses—until hopefully we
arrive at the correct answer.
Make sure to test your application to confirm that it properly handles numbers that are too high, too low, and just right. Also test to see whether the program does something meaningful when you leave the text input blank and click Submit or enter nonnumeric data in the field and click Submit. It is always a good idea to think through how to test your applications quickly and thoroughly. One general approach is to come up with a series of inputs that make sure that your test sequence touches every line of your program at least once.