Getting Started with Flask on App Engine Standard Environment

This guide is designed to help you learn how to develop and deploy basic Python 2.7 applications that run on the Google App Engine Standard Environment. This guide is intended for use by those new to Google App Engine, its related services, and in particular, using App Engine with the Python language. For that reason, the guide provides deeper explanations for each task than what is found in the Quickstart guide.

Before you begin

Before you can develop an application:

  1. Create a new Cloud Platform Console project or retrieve the project ID of an existing project from the Google Cloud Platform Console:

    Go to the Projects page

    Tip: Retrieve a list of your existing project IDs with gcloud.

  2. Install and then initialize the Google Cloud SDK.

  3. Set up your development environment on your computer:

    1. Complete the Before you begin, Installing Eclipse, and Installing PyDev steps.
    2. When you reach the Configuring your project step, create a project named flask-app. Make a note of the location of this project, as you will need this information as you continue to develop your application.
    3. Do not complete the remaining steps in the document. You will install the Flask framework and its dependencies from the command line as you complete this guide.

Creating a basic application

This guide uses the Flask web application framework because of its simplicity, ease of use, and extensibility, but the same principles can be applied to any framework that you want to use. This guide teaches you:

  • How to create a basic user comment form that will display the content that the user submits via that form on an HTML template that you create.
  • How to create a basic application that can serve static files, such as CSS or images.

After you have set up your development environment, you can write the code for the application and deploy it to App Engine.

Basic structure of an app project

This guide uses the following structure for the flask-app project:

flask-app project structure

  • app.yaml: Configure the settings of your App Engine application
  • main.py: Write the content of your application
  • static: Directory to store your static files
    • style.css: Basic stylesheet that formats the look and feel of your template files
  • templates: Directory for all of your HTML templates
    • form.html: HTML template to display your form
    • submitted_form.html: HTML template to display the content of a submitted form

Setting up libraries to enable development

By default, the Google App Engine Python 2.7 runtime environment includes the Python standard library, the App Engine libraries, and a few bundled third- party packages. This guide will not explicitly use any runtime-provided libraries, but it will use other third-party libraries. For a complete list of runtime-provided libraries, see the built-in third-party libraries reference.

To install libraries into a folder in your project's root directory:

  1. Create a file named appengine_config.py in the root of the flask-app project directory. This file will tell the application how to find libraries in the lib directory:

    
    from google.appengine.ext import vendor
    
    # Add any libraries installed in the "lib" folder.
    vendor.add('lib')
    

  2. Open the command line and navigate to the root directory of the project, then use pip with the -t lib flag to install libraries:

    pip install -t lib flask
    

Creating the app.yaml file

You can configure your App Engine application's settings in the app.yaml file that you create manually or as part of the creation of your development project. The app.yaml file is a configuration file that tells App Engine how to run your application and how to map URLs to static files and Python modules.

To create the app.yaml file:

  1. Create a file named app.yaml in the root directory of your project.
  2. Add the following lines to the file:

    runtime: python27
    api_version: 1
    threadsafe: true
    
    handlers:
    - url: /.*
      script: main.app
    

More reference information about the app.yaml file can be found in the app.yaml reference documentation.

Importing Flask

The following sample is a basic Flask-based "Hello World!" application that also makes use of a simple error handler. The sample walks you through the following steps:

  • Importing the Python logging functionality and the Flask class from the Flask framework, then creating an instance of the Flask class.
  • Using the route() decorator to map the root URL ('/') to a simple request handler.
  • Defining a simple error handler.
import logging

from flask import Flask


app = Flask(__name__)


@app.route('/')
def hello():
    return 'Hello World!'


@app.errorhandler(500)
def server_error(e):
    # Log the error and stacktrace.
    logging.exception('An error occurred during a request.')
    return 'An internal error occurred.', 500

You can learn more about how to quickly get started with Flask in the Flask quickstart guide.

Creating a request handler for your Flask app

When App Engine receives a web request for your application, it calls the handler script that corresponds to the URL, as described in the application's app.yaml configuration file. The Python 2.7 runtime supports the WSGI standard. WSGI is preferred, and some features of Python 2.7 do not work without it. The configuration of your application's script handlers determines whether a request is handled using WSGI.

The server determines which Python application object to call by comparing the URL of the request to the URL patterns in the app's configuration file. It then calls the application object using the arguments as defined in the WSGI standard. The application object performs actions appropriate to the request, then prepares a response and returns it as a list of strings.

