A Flask extension that enables or disables features based on configuration.

Overview

Flask FeatureFlags

PyPI version Build Status Coverage Status

This is a Flask extension that adds feature flagging to your applications. This lets you turn parts of your site on or off based on configuration.

It's useful for any setup where you deploy from trunk but want to hide unfinished features from your users, such as continuous integration builds.

You can also extend it to do simple a/b testing or whitelisting.

Installation

Installation is easy with pip:

pip install flask_featureflags

To install from source, download the source code, then run this:

python setup.py install

Flask-FeatureFlags supports Python 2.6, 2.7, and 3.3+ with experimental support for PyPy.

Version 0.1 of Flask-FeatureFlags supports Python 2.5 (but not Python 3), so use that version if you need it. Be aware that both Flask and Jinja have dropped support for Python 2.5.

Docs

For the most complete and up-to-date documentation, please see: https://flask-featureflags.readthedocs.org/en/latest/

Setup

Adding the extension is simple:

from flask import Flask
from flask_featureflags import FeatureFlag

app = Flask(__name__)

feature_flags = FeatureFlag(app)

In your Flask app.config, create a FEATURE_FLAGS dictionary, and add any features you want as keys. Any UTF-8 string is a valid feature name.

For example, to have 'unfinished_feature' hidden in production but active in development:

class ProductionConfig(Config):

    FEATURE_FLAGS = {
        'unfinished_feature' : False,
    }


class DevelopmentConfig(Config):

    FEATURE_FLAGS = {
      'unfinished_feature' : True,
    }

Note: If a feature flag is used in code but not defined in FEATURE_FLAGS, it's assumed to be off. Beware of typos.

If you want your app to throw an exception in dev when a feature flag is used in code but not defined, add this to your configuration:

RAISE_ERROR_ON_MISSING_FEATURES = True

If app.debug=True, this will throw a KeyError instead of silently ignoring the error.

Usage

Controllers/Views

If you want to protect an entire view:

from flask import Flask
import flask_featureflags as feature

@feature.is_active_feature('unfinished_feature', redirect_to='/old/url')
def index():
  # unfinished view code here

The redirect_to parameter is optional. If you don't specify, the url will return a 404.

If your needs are more complicated, you can check inside the view:

from flask import Flask
import flask_featureflags as feature

def index():
    if feature.is_active('unfinished_feature') and some_other_condition():
        # do new stuff
    else:
        # do old stuff

Templates

You can also check for features in Jinja template code:

{% if 'unfinished_feature' is active_feature %}
    new behavior here!
{% else %}
    old behavior...
{% endif %}

Using other backends

Want to store your flags somewhere other than the config file? There are third-party contrib modules for other backends.

Please see the documentation here: https://flask-featureflags.readthedocs.org/en/latest/contrib.html

Feel free to add your own - see CONTRIBUTING.rst for help.

Customization

If you need custom behavior, you can write your own feature flag handler.

A feature flag handler is simply a function that takes the feature name as input, and returns True (the feature is on) or False (the feature is off).

For example, if you want to enable features on Tuesdays:

from datetime import date

def is_it_tuesday(feature):
  return date.today().weekday() == 2:

You can register the handler like so:

from flask import Flask
from flask_featureflags import FeatureFlag

app = Flask(__name__)

feature_flags = FeatureFlag(app)
feature_flags.add_handler(is_it_tuesday)

If you want to remove a handler for any reason, simply do:

feature_flags.remove_handler(is_it_tuesday)

If you try to remove a handler that was never added, the code will silently ignore you.

To clear all handlers (thus effectively turning all features off):

feature_flags.clear_handlers()

Clearing handlers is also useful when you want to remove the built-in behavior of checking the FEATURE_FLAGS dictionary.

To enable all features on Tuesdays, no matter what the FEATURE_FLAGS setting says:

from flask import Flask
from flask_featureflags import FeatureFlag

app = Flask(__name__)

feature_flags = FeatureFlag(app)
feature_flags.clear_handlers()
feature_flags.add_handler(is_it_tuesday)

Chaining multiple handlers

