Flask Deployment to Google App Engine

8 months ago | 29 December, 2021 | X minute read.

Introduction

This story series shares my framework for web applications using Python Flask as the backbone. It allows for advanced features to be added in as Python is very flexible.

The first part described the files needed to run the Flask website on your local machine. This final part extends the application by explaining how the application can be deployed to the cloud using Google App Engine (GAE).

Flask Development Web Stack Series: Part 2 of 2

Did you miss the first part?

Go To Part 1: Flask Webstack

Page Contents

Updated Directory Structure

The following shows the directory structure with the extra files needed to run the web app on Google App Engine. These additional files are described in this story.

app_directory/
  |-- app.yaml
  |-- .gcloudignore
  |-- requirements.txt
  |-- main.py    - defined in story part 1
  |-- assets/    - defined in story part 1
  |-- .gitignore - defined in story part 1

Download '.zip' of the files used in Part 2

Deploying to App Engine

Setup via Google Console

  1. Create a Project on Google Could Platform.

    • Take note of the Project ID when naming the project.
      Creating a Project
  2. Create an App Engine Application on the App Engine Console.

    • Ensure you have are working on the project you just created (at top of screen).
    • Choose a location/region for the hosting.
      Creating a Project
  3. No further settings are required to be configured here, however I use a standard Python environment (part of the next page).

  4. The rest is done in the terminal.

Google App Engine Configuration File

runtime: python37

handlers:

# This configures Google App Engine to serve the files in the app's static
# directory.
- url: /assets
  secure: always
  static_dir: assets

# This handler routes all requests not caught above to your main app. It is
# required when static routes are defined, but can be omitted (along with
# the entire handlers section) when there are no static files defined.
- url: /.*
  secure: always
  script: auto

Python Library Requirements File

This requirements file defines the python packages required for the project.

click==7.1.2
Flask==1.1.2
Flask-Markdown==0.3
itsdangerous==1.1.0
Jinja2==2.11.2
MarkupSafe==1.1.1
requests==2.21.0
Werkzeug==1.0.1

There are two good ways to generate the requirements.txt file.
First, you can use the pipreqs package as follows:

pip install pipreqs
pipreqs /path/to/project

The other option is to use the pip freeze command and redirect the output to the text file, creating a list of all Python packages installed.

pip3 freeze > requirements.txt

As this list could be quite large for the entire system, this method is best used when running in a Python virtual environment (venv), which is best practice. Learn more about Python virtual environments here.

Cloud Ignore File

This file defines parts of the directory tree which shouldn't be uploaded to App Engine when deploying the app, similar to the .gitignore file which restricts files Git manages.

# This file specifies files that are *not* uploaded to Google Cloud Platform
# using gcloud. It follows the same syntax as .gitignore, with the addition of
# "#!include" directives (which insert the entries of the given .gitignore-style
# file at that point).
#
# For more information, run:
#   $ gcloud topic gcloudignore
#
.gcloudignore
# If you would like to upload your .git directory, .gitignore file or files
# from your .gitignore file, remove the corresponding line
# below:

.git
.gitignore
archive/
tools/

# Python pycache:
__pycache__/
# Ignored by the build system
/setup.cfg

Google Cloud SDK Deployment

Download '.zip' of the files above

Now that the app is fully configured for use in App Engine, the following steps will deploy it. When updating, only the last 2 steps are required.

Download and install the Google Cloud SDK from here.

In the terminal initialise the SDK using command gcloud init. This will assist you to login to Google Cloud and select your project.

If you have multiple gcloud projects, you can change the current project to the correct one using gcloud projects list to list the projects then gcloud config set project <project-id> to set it. For example:

$ gcloud projects list

PROJECT_ID             NAME              PROJECT_NUMBER
anotherproject-123     anotherproject    123456789012
exampleproject-334607  ExampleProject    334212796965

pi@pi:/path/to/exampleproject $ gcloud config set project exampleproject-334607
Updated property [core/project].

Ensure you are in the directory of your app (where main.py is).

Deploy the app to App Engine using the command gcloud app deploy. This will upload the files and configure the application.

The first time you run this, you may need to enable 'Cloud Build'. The gcloud SDK will provide a link to do so.

Once ready it will provide a URL to access the website in a browser. Here is an example of successful deployment:

$ gcloud app deploy
Services to deploy:

descriptor:      [/path/to/exampleproject/app.yaml]
source:          [/path/to/exampleproject]
target project:  [exampleproject-334607]
target service:  [default]
target version:  [20211213t210027]
target url:      [https://exampleproject-334607.uc.r.appspot.com]


Do you want to continue (Y/n)?  y

Beginning deployment of service [default]...
╔════════════════════════════════════════════════════════════╗
╠═ Uploading 16 files to Google Cloud Storage          ═╣
╚════════════════════════════════════════════════════════════╝
File upload done.
Updating service [default]...done.
Setting traffic split for service [default]...done.
Deployed service [default] to [https://exampleproject-334607.uc.r.appspot.com]

You can stream logs from the command line by running:
  $ gcloud app logs tail -s default

To view your application in the web browser run:
  $ gcloud app browse

As you can see, this will allow access at the url: https://exampleproject-334607.uc.r.appspot.com.

Next Steps & Resources

If you missed if (I hope not), Part 1 describes the files needed to run a Python Flask powered website using Jinja templating on your local machine.

  • Add a custom domain - Google includes HTTPS certs for free!

APP ENGINE, FLASK, GOOGLE, PYTHON