How to Use Multiple Feature Flags in Your LaunchDarkly Flask App featured image

Feature flags are a nifty tool to help developers build and change configurations at runtime. You might be a web developer looking for ways to test out a webpage design. Instead of killing the process and rerunning the application each time, or commenting out frontend designs, consider using a feature flag to test out different themes for your site. 

It is also a great way to share the website design in real time to different groups of users and gather feedback before you choose the design you want. 


In this tutorial, you will learn how to create a quick Flask application that tests out two feature flags on a webpage that can hide or display gifs, images, or audio files. The example in this article is inspired by the song “Maps” by the Yeah Yeah Yeahs.

Tutorial requirements

  • Python 3.6 or newer. If your operating system does not provide a Python interpreter, you can go to python.org to download an installer.
  • Visual Studio Code or your favorite IDE. 

LaunchDarkly account. If you haven’t done so already, create a free account.

Create a feature flag

In the LaunchDarkly app, create a feature flag with the following configuration:

  • Flag name: “animate-gif”
  • Configuration: Custom
  • Flag type: Boolean
  • Variants: animate file - true
  • Variants: static file - false
  • Serve when targeting is ON: animate file
  • Serve when targeting is OFF: static file

Screenshot demonstrating feature flag configuration UI.

Configuration

If you are using a Unix or Mac OS system, open a terminal and enter the following commands to do the tasks described below:

$ mkdir dancingflag
$ cd dancingflag
$ python3 -m venv venv
$ source venv/bin/activate
(venv) $ pip install flask python-dotenv launchdarkly-server-sdk

For those of you following the tutorial on Windows, enter the following commands in a command prompt window:

$ md dancingflag
$ cd dancingflag
$ python -m venv venv
$ venv\Scripts\activate
(venv) $ pip install flask python-dotenv launchdarkly-server-sdk

The last command uses pip, the Python package installer, to install the five packages that we are going to use in this project, which are:

The LaunchDarkly SDK to initiate and activate feature flags on the server.

Set up the developer environment for the Flask application

Make sure that you are currently in the virtual environment of your project’s directory in the terminal or command prompt. 

Create a file named .env and add the following line to define the environment variable.

LAUNCHDARKLY_SDK_KEY="sdk-###############"

Navigate to the Organizations settings / Projects dashboard page to locate a list of projects in your account. Find the project you created your initial flag in.

On the General page, select Environments.

Screenshot showing general project settings in the LaunchDarkly app UI.

Find the Test section and click on the “...” to find your SDK key. Copy the SDK key into your .env file. Save the file.

Screenshot demonstrating where to copy the SDK key from the LaunchDarkly app UI, in a Test environment.

Since we will be utilizing Flask throughout the project, we will need to set up the development server. Add a .flaskenv file (make sure you have the leading dot) to your project with the following lines:

FLASK_APP=app.py
FLASK_ENV=development

FLASK_APP tells the Flask framework where our application is located.

FLASK_ENV configures Flask to run in debug mode.

These lines are convenient because every time you save the source file, the server will reload and reflect the changes.

Build the Flask application to add more feature flags 

Create a new file named main.py in the dancingflag project folder so that it can run a functional Flask application. Add the import statements below:

from flask import Flask, render_template
import os
import ldclient
from ldclient import Context
from ldclient.config import Config
from threading import Lock, Event

app = Flask(__name__)

from dotenv import load_dotenv
load_dotenv()

Create a route to render a homepage on the Flask application under the LaunchDarkly initialization

# Set sdk_key to your LaunchDarkly SDK key.
sdk_key = os.getenv("LAUNCHDARKLY_SDK_KEY")

# Set feature_dance_flag_key to the feature flag key you want to evaluate.
feature_dance_flag_key = "animate-gif"

# this is printed in the terminal 
def show_evaluation_result(key: str, value: bool):
    print()
    print(f"*** The {key} feature flag evaluates to {value}")