You can define multiple handlers. If any of them return true, the feature is considered on.

For example, if you want features to be enabled on Tuesdays or Fridays:

feature_flags.add_handler(is_it_tuesday)
feature_flags.add_handler(is_it_friday)

Important: the order of handlers matters! The first handler to return True stops the chain. So given the above example, if it's Tuesday, is_it_tuesday will return True and is_it_friday will not run.

You can override this behavior by raising the StopCheckingFeatureFlags exception in your custom handler:

from flask_featureflags import StopCheckingFeatureFlags

def run_only_on_tuesdays(feature):
  if date.today().weekday() == 2:
    return True
  else:
    raise StopCheckingFeatureFlags

If it isn't Tuesday, this will cause the chain to return False and any other handlers won't run.

Acknowledgements

A big thank you to LinkedIn for letting me opensource this, and for my coworkers for all their feedback on this project. You guys are great. :)

Questions?

Feel free to ping me on twitter @trustrachel or on the Github project page.

Comments
  • add flask_featureflags.contrib sub package in install script

    add flask_featureflags.contrib sub package in install script

    This changeset fixes the installed packages. Previously, flask_featureflags.contrib sub packages (including inline and sqlalchemy) were not installed through pip install flask-featureflags.

    opened by iromli 6
  • Signal for missing keys

    Signal for missing keys

    I want to add the key to my sqlalchemy database if it does not exist in any other handler. I can listen to some flask signal in this case to do that.

    Is it a good idea? I can work on it, but maybe others have better ideas about how to handle it.

    opened by iurisilvio 5
  • Update __init__.py to fix ExtDeprecationWarning

    Update __init__.py to fix ExtDeprecationWarning

    This is the fix the following warning which happens whenever the module is loaded: ExtDeprecationWarning: Importing flask.ext.featureflags is deprecated, use flask_featureflags instead. from flask.ext.featureflags import NoFeatureFlagFound, log

    opened by Naishy 3
  • Add contrib modules to setup.py

    Add contrib modules to setup.py

    Was trying to use InlineFeatureFlag (as described here), but found that the contrib modules weren't being included. Small change to setup.py fixes it.

    opened by pcraig3 3
  • SQLAlchemy handler

    SQLAlchemy handler

    My proposal to make an SQLAlchemy handler.

    You just need a SQLAlchemy instance (from Flask-SQLAlchemy extension) and a check method in the model.

    from flask import Flask
    from flask.ext.sqlalchemy import SQLAlchemy
    from flask.ext.featureflags import FeatureFlag
    from flask.ext.featureflags.contrib.sqlalchemy import SQLAlchemyFeatureFlags
    
    app = Flask(__name__)
    db = SQLAlchemy(app)
    handler = SQLAlchemyFeatureFlags(db)
    
    ff = FeatureFlag(app)
    ff.add_handlers(handler)
    
    opened by iurisilvio 3
  • Feature flag application backend

    Feature flag application backend

    As a fellow lover of python and flask, and having written a feature-switching backend application with an administrative UI, I would like to contribute an integration between the two. Is that something you'd be interested in?

    https://github.com/giftig/flippy

    I was actually inspired by gargoyle / django-gargoule when writing flippy, which worked very similarly to your lib.

    I'm genuinely not sure why I've never written my own python connector to it.

    opened by giftig 2
  • consistent version in __init__.py and setup.py

    consistent version in __init__.py and setup.py

    Previously, flask_featureflags.__version__ is set to 0.4dev while setup.py is set to 0.7-dev. This changeset ensures consistent version found in flask_featureflags.__version__ and setup.py.

    You can check the version in Python shell:

    >>> import flask_featureflags
    >>> print(flask_featureflags.__version__)
    0.7-dev
    

    and using pip freeze:

    $ pip freeze | grep FeatureFlags
    Flask-FeatureFlags==0.7.dev0
    
    opened by iromli 2
  • Add custom handler to add inline feature flags

    Add custom handler to add inline feature flags

    The changesets introduce custom handler for inline feature flags.

    One notable difference is, instead of specifying feature flags in dict-style:

    FEATURE_FLAGS = {
        "finished": False,
    }
    

    the flag must be written in uppercased plain string with FEATURE_FLAGS_X where X is the feature name:

    FEATURE_FLAGS_FINISHED = False
    

    The motivation behind this custom handler is to interopt with other Flask extensions, e.g. Flask-AppConfig.

    opened by iromli 2
  • Adding route definition to example

    Adding route definition to example

    This tripped me up a bit, so thought explicitly stating the order of decorators could help.

    This works (404s):

    @app.route('/feature-flag-test-route')
    @is_active_feature('test_route')
    def feature_flag_test_route():
        return 'on!'
    

    This does not (returns 200, displays 'on!')

    @is_active_feature('test_route')
    @app.route('/feature-flag-test-route')
    def feature_flag_test_route():
        return 'on!'
    
    opened by jskulski 1
  • Raise NoFeatureFlagFound instead of handle missing flags

    Raise NoFeatureFlagFound instead of handle missing flags

    The handler is not responsible to handle the feature flag missing. I expect the KeyError only if it was not found in any handler.

    The current implementation works for only one handler.

    This is my first step to create a custom handler. I want to make the core responsible for missing keys.

    I'm not sure about the exception name. Django use DoesNotExist, SQLAlchemy use NoResultFound, but I tried FeatureFlagNotFound, NotFound, FeatureNotFound and others.

    opened by iurisilvio 1
  • Add argument redirect (optional) to is_active_feature

    Add argument redirect (optional) to is_active_feature

    It's not possible to use url_for() in the decorator call if the app context is not build yet. Therefore this patch adds a new optional argument named redirect to is_active_feature. It's the same as redirect_to but it triggers url_for() right before the redirect.

    opened by michaelcontento 1
  • Fix imports to remove warning per Flask recommendation.

    Fix imports to remove warning per Flask recommendation.

    Flask no longer recommend using the "flask.ext." import style; this change eliminates the warning currently generated by flask when using this extension.

    http://flask.pocoo.org/docs/0.12/extensiondev/#extension-import-transition

    (The 0.12 docs are somewhat contradictory on this, but the confusing text seems to have been removed in the latest dev docs.)

    opened by galund 1
