Python Web Applications: Deploy Your Script as a Flask App

Python Web Applications: Deploy Your Script as a Flask App

by Martin Breuss Updated Reading time estimate 56m intermediate devops flask web-dev

You wrote a Python script that you’re proud of, and now you want to show it off to the world. But how? Most people won’t know what to do with your .py file. Converting your script into a Python web application is a great solution to make your code usable for a broad audience.

In this tutorial, you’ll learn how to go from a local Python script to a fully deployed Flask web application that you can share with the world.

By the end of this tutorial, you’ll know:

  • What web applications are and how you can host them online
  • How to convert a Python script into a Flask web application
  • How to improve user experience by adding HTML to your Python code
  • How to deploy your Python web application to Google App Engine

In addition to walking through an example project, you’ll find a number of exercises throughout the tutorial. They’ll give you a chance to solidify what you’re learning through extra practice. You can also download the source code that you’ll use to build your web application by clicking the link below:

Take the Quiz: Test your knowledge with our interactive “Python Web Applications: Deploy Your Script as a Flask App” quiz. You’ll receive a score upon completion to help you track your learning progress:


Interactive Quiz

Python Web Applications: Deploy Your Script as a Flask App

Test your understanding of Flask web apps: routes, request data, escaping user input, and deploying a Python script to Google App Engine.

Brush Up on the Basics

In this section, you’ll get a theoretical footing in the different topics that you’ll work with during the practical part of this tutorial:

  • What types of Python code distribution exist
  • Why building a web application can be a good choice
  • What a web application is
  • How content gets delivered over the Internet
  • What web hosting means
  • Which hosting providers exist and which one to use

Brushing up on these topics can help you feel more confident when writing Python code for the Web. However, if you’re already familiar with them, then feel free to skip ahead, install the Google Cloud SDK, and start building your Python web app.

Distribute Your Python Code

Bringing your code to your users is called distribution. Traditionally, there are three different approaches you can use to distribute your code so that others can work with your programs:

  1. Python library
  2. Standalone program
  3. Python web application

You’ll take a closer look at each of these approaches below.

Python Library

If you’ve worked with Python’s extensive package ecosystem, then you’ve likely installed Python packages with pip. As a programmer, you might want to publish your Python package on PyPI to allow other users to access and use your code by installing it using pip:

Language: Shell
$ python3 -m pip install <your-package-name>

After you’ve successfully published your code to PyPI, this command will install your package, including its dependencies, on any of your users’ computers, provided that they have an Internet connection.

If you don’t want to publish your code as a PyPI package, then you can still use Python’s built-in sdist command to create a source distribution or a Python wheel to create a built distribution to share with your users.

Distributing your code like this keeps it close to the original script you wrote and adds only what’s necessary for others to run it. However, using this approach also means that your users will need to run your code with Python. Many people who want to use your script’s functionality won’t have Python installed or won’t be familiar with the processes required to work directly with your code.

A more user-friendly way to present your code to potential users is to build a standalone program.

Standalone Program

Computer programs come in different shapes and forms, and there are multiple options for transforming your Python scripts into standalone programs. Below you’ll read about two possibilities:

  1. Packaging your code
  2. Building a GUI

Programs such as PyInstaller, py2app, py2exe, or Briefcase can help with packaging your code. They turn Python scripts into executable programs that can be used on different platforms without requiring your users to explicitly run the Python interpreter.

While packaging your code can resolve dependency problems, your code still just runs on the command line. Most people are used to working with programs that provide a graphical user interface (GUI). You can make your Python code accessible to more people by building a GUI for it.

While a standalone GUI desktop program can make your code accessible to a wider audience, it still presents a hurdle for people to get started. Before running your program, potential users have a few steps to get through. They need to find the right version for their operating system, download it, and successfully install it. Some may give up before they make it all the way.

It makes sense that many developers instead build web applications that can be accessed quickly and run on an Internet browser.

Python Web Application

The advantage of web applications is that they’re platform independent and can be run by anyone who has access to the Internet. Their code is implemented on a back-end server, where the program processes incoming requests and responds through a shared protocol that’s understood by all browsers.

Python powers many large web applications and is a common choice as a back-end language. Many Python-driven web applications are planned from the start as web applications and are built using Python web frameworks such as Flask, which you’ll use in this tutorial.

However, instead of the web-first approach described above, you’re going to take a different angle. After all, you weren’t planning to build a web application. You just created a useful Python script, and now you want to share with the world. To make it accessible to a broad range of users, you’ll refactor it into a web application and then deploy it to the Internet.