@app.route("/")
def home():
    # Set up the evaluation context
    context = Context.builder("example-user-key").kind("user").name("Sandy").build()

    # Check the value of the feature flag
    dance_flag_value = ldclient.get().variation(feature_dance_flag_key, context, False)

    # Render different templates based on the flag value
    if dance_flag_value:
        return render_template("dance.html")
    else:
        return render_template("wait.html")

Contexts are defined and passed through at the time of initiating the SDK after login. This process determines how feature flags should behave for a specific user or entity. 

The "example-user-key" is the unique identifier for the context that ensures that the flag evaluations are consistent for the same user or entity across sessions.

The “kind” attribute is set to “user” to represent an individual user, who is named “Sandy” in this case. It is optional to change the name for personal debugging and viewing purposes.

Set up the HTML Flask page

Create a new subdirectory in the application named “templates” with two new HTML files: dance.html and wait.html. 


If the “dance_flag_value” is set to true, then our character Lain is ready to dance on the dance.html page. Copy this code into dance.html.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Lain Dancing</title>
</head>
<body>
    <h1>They don't love you like I love you 💃</h1>
    <img src="https://media1.tenor.com/m/O8k-DvUjaeEAAAAd/lain-dance.gif" alt="Dancing Lain">
    <br>
</body>
</html>

Modify the wait.html file with the following code:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Lain Waiting</title>
</head>
<body>
    <h1>WAIT 😲✋🏻</h1>
    <p>Turn on the flag to see Lain dance.</p>
       <img src="{{ url_for('static', filename='lain.jpg') }}" alt="Lain" />
</body>
</html>

Create a new subdirectory in the root folder named “static” to store the static image of Lain that is rendered in wait.html

Download the image from the GitHub repository and add it to the “static” folder. 

Great, it’s time to flip the switch and see the feature flags in action.

Initialize the Python script 

Copy this code into main.py to define the main script for the Python interpreter, launch the LaunchDarkly SDK, and put the feature flags in action: 

if __name__ == "__main__":
    if not sdk_key:
        print("*** Please set the LAUNCHDARKLY_SDK_KEY env first")
        exit()
    if not feature_dance_flag_key:
        print("*** Please set the LAUNCHDARKLY_FLAG_KEY env first")
        exit()

    ldclient.set_config(Config(sdk_key))

    if not ldclient.get().is_initialized():
        print("*** SDK failed to initialize. Please check your internet connection and SDK credential for any typo.")
        exit()

    print("*** SDK successfully initialized")

    # Set up the evaluation context. 
    context = \
        Context.builder('example-user-key').kind('user').name('Sandy').build()

    # Check the value of the feature flag.

    dance_flag_value = ldclient.get().variation(feature_dance_flag_key, context, False)

    show_evaluation_result(feature_dance_flag_key, dance_flag_value)
    
    try:
        app.run(debug=True)
        Event().wait()
    except KeyboardInterrupt:
        pass

Python will first check if the SDK key is set in the environment before it can initialize the client. 

The object named “dance_flag_value” is used to evaluate the “animate-gif” flag that was defined and displayed in the LaunchDarkly dashboard. To assist with the debugging process, the evaluation result will be deployed on the terminal to indicate the status of the feature flag value.

Navigate the feature flag dashboard on LaunchDarkly 

In order to change the flag to false, navigate to the flags dashboard. Click on the feature flag name “animate-gif” to be redirected to the “Targeting” section. Notice that the toggle is already set to “Off” to serve a static file and that the default rule is to serve animate file, which is true.

In your terminal, run “python3 main.py”. 


Go to http://localhost:5000/ and notice that Lain, or the gif, is not moving. She’s waiting for the cue to dance.

Still shot from the anime series Lain. Lain has brown hair and is wearing a pink jacket, black shirt, red skirt, red boots. She is listening with her head cocked to one side. Above the image, the text "WAIT. Turn the flag on to see Lain dance."

Navigate back in the dashboard, toggle the flag “On” and click the Review and save button to see the screenshot below:

Screenshot showing confirmation modal for changing flag state in the LaunchDarkly app UI.

Save changes. Kill the process running on the terminal and restart the app with “python3 main.py”. Go back to http://localhost:5000/ and notice that Lain, or the gif, is activated!

Animated gif from the animated series Lain. A girl with brown hair dancing.

Create another flag from the LaunchDarkly dashboard

Click on the blue + Create button. Give the new flag a name such as “musicflag” and a description “activate audio file” as seen below:

Screenshot demonstrating configuration for a feature flag to hide or display an audio file embedded in a web page.

Specify the flag’s configuration as:

  • Configuration: Custom
  • Temporary: Yes
  • Flag type: Boolean
  • Variations: display audio file - true
  • Variations: hide audio file - false 
  • Serve when targeting is ON: display audio file
  • Serve when targeting is OFF: hide audio file

Add the new flag to the Python Flask app 

Navigate back to the main.py file and add the new flag to the file so that the code matches the snippet below:

feature_dance_flag_key = "animate-gif"
feature_music_flag_key = "musicflag"

@app.route("/")
def home():
    # Set up the evaluation context
    context = Context.builder("example-user-key").kind("user").name("Sandy").build()

    # Check the value of the feature flag
    dance_flag_value = ldclient.get().variation(feature_dance_flag_key, context, False)
    music_flag_value = ldclient.get().variation(feature_music_flag_key, context, False)

    # Render different templates based on the flag value
    if dance_flag_value is True and music_flag_value is False:
        return render_template("dance.html")
    if dance_flag_value is True and music_flag_value is True:
        return render_template("dance.html", playmusic = True)
    else:
        return render_template("wait.html")

Scroll down to the Python script and add these objects at the end to evaluate the values and results.

    dance_flag_value = ldclient.get().variation(feature_dance_flag_key, context, False)
    music_flag_value = ldclient.get().variation(feature_music_flag_key, context, False)

    show_evaluation_result(feature_dance_flag_key, dance_flag_value)
    show_evaluation_result(feature_music_flag_key, music_flag_value)

There are now two cases. If the dance flag is set to true and the music flag is false, then our character Lain will only be dancing without music. However, if both flags are set to true, than an audio player will appear

Add the audio and video to the Flask webpage

Let’s allow our character Lain to dance to music. Download the mp3 from GitHub and save it in the static folder of your project.


Add the following HTML snippet to the dance.html file under the gif.

    {% if playmusic %}
    <p>playmusic is true</p>
   <audio controls autoplay>
      <source
        src="{{ url_for('static', filename='audio.mp3') }}"
        type="audio/mpeg"
      />
      Your browser does not support the audio element.
    </audio>
    {% endif %}

Since all new flags are automatically set to OFF, go back to the dashboard and make sure both flags are set to true. Time to turn the music ON!

Confirmation modal to enable the flag and let the music blast.

Refresh the page and you should see the Lain dancing gif as well as an option to play some music.

Screenshot of the Lain image, plus an embedded audio player on a web page.

Hit the play button for some background music while enjoying this gif. Feel free to toggle the music flag off to turn the music off if you want to kill the party. 

Notice the flag change in the terminal.

Screenshot of Flask server log output from the terminal, confirming the state of both feature flags.

What’s next for building Flask applications with feature flags? 

Incorporating feature flags for your next Flask application is not only a great tool to have under your belt, but it can be fun to add it to a website and see how different assets can be rendered on the site. Challenge yourself by adding more flags to toggle new site UI designs. Perhaps test out the Flask application across various devices such as your mobile phone or tablet to see how it can change dynamically. 

Consider building your next project with FastAPI and using LaunchDarkly to upgrade your APIs safely with progressive rollouts. It’s always great to explore a fun API such as the Star Wars API and build another creative project.


Join us on Discord or send me an email at dphan@launchdarkly.com, or connect with me on LinkedIn and let us know what you're building.

Like what you read?
Get a demo
Related Content
February 1, 2025