Releases(0.6)
  • 0.6(Jun 10, 2015)

  • 0.5.1(Oct 13, 2014)

    Adding the ability to have feature flags inline instead of in a dictionary, to make it easier to interoperate with other Flask extensions, e.g. Flask-AppConfig.

    A big thank you to Isman Firmansyah (@iromli) for the contribution!

    Source code(tar.gz)
    Source code(zip)
  • 0.5(Aug 7, 2014)

    Official support for contributed modules, thank you to iurisilvio! He contributed the first for SQLAlchemy, so you can store your flags in the database instead.

    Contributions for other storage backends welcome!

    Source code(tar.gz)
    Source code(zip)
  • 0.4(Apr 8, 2014)

    • General code cleanup, modernization and optimization
    • Adding optional redirect to is_active_feature, thank you to michaelcontento
    • Fixed syntax error in docs, thank you to iurisilvio
    Source code(tar.gz)
    Source code(zip)
Owner
Rachel Greenfield
Currently funlancing, Previously Stripe, LinkedIn
Rachel Greenfield
Search users in Github. Created with Flask, PipEnv, Heroku and free time.

Search in Github Here search for users in Github and other stuff! This app is working with, Data Github API BackEnd Flask Language Python Package mana

AmirHossein Mohammadi 12 Jan 16, 2022
Track requests to your Flask website with Matomo

Flask-Matomo Flask-Matomo is a library which lets you track the requests of your Flask website using Matomo (Piwik). Installation pip install flask-ma

Lucas Hild 13 Jul 14, 2022
Quick and simple security for Flask applications

Note This project is non maintained anymore. Consider the Flask-Security-Too project as an alternative. Flask-Security It quickly adds security featur

Matt Wright 1.6k Dec 19, 2022
Are-You-OK is a Flask-based, responsive Web App to monitor whether the Internet Service you care about is still working.

