Making our first Python application
We have now have an idea of the features Google Cloud Platform can provide us with and we are ready to put App Engine in action, but before we can start writing some code, we need to set up our workstation.
Download and installation
To get started, we need to install the Google App Engine SDK for Python for the platform of our choice. The SDK contains all the libraries needed to develop an application and a set of tools to run and test the application in the local environment and deploy it in the production servers. On some platforms, administrative tasks can be performed through a GUI, the Google App Engine Launcher, on other platforms we can use a comprehensive set of command line tools. We will see Google App Engine Launcher in detail later in this chapter.
Before installing the SDK, we have to check whether a working installation of Python 2.7 (version 2.7.8 is the latest at the time of writing this book) is available on our system; we need this specific version of Python because, with 2.5 deprecated now, it is the only version supported by the App Engine platform. If we are using Linux or Mac OS X, we can check the Python version from the terminal that issues the command (notice the capital letter V
):
The output should look like this:
If we are on Windows, we can just ensure the right version of Python is listed in the Programs section within the Control Panel.
The official App Engine download page contains links for all the available SDKs. The following link points directly to the Python version: https://developers.google.com/appengine/downloads#Google_App_Engine_SDK_for_Python.
We have to choose the right package for our platform, download the installer, and proceed with the installation.
To install the SDK on Windows we have to download the .msi
file from the App Engine download page, double-click it to launch the installation wizard, and follow the instructions on the screen. Once the install is complete, a shortcut to Google App Engine Launcher will be placed on the desktop as well as an item within the Start menu. The Windows version of the SDK does not provide any command-line tool, so we will always use Launcher to manage our applications.
To install the SDK on Mac OS X, we have to download the .dmg
file from the App Engine download page, double-click it to open the disk image, and drag the App Engine icon into the Applications
folder. It is convenient to keep a shortcut to Launcher in our Dock; to do so, we just have to just drag the App Engine icon again from the Applications
folder to the dock. The command-line tools will also be installed and during the first execution of Launcher, a pop-up dialog will prompt us as to whether we want to create the symlinks needed to make the tools available system-wide, so they can be executed from any terminal window without further configuration.
To install the SDK on Linux and more generally on POSIX-compliant systems, we have to download the .zip
file from the App Engine download page and extract its contents in a directory of our choice. The archive contains a folder named google_appengine
that contains the runtime and the command-line tools, and we have to add it to our shell's PATH
environment variable to make the tools available from within any terminal. The Linux version of the SDK does not include Launcher.
The Windows and OS X versions of the SDK ships with a graphical user interface tool called Launcher that we can use to perform administrative tasks such as creating and managing multiple applications.
Note
Launcher is a very handy tool but bear in mind that while every single task we can accomplish through Launcher can be performed by command-line tools as well, the contrary isn't true. There are tasks that can be performed only from the command line using the proper tools as we will see later in the book.
The following screenshot shows the Launcher window in OS X:
We can see the Launcher in Windows in the following screenshot:
Before we start using the Launcher it's important to check whether it is using the right Python version. This is very important if we have more than one Python installation in our system. To check the Python version used by Launcher and to change it, we can open the Preferences... dialog by clicking the appropriate menu depending on our platform and set the Python path value. In the same dialog we can specify which text editor Launcher will open by default when we need to edit application files.
To create a new application we can click New Application in the File menu or click the button with a plus sign icon in the bottom-left corner of the Launcher window. Launcher will prompt for the application name and the path to the folder that will contain all the project files; once created, the application will be listed in the main window of Launcher.
We can start the local development server by clicking the Run button on the Launcher toolbar or clicking Run in the Control menu. Once the server is started, we can stop it by clicking on the Stop button or the Stop entry in the Control menu. Clicking the Browse button or the Browse entry in the Control menu opens the default browser at the home page of the selected application. To browse the logs produced by the development server, we can open the Log Console window by clicking the Logs button on the toolbar or the Logs entry in the Control menu. The SDK Console button on the toolbar and the SDK Console action on the Control menu will open the default browser at the URL that serves the Developer Console, a built-in application to interact with the local development server, which we will explore in detail later in this chapter.
The Edit button will open the configuration file for the selected application in an external text editor, maybe the one we specified in the Preferences... dialog; the same happens when we click the Open in External Editor action in the Edit menu.
To deploy and upload the selected application to App Engine we can click the Deploy button on the toolbar or click the Deploy action in the Control menu. The Dashboard button on the toolbar and the Dashboard action in the Control menu will open the default browser at the URL of App Engine Administrative Console.
Using Launcher we can set additional flags for the local development server and customize some parameters such as the TCP port number to which listens. To do so we have to click the Application Settings... entry in the Edit menu and make the desired adjustments in the settings dialog.
Launcher can also handle existing applications created from scratch through the command line or checked out from an external repository. To add an existing application to the Launcher, we can click the Add Existing Application... entry in the File menu and specify the application path.
The first step to create an application is pick a name for it. According to the tradition we're going to write an application that will print "Hello, World!" so we can choose helloword
as the application name. We already know how to create an application from Launcher, the alternative is to do it manually from the command line.
At the simplest, a working Python application consists of a folder called application root that contains an app.yaml
configuration file and a Python module with the code needed to handle HTTP requests. When we create an application within Launcher, it takes care of generating those files and the root
folder for us, but let's see how can we can accomplish the same result from the command line.
The app.yaml configuration file
When we start creating the root
folder, it doesn't matter how we name it but to be consistent with Launcher we can use the application's name:
We then create an app.yaml
file that contains the following YAML
code:
Note
YAML (a recursive acronym for YAML Ain't Markup Language) is a human-readable serialization format that is suitable for configuration files that have to be accessed and manipulated both from users and programmatically.
The first section of the previous code defines some setup parameters for the application:
- The
application
parameter: This is the application name; later in the chapter, we'll see how important it is. - The
version
parameter: This is a string that specifies the version of the application. App Engine retains a copy of each version deployed and we can run them selectively, a very useful feature for testing an application before making it public. - The
runtime
parameter: At the time of writing this book, Python 27 is the only runtime available for newly created applications as Python 25 was deprecated. - The
api_version
parameter: This is the version of the API for the current runtime environment. At the time writing this, 1 is the only API version available for the Python 27 runtime. - The
threadsafe
parameter: This specifies whether our application can handle requests concurrently in separate threads or not.
The next section of the app.yaml
file lists the URLs we want to match in the form of a regular expression; the script
property specifies the handler for each URL. A handler is a procedure App Engine invokes to provide a response when an application receives a request. There are two types of handlers:
- The
script
handlers: These handlers run the Python code provided by the application - The
static file
handlers: These handlers return the content of a static resource such as an image or a file that contain the JavaScript code
In this case, we are using a script
handler, a Python callable addressed with a dot notation import string: App Engine will match any URL and invoke the app
object contained in the main
module.
The final section lists the name and version of third-party modules provided by App Engine we want to use from our application, and in this case we only need the latest version of the webapp2 web framework. We might wonder why we need something complex such as a web framework to simply print a "Hello, World!" message, but as we already know, our handler must implement a WSGI-compliant interface and this is exactly one of the features provided by webapp2. We will see how to use it in the next section.
The main.py application script
Now that the application is configured, we need to provide logic, so we create a file named main.py
in the application root folder that will contain the following:
In the first line of the previous code we import the webapp2
package into our code, and then we proceed to define a class named MainHandler
that is derived from the RequestHandler
class provided by the framework. The base class implements a behavior that makes it very easy to implement a handler for HTTP requests; all we have to do is to define a method named after the HTTP action we want to handle. In this case, we implement the get()
method that will be automatically invoked whenever the application receives a request of the type GET
. The RequestHandler
class also provides a self.response
property we can use to access the response object that will be returned to the application server. This property is a file-like object that supports a write()
method we can use to add content to the body of the HTTP response; in this case we write a string inside the response body with the default content type text/html
so that it will be shown inside the browser.
Right after the MainHandler
class definition we create the app
object, which is an instance of the WSGIApplication
class provided by webapp2 that implements the WSGI-compliant callable entry point we specified in app.yaml
with the import string main.app
. We pass two parameters to the class constructor, a list of URL patterns, and a Boolean flag stating whether the application should run in debug mode or not. URL patterns are tuples that contain two elements: a regular expression that matches requested URLs and a class object derived from webapp2.RequestHandler
class that will be instantiated to handle requests. URL patterns are processed one by one in the order they are in the list until one matches and the corresponding handler is called.
As we may notice, URL mappings take place twice—firstly in the app.yaml
file, where a URL is routed to a WSGI compatible application in our code and then in the WSGIApplication
class instance, where an URL is routed to a request handler object. We can freely choose how to use these mappings, that is either route all URLs in the app.yaml
file to a single webapp2 application where they are dispatched to handlers or to different URLs to different, smaller webapp2 applications.
Running the development server
The App Engine SDK provides an extremely useful tool called development server that runs on our local system emulating the runtime environment we will find in production. This way, we can test our applications locally as we write them. We already know how to start the development server from Launcher. To launch it from the command line instead, we run the dev_appserver.py
command tool passing the root folder of the application we want to execute as an argument. For example, if we're already inside the root folder of our helloworld
application, to start the server, we can run this command:
The development server will print some status information on the shell and will then start listen at the local host to the default TCP ports 8000 and 8080, serving the admin console and the application respectively.
While the server is running, we can open a browser, point it at http://localhost:8080
and see our first web application serving content.
The following screenshot shows the output:
If we are using Launcher, we can simply press the Browse button and the browser will be opened automatically at the right URL.
The development server automatically restarts application instances whenever it detects that some content on the application root folder has changed. For example, while the server is running we can try to change the Python code that alters the string we write in the response body:
After saving the file, we can refresh the browser and immediately see the changes without reloading the server, as shown in the following screenshot:
We can now move our application to a production server on App Engine and make it available through the Internet.
Uploading the application to App Engine
Every application running on App Engine is uniquely identified by its name within the Google Cloud Platform. That is why sometimes we find parts of the documentation and tools referring to that as application ID. When working on a local system, we can safely pick any name we want for an application as the local server does not enforce any control on the application ID; but, if we want to deploy an application in production, the application ID must be validated and registered through App Engine Admin Console.
Admin Console can be accessed at https://appengine.google.com/ and log in with a valid Google user account or a Google apps account for custom domains. If we are using Application Launcher, clicking the Dashboard button will open the browser at the right address for us. Once logged in, we can click the Create Application button to access the application creation page. We have to provide an application ID (the console will tell us whether it is valid and available) and a title for the application and we're done. For now, we can accept the default values for the remaining options; clicking on Create Application again will finally register the application's ID for us.
Now we have to change the dummy application ID we provided for our application with the one registered on App Engine. Open the app.yaml
configuration file and change the application
property accordingly:
We are now ready to deploy the application on App Engine. If we are using Application Launcher, all we have to do is click on the Deploy button in the toolbar. Launcher will ask for our Google credentials and then the log window will open showing the deployment status. If everything went fine the last line shown should be something like this:
Deploying from the command line is just as easy; from the application root directory, we issue the command:
We will be prompted for our Google account credentials, and then the deployment will proceed automatically.
Every App Engine application running in production can be accessed via http://the_registered_application_ID.appspot.com/
, so we can tell whether the application is actually working by accessing this URL from a browser and checking whether the output is the same as that produced by the local development server.
Google App Engine allow us to serve content over HTTPS (HTTP Secure) connections on top of the Secure Sockets Layer (SSL) protocol, which means that data transferred from and to the server is encrypted. When using the appspot.com
domain, this option is free of charge. To enable secure connections between clients and the App Engine server, all we have to do is add the secure
option to the URLs listed in the app.yaml
file:
On the local development server we will still use regular HTTP connections, but in production we will access https://the_registered_application_ID.appspot.com/
in a secure manner over HTTPS connections.
If we want to access the application over HTTPS through a custom domain instead, such as example.com
, we have to configure App Engine so that the platform can use our certificates by following the instructions at https://cloud.google.com/appengine/docs/ssl. This service has a fee and we will be charged monthly.