{ "info": { "author": "Rachel Sanders", "author_email": "rachel@trustrachel.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 3 - Alpha", "Environment :: Web Environment", "Intended Audience :: Developers", "License :: OSI Approved :: Apache Software License", "Operating System :: OS Independent", "Programming Language :: Python", "Topic :: Internet :: WWW/HTTP :: Dynamic Content", "Topic :: Software Development :: Libraries :: Python Modules" ], "description": "Flask FeatureFlags\n===================\n\n[![PyPI version](https://badge.fury.io/py/Flask_Featureflags.svg)](http://badge.fury.io/py/Flask_Featureflags) [![Build Status](https://travis-ci.org/trustrachel/Flask-FeatureFlags.png)](https://travis-ci.org/trustrachel/Flask-FeatureFlags) [![Coverage Status](https://coveralls.io/repos/trustrachel/Flask-FeatureFlags/badge.png?branch=master)](https://coveralls.io/r/trustrachel/Flask-FeatureFlags?branch=master)\n\nThis 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.\n\nIt's useful for any setup where you deploy from trunk but want to hide unfinished features from your users, such as continuous integration builds.\n\nYou can also extend it to do simple a/b testing or whitelisting.\n\nInstallation\n============\n\nInstallation is easy with pip:\n\n pip install flask_featureflags\n\nTo install from source, download the source code, then run this:\n\n python setup.py install\n\nFlask-FeatureFlags supports Python 2.6, 2.7, and 3.3+ with experimental support for PyPy.\n\nVersion 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.\n\nDocs\n====\n\nFor the most complete and up-to-date documentation, please see: [https://flask-featureflags.readthedocs.org/en/latest/](https://flask-featureflags.readthedocs.org/en/latest/) \n\nSetup\n=====\n\nAdding the extension is simple:\n\n from flask import Flask\n from flask_featureflags import FeatureFlag\n\n app = Flask(__name__)\n\n feature_flags = FeatureFlag(app)\n\nIn 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.\n\nFor example, to have 'unfinished_feature' hidden in production but active in development:\n\n class ProductionConfig(Config):\n\n FEATURE_FLAGS = {\n 'unfinished_feature' : False,\n }\n\n\n class DevelopmentConfig(Config):\n\n FEATURE_FLAGS = {\n 'unfinished_feature' : True,\n }\n\n**Note**: If a feature flag is used in code but not defined in ``FEATURE_FLAGS``, it's assumed to be off. Beware of typos.\n\nIf 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:\n\n RAISE_ERROR_ON_MISSING_FEATURES = True\n\nIf ``app.debug=True``, this will throw a ``KeyError`` instead of silently ignoring the error.\n\nUsage\n=====\n\nControllers/Views\n-----------------\n\nIf you want to protect an entire view:\n\n from flask import Flask\n import flask_featureflags as feature\n\n @feature.is_active_feature('unfinished_feature', redirect_to='/old/url')\n def index():\n # unfinished view code here\n\nThe redirect_to parameter is optional. If you don't specify, the url will return a 404.\n\nIf your needs are more complicated, you can check inside the view:\n\n from flask import Flask\n import flask_featureflags as feature\n\n def index():\n if feature.is_active('unfinished_feature') and some_other_condition():\n # do new stuff\n else:\n # do old stuff\n\nTemplates\n---------\n\nYou can also check for features in Jinja template code:\n\n {% if 'unfinished_feature' is active_feature %}\n new behavior here!\n {% else %}\n old behavior...\n {% endif %}\n\nUsing other backends\n====================\n\nWant to store your flags somewhere other than the config file? There are third-party contrib modules for other backends.\n\nPlease see the documentation here: [https://flask-featureflags.readthedocs.org/en/latest/contrib.html](https://flask-featureflags.readthedocs.org/en/latest/contrib.html)\n\nFeel free to add your own - see CONTRIBUTING.rst for help.\n\nCustomization\n=============\n\nIf you need custom behavior, you can write your own feature flag handler.\n\nA 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).\n\nFor example, if you want to enable features on Tuesdays:\n\n from datetime import date\n\n def is_it_tuesday(feature):\n return date.today().weekday() == 2:\n\nYou can register the handler like so:\n\n from flask import Flask\n from flask_featureflags import FeatureFlag\n\n app = Flask(__name__)\n\n feature_flags = FeatureFlag(app)\n feature_flags.add_handler(is_it_tuesday)\n\nIf you want to remove a handler for any reason, simply do:\n\n feature_flags.remove_handler(is_it_tuesday)\n\nIf you try to remove a handler that was never added, the code will silently ignore you.\n\nTo clear all handlers (thus effectively turning all features off):\n\n feature_flags.clear_handlers()\n\nClearing handlers is also useful when you want to remove the built-in behavior of checking the ``FEATURE_FLAGS`` dictionary.\n\nTo enable all features on Tuesdays, no matter what the ``FEATURE_FLAGS`` setting says:\n\n from flask import Flask\n from flask_featureflags import FeatureFlag\n\n app = Flask(__name__)\n\n feature_flags = FeatureFlag(app)\n feature_flags.clear_handlers()\n feature_flags.add_handler(is_it_tuesday)\n\n\nChaining multiple handlers\n--------------------------\n\nYou can define multiple handlers. If any of them return true, the feature is considered on.\n\nFor example, if you want features to be enabled on Tuesdays *or* Fridays:\n\n feature_flags.add_handler(is_it_tuesday)\n feature_flags.add_handler(is_it_friday)\n\n\n**Important:** the order of handlers matters! The first handler to return True stops the chain. So given the above example,\nif it's Tuesday, ``is_it_tuesday`` will return True and ``is_it_friday`` will not run.\n\nYou can override this behavior by raising the StopCheckingFeatureFlags exception in your custom handler:\n\n from flask_featureflags import StopCheckingFeatureFlags\n\n def run_only_on_tuesdays(feature):\n if date.today().weekday() == 2:\n return True\n else:\n raise StopCheckingFeatureFlags\n\nIf it isn't Tuesday, this will cause the chain to return False and any other handlers won't run.\n\n\nAcknowledgements\n================\n\nA 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. :)\n\nQuestions?\n==========\n\nFeel free to ping me on twitter [@trustrachel](https://twitter.com/trustrachel) or on the [Github](https://github.com/trustrachel/Flask-FeatureFlags) project page.\n\n\nChanges\n=======\n\n0.1 (April 17, 2013)\n--------------------\n\nInitial public offering.\n\n0.2 (June 20, 2013)\n--------------------\n\nRevved the version number so I could re-upload to PyPI. No real changes other than that. :/\n\n0.3 (June 27, 2013)\n-------------------\n\n* Dropped support for Python 2.5, and added support for Python 3.3 and Flask 0.10\n* Now testing with PyPy in Travis!\n* Added ``RAISE_ERROR_ON_MISSING_FEATURES`` configuration to throw an error in dev if a feature flag is missing.\n\n0.4 (April 8, 2014)\n-------------------\n\n* General code cleanup and optimization\n* Adding optional redirect to is_active_feature, thank you to michaelcontento \n* Fixed syntax error in docs, thank you to iurisilvio\n\n0.5 (August 7, 2014)\n-------------------\n\nOfficial support for contributed modules, thank you to iurisilvio! He contributed the first for\nSQLAlchemy, so you can store your flags in the database instead.\n\nOther contributions welcome.\n\n\n0.5.1 (October 13, 2014)\n----------------------\n\nAdding 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.\n\nA big thank you to Isman Firmansyah (@iromli) for the contribution!\n\n\n0.6 (June 9, 2015)\n------------------\n\nAdding contrib modules to setup.py. Thank you @iromli and @pcraig3!", "description_content_type": null, "docs_url": null, "download_url": "UNKNOWN", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/trustrachel/Flask-FeatureFlags", "keywords": null, "license": "Apache", "maintainer": null, "maintainer_email": null, "name": "Flask-FeatureFlags", "package_url": "https://pypi.org/project/Flask-FeatureFlags/", "platform": "any", "project_url": "https://pypi.org/project/Flask-FeatureFlags/", "project_urls": { "Download": "UNKNOWN", "Homepage": "https://github.com/trustrachel/Flask-FeatureFlags" }, "release_url": "https://pypi.org/project/Flask-FeatureFlags/0.6/", "requires_dist": null, "requires_python": null, "summary": "Enable or disable features in Flask apps based on configuration", "version": "0.6" }, "last_serial": 1585757, "releases": { "0.1": [], "0.2": [ { "comment_text": "", "digests": { "md5": "d48f85df8edc697303d3c1383b8e7a68", "sha256": "3b5cf53b29fa3edc9a803c5d5a54a7f111c0bc39ec5bdc43749ccd0f2ac4ab6e" }, "downloads": -1, "filename": "Flask_FeatureFlags-0.2-py2.7.egg", "has_sig": false, "md5_digest": "d48f85df8edc697303d3c1383b8e7a68", "packagetype": "bdist_egg", "python_version": "2.7", "requires_python": null, "size": 8061, "upload_time": "2013-06-20T23:23:48", "url": "https://files.pythonhosted.org/packages/4b/99/f1cbea903efe4aaa08c9d00efee9b8309059950cad6e02f3c1eedeba9310/Flask_FeatureFlags-0.2-py2.7.egg" }, { "comment_text": "", "digests": { "md5": "daf8075924bf0a643ea9fae154aca7c6", "sha256": "28b5e8cf8ccd9e5191a7e79767096a2def5ce4ed8c13e46076edadd54b0c2af2" }, "downloads": -1, "filename": "Flask-FeatureFlags-0.2.tar.gz", "has_sig": false, "md5_digest": "daf8075924bf0a643ea9fae154aca7c6", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 17095, "upload_time": "2013-06-20T23:23:58", "url": "https://files.pythonhosted.org/packages/a6/e2/8dceac1b65411447839174b70b11967533bec14553db4c37dcda6804980b/Flask-FeatureFlags-0.2.tar.gz" } ], "0.3": [ { "comment_text": "", "digests": { "md5": "f56714059accef37b842215c96a2510d", "sha256": "b3395cb0fc93def0fc4e72b94dc511ae115055f261d4ed3b44e4179246ff5409" }, "downloads": -1, "filename": "Flask-FeatureFlags-0.3.tar.gz", "has_sig": false, "md5_digest": "f56714059accef37b842215c96a2510d", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 19632, "upload_time": "2013-06-27T17:11:10", "url": "https://files.pythonhosted.org/packages/39/41/0ad765c9bb179a3a175ed07c83b0b93228b2d9d9defa23ea3adba54d8ba9/Flask-FeatureFlags-0.3.tar.gz" } ], "0.4": [ { "comment_text": "", "digests": { "md5": "fe2d9dad3d40450654bf9e83e13c577f", "sha256": "8a28c7a1277d74518f6c81e5cead1ecbb4852a279a05160ba8c2c958cd5971a4" }, "downloads": -1, "filename": "Flask-FeatureFlags-0.4.macosx-10.8-intel.exe", "has_sig": false, "md5_digest": "fe2d9dad3d40450654bf9e83e13c577f", "packagetype": "bdist_wininst", "python_version": "any", "requires_python": null, "size": 75555, "upload_time": "2014-04-08T23:30:54", "url": "https://files.pythonhosted.org/packages/bd/1a/ec2a579c3fe503daa14ea6b33047b9ca2cbbea8008621fac8b010baa1c06/Flask-FeatureFlags-0.4.macosx-10.8-intel.exe" }, { "comment_text": "", "digests": { "md5": "c290729364067b32926f6c3c81645fc7", "sha256": "99ba7f5ab762640117a4c5d315e739ca5c715731b824f32c49dedf5c47758e44" }, "downloads": -1, "filename": "Flask-FeatureFlags-0.4.tar.gz", "has_sig": false, "md5_digest": "c290729364067b32926f6c3c81645fc7", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 21708, "upload_time": "2014-04-08T23:30:51", "url": "https://files.pythonhosted.org/packages/13/de/35ca922154e873495b8e00ec5c81fac0080b26fbb491c9a77314c6ce44ef/Flask-FeatureFlags-0.4.tar.gz" } ], "0.5": [ { "comment_text": "", "digests": { "md5": "453d2b5fd6b0188557d0af1e2bde40fa", "sha256": "dbe86c9697bf7cc76e44d6a5641726a414234fea466cb0e5df8352059333e418" }, "downloads": -1, "filename": "Flask-FeatureFlags-0.5.tar.gz", "has_sig": false, "md5_digest": "453d2b5fd6b0188557d0af1e2bde40fa", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 19944, "upload_time": "2014-08-07T22:16:09", "url": "https://files.pythonhosted.org/packages/21/c7/a6bc59da336bc24e557f315612f89fbfd771ac2461854d971373a18553f9/Flask-FeatureFlags-0.5.tar.gz" } ], "0.5.1": [ { "comment_text": "", "digests": { "md5": "6dba0e3d7e4b73c59fefaf9f1d412933", "sha256": "e5738a5a6b0b4bc0a8dc8f770908a0a3cbabaaa475c06645840a31c8a592bdf2" }, "downloads": -1, "filename": "Flask-FeatureFlags-0.5.1.tar.gz", "has_sig": false, "md5_digest": "6dba0e3d7e4b73c59fefaf9f1d412933", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 20339, "upload_time": "2014-10-13T20:36:54", "url": "https://files.pythonhosted.org/packages/b2/37/51bf0c31d7302ed91ef199f0fbee4ca28ffc1facd46c9a1ed1af95ea1533/Flask-FeatureFlags-0.5.1.tar.gz" } ], "0.6": [ { "comment_text": "", "digests": { "md5": "22d90a6c2dd88e83c51512b8f20c397f", "sha256": "fc8490e4e4c1eac03e306fade8ef4be3cddff6229aaa3bb96466ede7d107b241" }, "downloads": -1, "filename": "Flask-FeatureFlags-0.6.tar.gz", "has_sig": false, "md5_digest": "22d90a6c2dd88e83c51512b8f20c397f", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 6928, "upload_time": "2015-06-10T02:17:34", "url": "https://files.pythonhosted.org/packages/75/ae/5ff4f7d126130cfd6079ccce7b82899df327080a142195814afa7f2a2b59/Flask-FeatureFlags-0.6.tar.gz" } ], "0.6-dev": [] }, "urls": [ { "comment_text": "", "digests": { "md5": "22d90a6c2dd88e83c51512b8f20c397f", "sha256": "fc8490e4e4c1eac03e306fade8ef4be3cddff6229aaa3bb96466ede7d107b241" }, "downloads": -1, "filename": "Flask-FeatureFlags-0.6.tar.gz", "has_sig": false, "md5_digest": "22d90a6c2dd88e83c51512b8f20c397f", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 6928, "upload_time": "2015-06-10T02:17:34", "url": "https://files.pythonhosted.org/packages/75/ae/5ff4f7d126130cfd6079ccce7b82899df327080a142195814afa7f2a2b59/Flask-FeatureFlags-0.6.tar.gz" } ] }