Are-You-OK Are-You-OK is a Flask-based, responsive Web App to monitor whether the Internet Service you care about is still working. Demo-Preview Get S

Tim Qiu 1 Oct 28, 2021
Flask-Discord-Bot-Dashboard - A simple discord Bot dashboard created in Flask Python

Flask-Discord-Bot-Dashboard A simple discord Bot dashboard created in Flask Pyth

Ethan 8 Dec 22, 2022
RestApi_flask_sql.alchemy - Product REST API With Flask & SQL Alchemy

REST API With Flask & SQL Alchemy Products API using Python Flask, SQL Alchemy and Marshmallow Quick Start Using Pipenv # Activate venv $ pipenv shell

amirwahla 1 Jan 01, 2022
An Instagram Clone using Flask, Python, Redux, Thunk, React

An Instagram Clone using Flask, Python, Redux, Thunk, React

1 Dec 09, 2021
A boilerplate Flask API for a Fullstack Project :rocket:

Flask Boilerplate to quickly get started with production grade flask application with some additional packages and configuration prebuilt.

Yasser Tahiri 32 Dec 24, 2022
A YouTube webscraper made with flask.

YouTube Webscraper This website is for you to check all the stats on your favorite Youtube video! Technologies Python Flask HTML CSS Pafy Contributing

Proconsulates 3 Nov 25, 2021
A flask template with Bootstrap 4, asset bundling+minification with webpack, starter templates, and registration/authentication. For use with cookiecutter.

cookiecutter-flask A Flask template for cookiecutter. (Supports Python ≥ 3.6) See this repo for an example project generated from the most recent vers

4.3k Dec 29, 2022
A template themes for phyton flask website

Flask Phyton Web template A template themes for phyton flask website

Mesin Kasir 2 Nov 29, 2021
É uma API feita em Python e Flask que pesquisa informações em uma tabela .xlsx e retorna o resultado.

API de rastreamento de pacotes É uma API feita em Python e Flask que pesquisa informações de rastreamento de pacotes em uma tabela .xlsx e retorna o r

Marcos Beraldo Barros 4 Jun 27, 2021
SeCl - A really easy to deploy and use made-on Flask API to manage your files remotely from Terminal

SeCl SeCl it's a really easy to deploy and use made-on Flask API to manage your

ZSendokame 3 Jan 15, 2022
Python3🐍 webApp to display your current playing music on OBS Studio.

Spotify Overlay A Overlay to display on Obs Studio or any related video/stream recorder, the current music that is playing on your Spotify. Installati

carlitos 0 Oct 17, 2022
PatientDB is a flask app to store patient information.

PatientDB PatientDB on Heroku "PatientDB is a simple web app that stores patient information, able to edit the information, and able to query the data

rbb 2 Jan 31, 2022
Full-Stack application that visualizes amusement park safety.

Amusement Park Ride Safety Analysis Project Proposal We have chosen to look into amusement park data to explore ride safety relationships visually, in

Michael Absher 0 Jul 11, 2021
Flask 文档中文翻译

Flask 中文文档 这里是 Flask 文档中文翻译项目,欢迎参与! 在开始翻译之前,请务必阅读下面的 Contributing Guide 了解贡献流程,然后阅读这个 Issue 了解翻译要求,在这个 Discussion 投票选出你认为合适的翻译词汇,在这个 Discussion 投票选出你喜

Grey Li 93 Nov 28, 2022
A simple web application built using python flask. It can be used to scan SMEVai accounts for broken pages.

smescan A simple web application built using python flask. It can be used to scan SMEVai accounts for broken pages. Development Process Step 0: Clone

Abu Hurayra 1 Jan 30, 2022
Sample Dockerized flask app deployed on Kubernetes on Azure using AKS

Sample Dockerized flask app deployed on Kubernetes on Azure using AKS

Ahmed khémiri 22 Sep 08, 2021
Socket.IO integration for Flask applications.

Flask-SocketIO Socket.IO integration for Flask applications. Installation You can install this package as usual with pip: pip install flask-socketio

Miguel Grinberg 4.9k Jan 02, 2023