Web Applications: Say Hello!
cs 110 notes

Want to learn how to build a web application? This article provides the "hello world" of web programming. You'll learn how to use Python and Google's App Engine to create a dynamic page that says "hello" to the user.

Dynamic Web Pages

Servers handle requests (events): the user entering a URL, clicking on a link, or submitting a form. The user's action causes a request to be sent to a server.

Some requests are simple and the server just returns a static web page in HTML format.

Many requests, however, are for dynamic web pages such as that of a news site or social network. For these pages, the server invokes controller code which processes the request.

The controller accesses information from a database, performs computations, and ultimately generates a new HTML page sent to a browser.

HTML Templates
An HTML template is like a form letter in which the name and address can be automatically replaced so that the letter is sent out to many people.

HTML templates consist of HTML code and template variables, which are the parts of the page that are replaced with "live" data such as a news item.

In this lesson, we'll be using Google's App Engine and controller code written in the Python language. The HTML templates we'll use define anything within double-curly-brackets as a template variable, e.g.,

<html>
<body>
   Dear {{recipient}},
   <p>You are a nice man</p>
</body>
</html>

HTML Forms
For command-line programs written in Python, we use the 'input' and 'raw-input' functions to get input data from the user. With web applications, our user interface is HTML and we get input from the user with an HTML component called a form.

    <form action="/say_hello" method="get">
      first:<input type="text" name="first"><br/>
      last:<input type="text" name="last"><br/> 
      <input type="submit" value="Say Hello">
   </form>


If this HTML were rendered in a browser, you'd see:

The form consists of a set of input components. In the example, there are two text components, one named 'first', the other named 'last', and a submit button.

Web applications are based on the client-server model. The web page runs on the client (the browser). When the user clicks on a submit button, a request is made to the server using the data defined within the form.

Let's pretend our example came from the server http://sample.com
, and say the user entered 'Joe' and 'Smith' in the text boxes and then clicked 'Say Hello'. Then the following URL would be invoked:

    http://sample.com/say_hello?first=Joe&last=Smith

Here 'say_hello' is the action defined in the form, and first and last are the names of the text boxes within the form.

The URL is something like a function call in Python, where the function is say_hello, the formal parameters are first and last, and the actual parameters are 'Joe' and 'Smith'.

Here, the browser sends a request to the server, sample.com. The server processes the request and sends back a new page, with result information, to the browser.

Responding to Forms: The Controller
We call the web server code that handles requests the controller. We'll be working with controllers written in the Python language. With a Google App Engine server, your controller code maps a request action to a controller class method. The mapping table is defined near the bottom of the controller file:

            application = webapp.WSGIApplication(
                       [
                                   ('/', MainPage),
                                      ('/say_hello', SayHelloHandler)  # map request to a class
                        ],
                        debug=True)

For this example, the /say_hello action is mapped to the class SayHelloHandler. Most server code will define a number of actions that it can "handle". For instance, the sample above also maps the main page of the site, denoted with '/' to a class called MainPage. 

The definitions for each handler class are found elsewhere in the controller file. For example, the sayHelloHandler would look something like the following:

class SayHelloHandler(webapp.RequestHandler):
  def get(self):
      first=self.request.get('first')
      last=self.request.get('last')
      # do some computations, access database
      # set up template values
      # render a  page for the browser
    
In this incomplete handler, the parameters 'first' and 'last' of the request are accessed through the self.request.get method.  Note also that the handler code is in a get function to match the 'method=get' specified in the HTML form.

Generally, the server code will use the input parameters to access/modify a database, perform some computations, and ultimately render a new web page containing the results of the computations. For instance, the server code might access the personal profile matching the first and last name given in the parameters, then send this profile information as part of the rendered page.

For our example, we'll just build a string which says hello to the user:

class SayHelloHandler(webapp.RequestHandler):
    def get(self):
        first=self.request.get('first')
        last=self.request.get('last')
        # set up template value
        messageString = 'hello ' + first
        template_values={'message':  messageString}
        path = os.path.join(os.path.dirname(__file__),'response.html')
        self.response.out.write(template.render(path,template_values))


This code creates a variable messageString that concatenates 'hello' with the first name, e.g., 'hello Joe'. To get this string back to the client, we stick  it into a variable called 'template_values'. template_values is a hash array that holds a list of key-value pairs. In this case there is one key, 'message' which is mapped to the value of the variable 'messageString'.

The second to last line in the controller code specifies that the file response.html should be rendered. response.html is called an 'HTML template', which is something like a form letter where the name and address can be automatically replaced so that the letter is sent out to many people. In this case, the replaceable part of response.html is the message, and it is specified with a template variable defined within double-curly brackets:

<html>
<body>
<p> {{ message }} </p>
</body>
</html>

When the template is rendered, the {{message}} is replaced with the value that the controller defined in template_values, e.g., 'hello Joe'.

Other input types

The above example is for text input, but HTML provides a number of other input widgets including radio buttons, checkboxes, and drop down listboxes. Check out this tutorial from http://www.w3schools.com/html/html_forms.asp for details.

Your Turn

Part I: Implement the say_hello web application described in this page.

1. Save the attachments at the bottom of this page (https://sites.google.com/site/usfcomputerscience/html-forms) into a folder 'say_hello'. First create a sub-folder in your home directory named 'say_hello'. Then right-click on each attached file and choose 'Save Link As'. Be sure and name them exactly as they are named in the attachment, and save them in your 'say_hello' subfolder.

2. Start Google's App Engine Launcher.  Open a command-line terminal and enter "appengine_launcher". This program allows you to test and deploy web apps on Google's servers.

3. Open the project you just downloaded. In the Launcher window, choose File | Add Existing Application. Then browse to your 'say_hello' folder and choose it.

4. Run the app on the (local) test server. Choose your app on the list that appears in the launcher and click the green "Run' button. This starts a test web server on your machine. You can access your app by typing the following in a browers:

    http://localhost:8080

When the page loads you'll see a form requesting your first an last name. Enter them and click "Submit". The program should respond by saying hello.

5. Deploy to the web. If you've made it this far, your web app works, but its really not on the web yet-- your browser is just accessing a 'test' server on your local machine. Now we'll upload your application to the web, and specifically Google's App Engine servers:
  • The first step is to register or sign-in with Google's App Engine service.  Go to http://appengine.google.com/start  If you are registering, you'll have to step through the registration process, including giving Google your cell phone #.
  • Once you are signed in, click 'Create Application' and set the application identifier to something like 'DavesSayHello', but with your name instead of 'Dave'. The name can be anything, but it has to be unique in the Google system.
  • You need to put the name of your application, which you just set at Google, into the configuration file of your application, app.yaml (the one you downloaded from the attachments on this page). So open a text editor, then go to your 'say_hello' folder and open the file 'app.yaml'. The first line of text in that file is the application name, and says 'application: yourappname'. Change 'yourappname' to the application identifier you just registered and save the file.
  • You're now ready to upload your program to Google. In the App Engine Launcher, click "Deploy".

6. To run your application, go to a browser and enter the name of your application, followed by 'appspot.com'.  For instance, if your application identifier was 'DavesSayHello', then enter 'DavesSayHello.appspot.com' in your browser.

If all is well, you should see a web page that looks the same as when you ran your program with the development server. Only this time, your application is really running on the web!

PART II. Modifying the code.

1. First, let's make it so that the hello message appears directly on the home page (index.html) instead of in a separate file. 
  • Open index.html in a text editor and add the text: {{message}} below the form (but above the \body tag)
  • Open the say_hello_controller.py file and find where it refers to 'response.html'. Change 'response.html' to 'index.html'. This will cause the message to appear directly on the home page. 
  • Test the app on the local server by entering "localhost:8080" in the browser, entering a name, then clicking "Submit".
2. Modify the app so that the hello message refers to the full name (first and last) and also reports the length of the person's first name, e.g.,

    Hello Jimmer Fredette, your first name has 6 letters in it

  • In say_hello_controller.py, build the variable 'messageString' so it has all the information you need.
  • You'll need to use string concatenation (+) and the str function.
3. Its better to put static information in the HTML file and only dynamic data in the controller. Modify the controller so that, in the template values, it sends back the name and lengthe of the first name  as two separate template values (name and nameLength). You can put more than one thing in the template_values by separating with commas, e.g.,

    template_values = {'name':name, 'nameLength':nameLength}

You'll also need to modify index.html so that it has the "Hello" and the "your first name has" and the "letters in it" directly, and so that it has two template valus:

{{name}} and {{nameLength}}.

4. Create a new folder named 'diceGame' and copy all of the files from 'say_hello' into it. Then modify the files to create an app that lets the user click on a button to roll a dice. The app should report the roll, and each time the button is clicked a random number between 1 and 6 should appear.




Č
ċ
ď
app.yaml
(0k)
David Wolber,
Sep 16, 2009 11:56 AM
ċ
ď
index.html
(0k)
David Wolber,
Sep 16, 2009 11:56 AM
ċ
ď
response.html
(0k)
David Wolber,
Sep 16, 2009 11:56 AM
ċ
ď
say_hello_controller.py
(1k)
David Wolber,
Sep 16, 2009 11:56 AM

Recent site activity