Build a Python App with Flask and Feature Flags in 10 Minutes
Tags: code
Published: 2021-03-19 17:21:55

---
title: Build a Python App with Flask and Feature Flags in 10 Minutes
published: true
date: 2021-02-10 17:48:00 UTC
tags: Code
canonical_url: https://www.split.io/blog/python-flask-feature-flags/
---

Feature flags allow you to configure your app without writing additional code in your codebase. With dynamic configurations, you can easily specify the experience desired for each segment of users without ever deploying new code. Feature flags are the foundation for progressive delivery, making it easier to test in production, release faster, and deploy code more safely. In this step-by-step tutorial, you will build a Python web app with Flask and then implement feature flags. For this example, you will build a menu application that will store the two menus for my restaurant.

## Prerequisites for Python, Flask, Feature Flags, etc.

You will need to install the Python extension for this project. From Visual Studio, click on the extensions tab and search for Python. Look for the extension that looks like this:

![](https://lh4.googleusercontent.com/FoaaGwT8QOD0z_GeKpAR8ZlqtIBLsz_pQvVu0ag2p9Y06LGPETIi5yeDFO5SRPg7336dBjdzseIvzbmqVTiqm9D8cdoEzoU9BJ3gUXXBJzB5p9e5r-T1fRMHbwkD3Fqi2t0dML0-)

Then, from your terminal, install python3.

`brew install python3`

You should also be using a virtual environment to download all of the Flask extensions you need. In your root folder, enter the following.

`python3 -m venv env`

Next, we will select our Python interpreter. In VSCode, from the command palette, search for Python: Select Interpreter.

![](https://lh5.googleusercontent.com/6Xbe5QjdQ2VeSJSFa7qSP7AngI4aijLI3ksFk6DQOPRdZKi8YcApYVjmoRMU_EeUKycq-bgJEdmFGa6xa-qXh86wLejMvacGqcN3xGhA03YiXRysvWx2RjZrdnxUMGyx0_Qd2TSs)

Select the path that starts with `./env`.

![](https://lh5.googleusercontent.com/o6A5I0xrhIpPYPnoS7gC2VXGkbegaqvlZow_0sMVfBaW4tN4sKZ9Qtx3DEa3iVUfuw-6uria43bE8SkAztBTsxNAXWrN8WG9Glj-SjDx-aQkMGhMzb8IoDMU6oCISgnRdsOnyBGB)

Now, from the Command Palette, search for Terminal: Create New Integrated Terminal.

![](https://lh4.googleusercontent.com/MEKIoyCO8489hCSkkkkb1xFjQpbp2yQpz5KhmjOouNRBXkpvQZ2xl2pI8AgdV4ytn_w5TPOBheP4XZY_LIi0YepuhSbwctqtU6dYCDKELq_koiIm7oYtXrUXMbSvo6C80XQgi3kp)

This will automatically activate your virtual environment.

Now, install Flask.

`pip3 install flask`

You will also need a [free developer account](https://www.split.io/) from Split, so be sure to sign up if you don’t have one yet!

## Create Your Flask App

In your root directory, create a file named `app.py` and import Flask.

`from flask import Flask`

`app = Flask( __name__ )`

Next, in the `app.py` file, you need to add a function that returns content in the home URL.

`@app.route("/")`

`def home():`

`   return "Hello, Flask!"`

In your terminal, run `python3 -m flask run`. Command-click on the URL that is outputted with the local port. 

![](https://lh4.googleusercontent.com/GuBwAcHjPyOW8rBY-PuXYD20hSKhDeZeZwkQRSsZYMO03aUvAi9MQIcCn2BeJH7uGSxI8EPj2EARWDRA1E_A5TNKg1gBNm3KC0wW4HRjx8WNC_63JDLUxLJC_5KOks1z0mVsqSQx)

Now that we got the app up and running, let’s add some functionality and styles to it. Update your `app.py` file to also import `render_template` and return that in a new function called `index()`. You can remove the old home function. The new index function will return the `index.html` file with the new template.

`from flask import Flask, render_template`

`app = Flask( __name__ )`

`@app.route("/")`

`def index():`

`   return render_template('index.html')`

In your root directory, create a new folder called templates, and in that folder, create a new file called `index.html`. Here, enter “!+tab” to render a basic HTML template.

I am going to call my restaurant The Queen’s Gambit, so let’s add that in a new Header.

```

`<!DOCTYPE html>
<html lang="en">
<head>
   <meta charset="UTF-8">
   <meta name="viewport" content="width=device-width, initial-scale=1.0">
   <title>The Queen's Gambit</title>
</head>
<body>
   <h1>The Queen's Gambit </h1>
</body>
</html>`
<small id="shcb-language-1"><span>Code language:</span> <span>Django</span> <span>(</span><span>django</span><span>)</span></small>
```

Now, we need to build our menus and add them to the home page. In the templates folder, add a new HTML file called `lunch_menu.html `and one called `happy_hour.html.` Then add some tables with the menu items you’d like in each corresponding menu.

Let’s add those routes to our `app.py` file:

```

`from flask import Flask, render_template
app = Flask( __name__ )
 
 
@app.route("/")
def index():
   return render_template('index.html')
 
 
@app.route("/lunch")
def lunch():
   return render_template('lunch_menu.html')
 
 
@app.route("/happyhour")
def happyhour():
   return render_template('happy_hour_menu.html')`
<small id="shcb-language-2"><span>Code language:</span> <span>Ruby</span> <span>(</span><span>ruby</span><span>)</span></small>
```

Now we can add the corresponding links to our index.html file.

```

`<!DOCTYPE html>
<html lang="en">
<head>
   <meta charset="UTF-8">
   <meta name="viewport" content="width=device-width, initial-scale=1.0">
   <title>The Queen's Gambit</title>
</head>
<body>
   <h1>The Queen's Gambit </h1>
   <h2><a href="/lunch">Lunch Menu</a></h2>
   <h2><a href="/happyhour">Happy Hour Menu</a></h2>
</body>
</html>`
<small id="shcb-language-3"><span>Code language:</span> <span>Django</span> <span>(</span><span>django</span><span>)</span></small>
```

When you run `python3 -m flask run`, you should see your menu app:

![](https://lh5.googleusercontent.com/MQ4xC4-jX7sxJtVa5GHgXXMDWCo1p7mjTdEwGTwGI-5Dv8hf65Rv6M4fdFg6AGZFh1NxnsB34ETJHUcC2h71oT9dno2IT7UwWYNpydspZB0Qse8K5k1g07pPk5oKqlQvAgGH7N8Z)

Clicking on each link will take you to the corresponding menu. Now let’s add feature flags.

## Create a Feature Flag with Split

The first thing we need to do is create a feature flag from the Split UI. Once you log in, click on Create Split.

![](https://lh3.googleusercontent.com/Sd9Si4e0NP1n74MSNZezAhkRxnJqeSmnB1lcjqgkOYWtO5VBoz06Z5_y6EKMJWBoBoWmxcu4o_IeXb71PiY0-b9rHgm-R7uL3VKfYSfD18HMKsh1Dq3EDOjC8JPw8D73LqiW-lpC)

![](https://lh6.googleusercontent.com/_8eC9EbwaIhiao5sZPYzwph9OLK0_FzOIdAopJHe2Io2vQJIPB483JoF0Xt7SYES0KE2R9P8BjC4P2bpGO9W1u0n0wBew4cybXZ_MVASch0MMp3UvYNG43M-c8Fkyx8nvn3Qa8V6)

Next, Click on Add Rules. Here, you will define the different treatments of your feature flag. I am going to define treatment on and treatment off. If the treatment is on for the current user, they will have access to the menu app. If the treatment is off, they will not have access.

![](https://lh4.googleusercontent.com/zkLc2tjwSJ3DtTMZJJ7mxG2OKLV4o-i7DA676_-OkXt_OChTr3vT70yH-t3K4iHiISedvgeDff-qPJxo9XA2eJymwfDIUJcbQn4EmSfkBFGrCIuIzteeWu-2MsaGYJC_bywWwVqJ)

Next, we need to target the specific users who _should_ have access to the app, at least initially, me.

![](https://lh6.googleusercontent.com/4k1l7n0DKtJCTIb7W56Cxx5s7-0AZdG8V922U9C0OOtrxm3fJBalw5edt_d-fH6Q8aNRaGh96b_fMkU_bDSTBFz_0Qf8RuCzkt1DhF_yQ5B8U902QDLGo1pz_SN7OMLqkyAntGPN)

For everyone else who is not in that list, they will get the default treatment of off because the default rule is off.

![](https://lh6.googleusercontent.com/hBYRWahwea_HqPf2mMz09wq-m_bkKykkNw90MAKJsOSkxWREJtIrhmACaW6WMQ3PS5ikV9_aC58RoaAAOSzxoiQHGwkCGjJtBeQfIksMlGhrZx83nuG3ZfqDVAY7jvjjQX8c0nI2)

## Instantiate and Use the Python SDK

In your root folder, import the Python SDK using pip.

`pip install splitio_client[cpphash]`==8.3.0

Then, in your `app.py` file, import the following:

`from splitio.exceptions import TimeoutException`

`from splitio import get_factory`

Now we will instantiate the SDK and create a new Split client (still in `app.py`):

`factory = get_factory('YOUR_API_KEY')`

_`try`_:

`   factory.block_until_ready(5)  # wait up to 5 seconds`

`except TimeoutException:`

   _`pass`_

To find your API key, go to the Syntax tab of your split, and then select Python as the language.

![](https://lh5.googleusercontent.com/1dulcdYK2QXIlPDnhhsqCvbMF_Jl0ZtdsPNW9MgiGcDJAGlcs9cq3JhjgICllr489Mun7uiNh6uNeFNTFU9NWu_BAanPUV0GxbjHu9kkphl54kZRPh8ut3K4prEW3rGKLzu3BViT)

In our `index` function, let’s create a Split client and treatment. In the `get_treatment` call, you will have two parameters: who the current user is and the name of the split. Then, you need to add our if/else statement to differentiate the different views. Since I only added my name to the targeting rules in the Split UI, only I should be able to see the menus. If someone who is not targeted while the flag is off tries to see the app, you need to create an error page. In your templates folder, create a new file called error.html and add an error message.

```

`<!DOCTYPE html>
<html lang="en">
<head>
   <meta charset="UTF-8">
   <meta name="viewport" content="width=device-width, initial-scale=1.0">
   <title>Document</title>
</head>
<body>
   <h2>Error</h2>
</body>
</html>`
<small id="shcb-language-4"><span>Code language:</span> <span>Django</span> <span>(</span><span>django</span><span>)</span></small>
```

Now, in our index function, we can add this template.

```

`@app.route("/")
def index():
   client = factory.client()
   treatment = client.get_treatment(
       'talia.nassi@split.io', 'the_queens_gambit_menu')
   if treatment == 'on':
       return render_template('index.html')
   else:
       return render_template('error.html')`
<small id="shcb-language-5"><span>Code language:</span> <span>Scala</span> <span>(</span><span>scala</span><span>)</span></small>
```

Here, we are telling Split that I am the current user, and treatment should be on for me. Let’s run the app and see what happens.

![](https://lh4.googleusercontent.com/WEsaWc0qBlinrOCfGmtcYmCS6DNSPfAmVxh2s-xVFlcyREYaPnxMB-99uMG3ox-Ny3zILuaGaKr-mX-fbu6S6XeLCrORQHGjQYdlYoGzRHJgWTXciGrba0jnUaUgrKmAyNUm9otT)

I can see the app!

Now, let’s change the targeted user to someone who should not have access (i.e., anyone else).

```

`@app.route("/")
def index():
   client = factory.client()
   treatment = client.get_treatment(
       'test@split.io', 'the_queens_gambit_menu')
   if treatment == 'on':
       return render_template('index.html')
   else:
       return render_template('error.html')
`
<small id="shcb-language-6"><span>Code language:</span> <span>Scala</span> <span>(</span><span>scala</span><span>)</span></small>
```

![](https://lh5.googleusercontent.com/RxoT4y9i_Vx9Kmhle5k-a-Dt-kCHaIIkBv-XL3A0fp9_puVyKTNBGVP3CtBu5xnGtcVZh4RsnsUjAL1ZMEiuPeU0HQwh126aG9OLnb2rBhsxu9jV_dzwiXpdRVqJBUHH3eFceIVO)

The test user does not see our app because they are not targeted.

For the full repo and more examples with feature flags, check out our examples [repo](https://github.com/talianassi921/python-flask-app).

## Improve Your Flask Apps with Feature Flags

Now that you have feature flags implemented, the possibilities are endless! You can [test your code in production](https://www.split.io/blog/how-to-implement-testing-in-production/), make sure it works, and then turn on the flag for your end-users. You can also release your app through a [canary release](https://www.split.io/blog/to-canary-release-or-not-to-canary-release/), or percentage rollout, where only a small percentage of your user base has access to the app to mitigate risk in case something goes wrong. With feature flags, you have full control over your app, and Split makes it easy to implement! 

## Build More Apps with Feature Flags

Feature flags are foundational to engineering. We at Split love building apps in all different languages and frameworks!

- [Build a CRUD App with Spring Boot and React in 20 Minutes](https://www.split.io/blog/tutorial-spring-boot-react/)
- [Build a CRUD App with Spring Boot and MongoDB](https://www.split.io/blog/crud-spring-boot-mongodb/)
- [How to Branch by Abstraction with Feature Flags](https://www.split.io/blog/branch-by-abstraction/)

To stay up to date with all of our content, be sure to [follow us on Twitter](https://twitter.com/SplitSoftware) and [subscribe to our Youtube Channel](https://www.youtube.com/channel/UCrkFMZZY8cjmZyKzOVV245Q/videos)!