It’s time to go over what a web application is and how it’s different from other content on the Web.

Learn About Python Web Applications

Historically, websites had fixed content that was the same for every user who accessed that page. These web pages are called static because their content doesn’t change when you interact with them. When serving a static web page, a web server responds to your request by sending back the content of that page, regardless of who you are or what other actions you took.

You can browse an example of a static website at the first URL that ever went online, as well as the pages it links to:

Screenshot of one of the first static webpages, displaying the history of the project as envisioned at CERN
The history of the WWW

Such static websites aren’t considered applications since their content isn’t generated dynamically by code. While static sites used to make up all of the Internet, most websites today are true web applications, which offer dynamic web pages that can change the content they deliver.

For instance, a webmail application allows you to interact with it in many ways. Depending on your actions, it can display different types of information, often while staying in a single page:

A webmail web app page as an example for a dynamic webpage
A single-page Webmail application

Python-driven web applications use Python code to determine what actions to take and what content to show. Your code is run by the web server that hosts your website, which means that your users don’t need to install anything. All they need to interact with your code is a browser and an Internet connection.

Getting Python to run on a website can be complicated, but there are a number of different web frameworks that automatically take care of the details. As mentioned above, you’ll build a basic Flask application in this tutorial.

In the upcoming section, you’ll get a high-level perspective on the main processes that need to happen to run your Python code on a server and deliver a response to your users.

Review the HTTP Request-Response Cycle

Serving dynamic content over the Internet involves a lot of different pieces, and they all have to communicate with one another to function correctly. Here’s a generalized overview of what takes place when a user interacts with a web application:

  1. Sending: First, your user makes a request for a particular web page on your web app. They can do this, for example, by typing a URL into their browser.

  2. Receiving: This request gets received by the web server that hosts your website.

  3. Matching: Your web server now uses a program to match the user’s request to a particular portion of your Python script.

  4. Running: The appropriate Python code is called up by that program. When your code runs, it writes out a web page as a response.

  5. Delivering: The program then delivers this response back to your user through the web server.

  6. Viewing: Finally, the user can view the web server’s response. For example, the resulting web page can be displayed in a browser.

This is a general process of how content is delivered over the Internet. The programming language used on the server, as well as the technologies used to establish that connection, can differ. However, the concept used to communicate across HTTP requests and responses remains the same and is called the HTTP Request-Response Cycle.

To allow Flask to handle requests on the server side, you’ll need to find a place where your Python code can live online. Storing your code online to run a web application is called web hosting, and there are a number of providers offering both paid and free web hosting.

Choose a Hosting Provider: Google App Engine

When choosing a web hosting provider, you need to confirm that it supports running Python code. Many of them cost money, but this tutorial will stick with a free option that’s professional and highly scalable yet still reasonable to set up: Google App Engine.

There are a number of other free options, such as PythonAnywhere, Repl.it, or Heroku that you can explore later on. Using Google App Engine will give you a good start in learning about deploying Python code to the web as it strikes a balance between abstracting away complexity and allowing you to customize the setup.

Google App Engine is part of the Google Cloud Platform (GCP), which is run by Google and represents one of the big cloud providers, along with Microsoft Azure and Amazon Web Services (AWS).

To get started with GCP, download and install the Google Cloud SDK for your operating system. For additional guidance beyond what you’ll find in this tutorial, you can consult Google App Engine’s documentation.

The Google Cloud SDK installation also includes a command-line program called gcloud, which you’ll later use to deploy your web app. Once you’re done with the installation, you can verify that everything worked by typing the following command into your console:

Language: Shell
$ gcloud --version

You should receive a text output in your terminal that looks similar to the one below:

Language: Text
app-engine-python 1.9.91
bq 2.0.62
cloud-datastore-emulator 2.1.0
core 2020.11.13
gsutil 4.55

Your version numbers will probably be different, but as long as the gcloud program is successfully found on your computer, your installation was successful.

With this high-level overview of concepts in mind and the Google Cloud SDK installed, you’re ready to set up a Python project that you’ll later deploy to the Internet.

Build a Basic Python Web Application

Google App Engine requires you to use a web framework for creating your web application in a Python 3 environment. Since you’re trying to use a minimal setup to get your local Python code up on the Internet, a microframework such as Flask is a good choice. A minimal implementation of Flask is so small that you might not even notice that you’re using a web framework.

The application you’re going to create will rely on several different files, so the first thing you need to do is to create a project folder to hold all these files.

Set Up Your Project

