Google's App Engine offers an attractive idea for web developers of being able to use Google's famous server infrastructure to serve up their own code and interactive websites. If you develop for it though you might find it is a bit different from developing for other types of web host and some of the concepts are new. I've been asked if I would do a simple run through of how you would set up an application and handle an HTTP GET requests with parameters, so here is a tutorial that will not just say “hello world” but greet you by name. The example is deliberately simple, but the concepts in it can be built on for many other uses. This example uses Python, if you would like to see a Java version then please mention it in the comments.
Firstly, grab a copy of the development web server from http://code.google.com/appengine/downloads.html for your operating system. Follow the instructions there to make sure it is installed correctly. The development web server allows you to develop code locally on your machine and experiment before uploading finished code to the Google App Engine itself. Despite the fact we have downloaded a web server and are running on a single machine it is important to remember that Google App Engine does not work in the same way as a traditional web server. Parts of your program could be run on different machines all over the world. A theme of developing for Google App Engine is that you will be describing how resources link to each other and the actual physical way this is implemented is hidden from you and handled by the underlying infrastructure. Keep this in mind especially when you are dealing with static resources such as image files or stylesheets.
We can now get started on our code by broadly following the tutorial at http://code.google.com/appengine/docs/python/gettingstarted/helloworld.html, except we don't want to greet the world we want to greet a specific person! So create a folder named “helloyou”, which will hold all of the files for our web application, and then create a file named helloyou.py inside it with the following code:
print 'Content-Type: text/plain'
print ''
print 'Hello, world!'
We will be modifying this code later on to be a bit more sophisticated. Now create a file named app.yaml and past in the following:
application: helloyou
version: 1
runtime: python
api_version: 1
handlers:
- url: /.*
script: helloyou.py
This file is really important as it tells Google App Engine which bit of your code to use for an incoming URL. In the “handlers” section the “url” entry is set to match any incoming URL and send it to our “helloyou.py” script to be dealt with. So far we have not put in any code to differentiate between URLs in our helloyou.py file, so any URL you pass to this application will have the same result. To see this in action start up the development webserver (you may need to modify this command to match your installation details):
./google_appengine/dev_appserver.py helloyou/
Try going to http://localhost:8080/ and you will see the message “Hello, world!”, now try going to http://localhost:8080/somethingelse and you will also see “Hello, world!”. The app.yaml file tells Google App Engine which script file should be used to handle a URL pattern, but you do not have to start a new script file to handle every different URL. Instead we can modify helloyou.py to make it handle different URLs. As we modify our code there is no need to restart the web server, it will pick up the changes automatically when we refresh the browser. To get the most out of AppEngine we need to use the webapp framework it supplies and do a bit of object orientated programming. If you are not familiar with object orientated programming check out chapter 9 of the Python tutorial. In our new code we need to do three things: make our code use the webapp framework, map the incoming url to a Class (object) that will handle it and write a Class that will output the message. I've also added to the code the facility to pass in a first name and surname and display a personalised greeting. The complete code for the new helloyou.py is shown below:
from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app
class HelloWorld(webapp.RequestHandler):
def get(self):
self.response.headers['Content-Type'] = 'text/plain'
self.response.out.write('Hello, webapp World!')
class HelloYou(webapp.RequestHandler):
def get(self):
self.response.headers['Content-Type'] = 'text/plain'
firstname = self.request.get("firstname")
surname = self.request.get("surname")
self.response.out.write('Hello %s %s' % (firstname, surname))
application = webapp.WSGIApplication(
[('/', HelloWorld), ('/helloyou', HelloYou)],
debug=True)
def main():
run_wsgi_app(application)
if __name__ == "__main__":
main()
This is a slightly more complex example than that shown on the Using the webapp Framework page in the documentation for AppEngine, but it is still worth reading that page. App Engine understands the Web Server Gateway Interface which is designed to provide a way for Python applications to be able to converse with a web server. In the main() function we are saying that our application uses this interface and in the “application=” line you can see a constructor that also maps a URL (without the http and server name bits) to a Python Class that handles it. In the example above “/” is handled by the HelloWorld class and “/helloyou” is handled by the HelloYou class. You can add extra entries to this list to handle other URLs.
The Classes inherit from webapp.RequestHandler, this just means that the AppEngine knows how to interact with your code as long as you write certain functions. If you have written forms in HTML you will be familiar with GET and POST. In the code for each of the classes you will notice a get() function, it is in here that you should put the code for what you want the page to display. The name of this function corresponds with the name of the HTTP request method that we are trying to handle, so for example if you were trying to handle a form submission where you used POST instead of GET to send the data you should write a post() function. In the HelloWorld class you can see a get() function that simply sets the content type (so the browser knows how to treat what you are going to send it) and then sends some text using the self.response.out.write() function.
Information heading out to the browser is contained in the self.response object that we inherited. Information coming in from the browser is contained in the self.request object. In the HelloYou Class we find out from this object what values for named parameters we passed by using the self.request.get() function, here this is used to get the firstname and surname and display a personalised greeting, for example I can enter the URL http://localhost:8080/helloyou?firstname=Liam&surname=Green-Hughes to get my personalised message. You can also find out the headers of the request passed as well, for example you can find out the User Agent for the browser with: self.request.headers['User-Agent'].
As you can see developing for Google App Engine is at first a bit more complicated than using something like PHP on a traditional web server. However, this structure is in place so that your application can than run in a way that can be scaled across multiple web servers and could well maintain performance even under peak demands. Running your own code on Google's infrastructure is a big attraction of writing code for App Engine, but if you want to use your own infrastructure or another cloud computing provider have a look at the AppScale project from UC Santa Barbara RACELab.