Enough justification. Now, to develop an application, you will need an SDK for the runtime environment that you are targeting, which happens to be Python in our case. To obtain the Python SDK, visit https://developers.google.com/appengine/downloads. From the download page, select and download the SDK version for your platform. Now let's examine installation process for each platform in detail.
Now that we have a good overview of how App Engine scales, available runtimes, and the services that are at our disposal, it's time to do something real and write our first app.
We will write a simple app that will print all the environment variables. Before you write any code, you'll need to create the app on Google App Engine. If you don't do this, you can still test and run the applications locally, but to deploy, you have to create an app on Google App Engine. To do this, navigate to http://appengine.google.com. Here, you'll be asked to log in using your Gmail credentials. Once you've logged in, you will have to click on Create a Project… from the drop down menu as shown below:
Once you click this, you'll be presented with this dialog:
In its most basic form, the pop-up would only contain the name of the project, but we have expanded all the options to demonstrate. The first thing is the Project name and this can be anything you like it to be. The second thing is the Project ID. This is the ID that you will use in your app.yaml
file. This ID must be unique across all the App Engine applications and it is automatically generated for you, but you can specify your own as well. If you specify your own, you will be warned if it is not unique and you won't be able to proceed.
The next advanced option is about the location that your app would be served from. By default, all the applications would be hosted from the data centers located in USA, but you can select the European ones. You should select the European data center if most of the user base is close to or is in Europe. For example, if we're building an app for which we expect most of the traffic from Asia, Middle-east, or Europe, then probably it would make more sense to go for European data center.
Once done, left-click on Compute | App Engine | Dashboard. When presented with the dialog box, select Try App Engine:
Tip
Downloading the example code
You can download the example code fi les for all Packt books you have purchased from your account at http://www.packtpub.com. If you purchased this book elsewhere, you can visit http://www.packtpub.com/support and register to have the fi les e-mailed directly to you.
And finally, you'll see the following screen:
This welcome page appears because you have no application deployed as yet. Once deployed, you'll see a dashboard, which we'll see in a while.
You can follow the above instructions from the welcome page, if you want to deploy a sample application as shown in the preceding screenshot, but for our purpose, we will deploy our own application. To deploy our own app, all we need is the project ID for which you can click on Home on the left side, which will show the following page:
We only need the Project ID from the first box on the top-left, which we will enter in app.yaml
for application directive and then we're all good. For example, in this chapter, we used mgae-01
as the Project ID and that's what we are using. Because application IDs must be unique across all the App Engine applications, therefore, you cannot use this ID while deploying your own application and you will have to select something else.
Once you have deployed the app, your dashboard (accessible from Compute | App Engine | Dashboard) will look like this, instead of the welcome page that we saw earlier:
Now that we are done with the basic setup, we will write the code and run and test it locally.
Create a directory somewhere. Create a file named app.yaml
and enter the following into it:
This app.yaml
file is what defines your application. Application is the unique ID that we discussed. The version
is your version of the app. You can have multiple versions of the same app. As you change this string, it will be considered a new version and would be deployed as a new version, whereas the previous version will be retained on the App Engine servers. You can switch to a previous version from the dashboard whenever you like. Besides this, you can also split the traffic between the various versions of an application.
The next attribute is the runtime
. We have many choices here, such as go
if we want to have our app in the Go programming language. Previously for Python, we had choice of either Python 2.7 or Python 2.5. However, support for the Python 2.5 runtime environment is deprecated, and new apps cannot be created with Python 2.5 since January 2014.
Next comes the api_version
. This indicates the version of the system services that you'd like to use. There is only one version of all the available system APIs (the ones that we discussed under runtime services), but in case Google does release any incompatible changes to the services, this API version number will be incremented. Thus, you will still be able to maintain the apps that you developed earlier, and you can opt for a newer version of APIs if you want to use them in newer applications or upgrade your existing applications to use newer versions.
Next comes the thread safe thing. Here, you indicate whether your application is thread-safe or not. As a rule of thumb, if your code does not write to any global variables or compute them on the fly to populate their values for later reference, your app is thread-safe. Hence, multiple requests can be handed over to your App Engine instance. Otherwise, you'll be handed over a single request at a time, which you'll have to finish processing before you can get the next request to be processed.
Multithreading was not available for the Python 2.5 environment because it worked via CGI, but Python 2.7 supports WSGI, which allows concurrent requests. However, this particular app uses the 2.7 runtime environment, but it is not a WSGI app. All of this might seem Greek to you for now, but we shall discuss CGI, WSGI, and concurrent requests in detail in the next chapter.
Next comes the handlers
section. Here, we list URLs as regular expressions and state what has to be done with them. They might be handled by a script or mapped to a static directory. We'll discuss the latter case in the next chapter, which will let us serve static application resources, such as images, styles, and scripts. An important thing that you should note is that the URLs in the list are always checked in the order in which they are defined, and as soon as the first match is found, the listed action is taken. Here, are mentioning tell that whatever URL we get, simply execute the Python script. This is the CGI way of doing things. WSGI will be slightly different, and we'll examine this in detail later.
So, this was the explanation of the app.yaml
, which describes the contents and details of your app. Next comes the actual script, which will generate the output for the web page. Create a main.py
file in the same directory as that of app.yaml
and enter the following code:
Now, let's examine this. This is actually a CGI script. First, we imported a standard Python module. Next, we wrote to the standard output (stdout
), and the first statement actually is writing an HTTP header, which indicated that we are generating plain text.
Next, the print
statement printed a blank line because the HTTP headers are supposed to be separated by a blank line from the HTTP body.
Next, we actually iterated over all the environment variables and printed them to stdout
, which in turn will be sent to the browser. With that, we're done with our example application.
Now that we understand how it works, let's run it locally by executing the following command:
Here, ~/Project/mgae/ch01/hello
is the directory that contains all the previously mentioned application files. Now, when you point your browser to http://localhost:8080
, you'll find a list of environment variables printed. Hit it with any URL, such as http://localhost:8080/hello
, and you'll find the same output except for a few environment variables, which might have a different value.
Let's deploy the application to the cloud, as follows:
This that indicates that our app is deployed and ready to sever. Navigate your browser to http://yourappid.appspot.com
and you will see something like this:
The --oauth2
option will open the browser, where you will have to enter your Google account credentials. You can do without --oauth2
. In this case, you will be asked for your email and password on the command shell, but you'll also get a notice that states that this mode of authentication is deprecated.
Let's examine a few interesting environment variables that are set by Google App Engine. REQUEST_ID_HASH
and REQUEST_LOG_ID
are set by App Engine to uniquely identify this request. That's the request ID that we talked about in the section about how scaling works. The APPENGINE_RUNTIME
indicates the runtime environment that this app is running on. There is a DATACENTER header that is set to us2
, which indicates that our app is being executed in the US data centers. Then, we have INSTANCE_ID
, which is the unique ID that is assigned to the instance handling this request.
Then, some user-specific headers such has USER_IS_ADMIN
, USER_EMAIL
, USER_ID
, USER_NICKNAME
, and AUTH_DOMAIN
are set by the User service that we discussed in the services section. If a user had logged in, these headers will have their email, ID, and nickname as values.
These headers are added by Google App Engine, and a feature of the environment in which your code executes. So that's all, folks!