Create a project folder and give it a name that’s descriptive of your project. For this practice project, call the folder hello-app. You’ll need three files inside this folder:

  1. main.py contains your Python code wrapped in a minimal implementation of the Flask web framework.
  2. requirements.txt lists all the dependencies your code needs to work properly.
  3. app.yaml helps Google App Engine decide which settings to use on its server.

While three files might sound like a lot, you’ll see that this project uses fewer than ten lines of code across all three files. This represents the minimal setup you need to provide to Google App Engine for any Python project you may launch. The rest will be your own Python code. You can download the complete source code that you’ll use in this tutorial by clicking the link below:

Next, you’ll take a look at the content of each of the files starting with the most complex one, main.py.

Create main.py

main.py is the file that Flask uses to deliver your content. At the top of the file, you import the Flask class on line 1, then you create an instance of a Flask app on line 3:

Language: Python
 1from flask import Flask
 2
 3app = Flask(__name__)
 4
 5@app.route("/")
 6def index():
 7    return "Congratulations, it's a web app!"

After you create the Flask app, you write a Python decorator on line 5 called @app.route that Flask uses to connect URL endpoints with code contained in functions. The argument to @app.route defines the URL’s path component, which is the root path ("/") in this case.

The code on lines 6 and 7 makes up index(), which is wrapped by the decorator. This function defines what should be executed if the defined URL endpoint is requested by a user. Its return value determines what a user will see when they load the page.

In other words, if a user types the base URL of your web app into their browser, then Flask runs index() and the user sees the returned text. In this case, that text is just one sentence: Congratulations, it's a web app!

You can render more complex content, and you can also create more than one function so that users can visit different URL endpoints in your app to receive different responses. However, for this initial implementation, it’s fine to stick with this short and encouraging success message.

Create requirements.txt

The next file to look at is requirements.txt. Since Flask is the only dependency of this project, that’s all you need to specify:

Language: Python Requirements
Flask==2.1.2

If your app has other dependencies, then you’ll need to add them to your requirements.txt file as well.

Google App Engine will use requirements.txt to install the necessary Python dependencies for your project when setting it up on the server. This is similar to what you would do after creating and activating a new virtual environment locally.

Create app.yaml

The third file, app.yaml, helps Google App Engine set up the right server environment for your code. This file requires only one line, which defines the Python runtime:

Language: YAML
runtime: python38

The line shown above clarifies that the right runtime for your Python code is Python 3.8. This is enough for Google App Engine to do the necessary setup on its servers.

You can use Google App Engine’s app.yaml file for additional setup, such as adding environment variables to your application. You can also use it to define the path to static content for your app, such as images, CSS or JavaScript files. This tutorial won’t go into these additional settings, but you can consult Google App Engine’s documentation on the app.yaml Configuration File if you want to add such functionality.

These nine lines of code complete the necessary setup for this app. Your project is now ready for deployment.

However, it’s good practice to test your code before putting it into production so you can catch potential errors. Next, you’ll check whether everything works as expected locally before deploying your code to the Internet.

Test Locally

Flask comes packaged with a development web server. You can use this development server to double-check that your code works as expected. To be able to run the Flask development server locally, you need to complete two steps. Google App Engine will do the same steps on its servers once you deploy your code:

  1. Set up a virtual environment.
  2. Install the flask package.

To set up a Python 3 virtual environment, navigate to your project folder on your terminal and type the following command:

Language: Shell
$ python3 -m venv venv

This will create a new virtual environment named venv using the version of Python 3 that you have installed on your system. Next, you need to activate the virtual environment by sourcing the activation script:

Language: Shell
$ source venv/bin/activate

After executing this command, your prompt will change to indicate that you’re now operating from within the virtual environment. After you successfully set up and activate your virtual environment, you’re ready to install Flask:

Language: Shell
$ python3 -m pip install -r requirements.txt

This command fetches all packages listed in requirements.txt from PyPI and installs them in your virtual environment. In this case, the only package installed will be Flask.

Wait for the installation to complete, then open up main.py and add the following two lines of code at the bottom of the file:

Language: Python
if __name__ == "__main__":
    app.run(host="127.0.0.1", port=8080, debug=True)

These two lines tell Python to start Flask’s development server when the script is executed from the command line. It’ll be used only when you run the script locally. When you deploy the code to Google App Engine, a professional web server process, such as Gunicorn, will serve the app instead. You won’t need to change anything to make this happen.

You can now start Flask’s development server and interact with your Python app in your browser. To do so, you need to run the Python script that starts the Flask app by typing the following command:

