Book Image

Python for Google App Engine

By : Massimiliano Pippi
Book Image

Python for Google App Engine

By: Massimiliano Pippi

Overview of this book

Table of Contents (15 chapters)
Python for Google App Engine
Credits
About the Author
About the Reviewers
www.PacktPub.com
Preface
Index

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):

python -V

The output should look like this:

Python 2.7.8

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.

Installing on Windows

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.

Installing on Mac OS X

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.

Installing on Linux

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.

App Engine 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.

Creating the application

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:

mkdir helloworld && cd helloworld

We then create an app.yaml file that contains the following YAML code:

application: helloworld
version: 1
runtime: python27
api_version: 1
threadsafe: yes

handlers:
- url: .*
  script: main.app

libraries:
- name: webapp2
  version: "2.5.2"

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:

import webapp2

class MainHandler(webapp2.RequestHandler):
    def get(self):
        self.response.write('Hello world!')

app = webapp2.WSGIApplication([
    ('/', MainHandler)
], debug=True)

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:

dev_appserver.py .

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:

import webapp2

class MainHandler(webapp2.RequestHandler):
    def get(self):
        self.response.write('<H1>Hello world!</H1>')
        self.response.write("<p>I'm using App Engine!</p>")

app = webapp2.WSGIApplication([
    ('/', MainHandler)
], debug=True)

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:

application: the_registered_application_ID
version: 1
runtime: python27
api_version: 1
threadsafe: yes

handlers:
- url: .*
  script: main.app

libraries:
- name: webapp2
  version: "2.5.2"

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:

*** appcfg.py has finished with exit code 0 ***

Deploying from the command line is just as easy; from the application root directory, we issue the command:

appcfg.py update .

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:

handlers:
- url: .*
  script: main.app
  secure: always

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.