The following request handlers take the information that is submitted in the form in the /templates/form.html file and places that information onto the /templates/submitted_form.html template file:

  1. Import the Flask framework and the Flask interfaces that you want to use:

    from flask import Flask, render_template, request

  2. Create a request handler that displays a form on the form.html template page:

    @app.route('/form')
    def form():
        return render_template('form.html')

    When the user navigates to the /form/ directory within the application, the form.html template that you will create will be displayed.

  3. Create a request handler that stores the information from the submitted_form.html file:

    @app.route('/submitted', methods=['POST'])
    def submitted_form():
        name = request.form['name']
        email = request.form['email']
        site = request.form['site_url']
        comments = request.form['comments']
    

The application stores the form information in the variables that you created here. These variables will allow you to post the data from the form onto the submitted_form.html template that you will create.

You can easily extend the functionality of this form. For example, you can use the Mail API, Mailgun, Mailjet, or SendGrid to send the comments that users submit to yourself or to others.

Setting up Jinja2 templates

Since HTML that is embedded in code can be difficult to maintain, you should use a templating system, storing HTML in a separate file that uses special syntax to specify where the data returned from an application appears. You can use your template engine of choice by bundling it with your application code. For your convenience, App Engine includes the Django and Jinja2 templating engines.

  1. Add the following line to the end of the submitted_form() function:

    return render_template(
        'submitted_form.html',
        name=name,
        email=email,
        site=site,
        comments=comments)

    This line uses the render_template() interface to insert the content from the form onto the submitted_form.html page.

  2. Create the form.html and submitted_form.html templates:

    1. Create form.html in the templates directory of your project:

      <html>
        <head>
          <title>Submit a form</title>
         <link rel="stylesheet" type="text/css" href="/static/style.css">
        </head>
        <body>
          <div id="container">
            <div class="pagetitle">
              <h1>Submit a form</h1>
            </div>
            <div id="main">
              <form method="post" action="{{ url_for('submitted_form') }}">
                <label for="name">Name:</label>
                <input type="text" name="name"><br />
                <label for="email">Email address:</label>
                <input type="email" name="email"><br />
                <label for="site_url">Website URL:</label>
                <input type="url" name="site_url"><br />
                <label for="comments">Comments:</label>
                <textarea name="comments"></textarea><br />
                <input type="submit">
              </form>
            </div>
          </div>
        </body>
      </html>
      

    2. Create submitted_form.html in the templates directory of your project:

      <html>
       <head>
         <title>Submitted form</title>
         <link rel="stylesheet" type="text/css" href="/static/style.css">
       </head>
       <body>
         <div id="container">
           <div class="pagetitle">
             <h1>Form submitted</h1>
           </div>
           <div id="main">
             <p>Thanks for your submission, {{name}}!</p>
             <p>Here's a review of the information that you sent:</p>
             <p>
                <strong>Name</strong>: {{name}} <br>
                <strong>Email</strong>: {{email}} <br>
                <strong>Website URL</strong>: {{site}} <br>
                <strong>Comments</strong>: {{comments}}
             </p>
           </div>
         </div>
       <body>
      </html>
      

To learn more about using templates with Flask and Jinja2, visit the official Flask documentation.

Serving static files

Serving static files is more efficient for some content, such as images, CSS or Flash animations, which aren't generated dynamically when a page is requested.

Create a CSS file and create a handler for it:

  1. Create the style.css file that will modify the look of your template files that you just created. Create the file in the static folder of your project and add the following styling:

    .pagetitle {
        color: #800080;
    }
    

  2. Specify the static directories that contain static files in your app.yaml file, if the handler does not exist already:

    handlers:
    - url: /static
      static_dir: static
    - url: /.*
      script: main.app

    The handlers section defines two handlers for URLs. When App Engine receives a request for a URL beginning with /static, it maps the remainder of the path to files in the static directory, and if an appropriate file is found, the contents of the file are returned to the client.

For more information on URL mapping and other options you can specify in app.yaml, see the app.yaml reference.

Deploying your application

To upload the app, run the following command from within the root directory of your project where the app.yaml file is located:

gcloud app deploy

Optional flags:

  • Include the --project flag to specify an alternate Cloud Platform Console project ID to what you initialized as the default in the gcloud tool. Example: --project [YOUR_PROJECT_ID]
  • Include the -v flag to specify a version ID, otherwise one is generated for you. Example: -v [YOUR_VERSION_ID]

To learn more about deploying your app from the command line, see Deploying a Python App.

Viewing your application

To launch your browser and view the app at http://[YOUR_PROJECT_ID].appspot.com, run the following command:

gcloud app browse

Support

If you encounter problems during the development of your application, you can get help from technical support and developer communities.

What's next

Send feedback about...

App Engine standard environment for Python