Language: Shell
$ python3 main.py

Flask starts up the development server, and your terminal will display output similar to the text shown below:

Language: Shell
 * Serving Flask app "main" (lazy loading)
 * Environment: production
   WARNING: This is a development server.
   Do not use it in a production deployment.
   Use a production WSGI server instead.
 * Debug mode: on
 * Running on http://127.0.0.1:8080/ (Press CTRL+C to quit)
 * Restarting with stat
 * Debugger is active!
 * Debugger PIN: 315-059-987

This output tells you three important pieces of information:

  1. WARNING: This is Flask’s development server, which means you don’t want to use it to serve your code in production. Google App Engine will handle that for you instead.

  2. Running on http://127.0.0.1:8080/: This is the URL where you can find your app. It’s the URL for your localhost, which means the app is running on your own computer. Navigate to that URL in your browser to see your code live.

  3. Press CTRL+C to quit: The same line also tells you that you can exit the development server by pressing Ctrl+C on your keyboard.

Follow the instructions and open a browser tab at http://127.0.0.1:8080/. You should see a page displaying the text that your function returns: Congratulations, it's a web app!

You can use Flask’s development server to inspect any changes that you make to the code of your Python app. The server listens to changes you make in the code and will automatically reload to display them. If your app doesn’t render as you expect it to on the development server, then it won’t work in production either. So make sure that it looks good before you deploy it.

Also keep in mind that even if it works well locally, it might not work quite the same once deployed. This is because there are other factors involved when you deploy your code to Google App Engine. However, for a basic app such as the one you’re building in this tutorial, you can be confident that it’ll work in production if it works well locally.

Change the return value of index() and confirm that you can see the change reflected in your browser. Play around with it. What happens when you change the return value of index() to HTML code, such as <h1>Hello</h1>, instead of using a plain text string?

After having checked your setup and the code’s functionality on your local development server, you’re prepared to deploy it to Google App Engine.

Deploy Your Python Web Application

It’s finally time to bring your app online. But first, your code needs a place to live on Google’s servers, and you need to make sure that it gets there safely. In this section of the tutorial, you’ll work on completing the necessary deployment setups both in the cloud and locally.

Set Up on Google App Engine

Read through the setup process below step by step. You can compare what you see in your browser with the screenshots. The project name used in the example screenshots is hello-app.

Start by signing in to the Google Cloud Platform. Navigate to the dashboard view, where you’ll see a toolbar at the top of the window. Select the downward-facing arrow button toward the left side of the toolbar. This will pop up a modal containing a list of your Google projects:

Dropdown for viewing all of your Google projects

The modal displays a list of your projects. The list may be empty if you haven’t created any projects yet. On the top right of that modal, find the NEW PROJECT button and click it:

Button to create a new project on Google App Engine

Clicking NEW PROJECT will redirect you to a new page where you can decide on a name for your project. This name will appear in the URL of your application, which will look similar to http://your-application-name.nw.r.appspot.com. Use hello-app as the name for this project to stay consistent with the tutorial:

Input field for assigning a project name to a GAE project

You can see your project ID below the Project name input field. The project ID consists of the name you entered and a number that Google App Engine adds. In the case of this tutorial, you can see that the project ID is hello-app-295110. Copy your personal project ID since you’ll need it later on for deploying.

You can now click CREATE and wait for the project to be set up on Google App Engine’s side. Once that’s done, a notification will pop up telling you that a new project has been created. It also gives you the option to select it. Go ahead and do that by clicking SELECT PROJECT:

Screenshot showing the option to Select Project

Clicking SELECT PROJECT will redirect you to the main page of your new Google Cloud Platform project. It looks like this:

Google Cloud Platform dashboard view

From here, you want to switch to the dashboard of Google App Engine. You can do that by clicking the hamburger menu on the top left, scrolling down to select App Engine in the first list, then selecting Dashboard on the top of the next pop-up list:

Visual instructions on how to get from the Cloud Platform dashboard to the App Engine dashboard

This will finally redirect you to the Google App Engine dashboard view of your new project. Since the project is empty so far, the page will look similar to this:

New project page on GAE after successfully creating a new project

When you see this page, it means you have completed setting up a new project on Google App Engine. You’re now ready to head back to the terminal on your computer and complete the local steps necessary to deploy your app to this project.

Set Up Locally for Deployment

After successfully installing the Google Cloud SDK, you have access to the gcloud command-line interface. This program comes with helpful instructions that guide you through deploying your web app. Start by typing the command that was suggested to you when you created a new project on the Google App Engine website:

New project page with gcloud CLI command suggested highlighted

As you can see in the bottom-right corner of the page, Google App Engine suggests a terminal command to deploy your code to this project. Open up your terminal, navigate to your project folder, then run the suggested command:

Language: Shell
$ gcloud app deploy

When you execute this command without any previous setup, the program will respond with an error message:

Language: Text
ERROR: (gcloud.app.deploy)
You do not currently have an active account selected.
Please run:

  $ gcloud auth login

to obtain new credentials.

If you have already logged in with a different account:

    $ gcloud config set account ACCOUNT

to select an already authenticated account to use.

You receive this error message because you can’t deploy any code to your Google App Engine account unless you prove to Google that you’re the owner of that account. You’ll need to authenticate with your Google App Engine account from your local computer.

The gcloud command-line app already provided you with the command that you need to run. Type it into your terminal:

Language: Shell
$ gcloud auth login

This will start the authentication process by generating a validation URL and opening it up in your browser. Complete the process by selecting your Google account in the browser window and granting Google Cloud SDK the necessary privileges. After you do this, you can return to your terminal, where you’ll see some information about the authentication process:

Language: Text
Your browser has been opened to visit:

    https://accounts.google.com/o/oauth2/auth?client_id=<yourid>

You are now logged in as [<your@email.com>].
Your current project is [None].  You can change this setting by running:
  $ gcloud config set project PROJECT_ID

If you see this message, then the authentication was successful. You can also see that the command-line program again offers you helpful information about your next step.

It tells you that there is currently no project set, and that you can set one by running gcloud config set project PROJECT_ID. Now you’ll need the project ID that you noted earlier.

Be sure to replace hello-app-295110 with your own project ID when running the suggested command:

Language: Shell
$ gcloud config set project hello-app-295110

Your terminal will print out a short feedback message that the project property has been updated. After successfully authenticating and setting the default project to your project ID, you have completed the necessary setup steps.

Run the Deployment Process

Now you’re ready to try the initial deployment command a second time:

Language: Shell
$ gcloud app deploy

The gcloud app fetches your authentication credentials as well as the project ID information from the default configuration that you just set up and allows you to proceed. Next, you need to select a region where your application should be hosted:

Language: Text
You are creating an app for project [hello-app-295110].
WARNING: Creating an App Engine application for a project is
irreversible and the region cannot be changed.
More information about regions is at
<https://cloud.google.com/appengine/docs/locations>.

Please choose the region where you want your App Engine application
located:

 [1] asia-east2
 [2] asia-northeast1
 [3] asia-northeast2
 [4] asia-northeast3
 [5] asia-south1
 [6] asia-southeast2
 [7] australia-southeast1
 [8] europe-west
 [9] europe-west2
 [10] europe-west3
 [11] europe-west6
 [12] northamerica-northeast1
 [13] southamerica-east1
 [14] us-central
 [15] us-east1
 [16] us-east4
 [17] us-west2
 [18] us-west3
 [19] us-west4
 [20] cancel
Please enter your numeric choice:

Enter one of the numbers that are listed on the left side and press Enter.

After you enter a number, the CLI will continue with the setup process. Before deploying your code to Google App Engine, it’ll show you an overview of what the deployment will look like and ask you for a final confirmation:

Language: Text
Creating App Engine application in project [hello-app-295110]
and region [europe-west]....done.
Services to deploy:

descriptor:      [/Users/realpython/Documents/helloapp/app.yaml]
source:          [/Users/realpython/Documents/helloapp]
target project:  [hello-app-295110]
target service:  [default]
target version:  [20201109t112408]
target url:      [https://hello-app-295110.ew.r.appspot.com]


Do you want to continue (Y/n)?

After you confirm the setup by typing Y, your deployment will finally be on its way. Your terminal will show you some more information and a small loading animation while Google App Engine sets up your project on its servers:

Language: Text
Beginning deployment of service [default]...
Created .gcloudignore file. See `gcloud topic gcloudignore` for details.
╔════════════════════════════════════════════════════════════╗
╠═ Uploading 3 files to Google Cloud Storage                ═╣
╚════════════════════════════════════════════════════════════╝
File upload done.
Updating service [default]...⠼

Since this is the first deployment of your web app, it may take a few minutes to complete. Once the deployment is finished, you’ll see another helpful output in the console. It’ll look similar to the one below:

Language: Text
Deployed service [default] to [https://hello-app-295110.ew.r.appspot.com]

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