Skip to main content

Simple feature flags with percentage rollout and user targeting.

Project description

philiprehberger-feature-flag

Tests PyPI version Last updated

Simple feature flags with percentage rollout and user targeting.

Installation

pip install philiprehberger-feature-flag

Usage

from philiprehberger_feature_flag import flags

flags.load({"dark_mode": True, "beta_ui": False})

if flags.is_enabled("dark_mode"):
    enable_dark_mode()

Percentage rollout

from philiprehberger_feature_flag import flags

flags.load({
    "new_checkout": {
        "enabled": True,
        "rollout": 25,  # 25% of users
    }
})

if flags.is_enabled("new_checkout", user_id="user-42"):
    show_new_checkout()

User targeting

from philiprehberger_feature_flag import flags

flags.load({
    "admin_panel": {
        "enabled": True,
        "users": ["alice", "bob"],
    }
})

if flags.is_enabled("admin_panel", user_id="alice"):
    show_admin_panel()

Segment targeting

from philiprehberger_feature_flag import flags

flags.define_segment("beta_testers", {"plan": "beta", "region": "us"})
flags.load({
    "new_ui": {
        "enabled": True,
        "segments": ["beta_testers"],
    }
})

if flags.is_enabled("new_ui", plan="beta", region="us"):
    show_new_ui()

Flag dependencies

from philiprehberger_feature_flag import flags

flags.load({"auth": True, "billing": True, "premium": True})
flags.add_dependency("premium", "auth")
flags.add_dependency("premium", "billing")

# premium is only enabled when both auth and billing are enabled
flags.is_enabled("premium")  # True

Scheduled activation

from datetime import datetime, timezone
from philiprehberger_feature_flag import flags

flags.load({"launch": True})
flags.schedule(
    "launch",
    activate_at=datetime(2026, 7, 1, tzinfo=timezone.utc),
    deactivate_at=datetime(2026, 8, 1, tzinfo=timezone.utc),
)

# Flag is only enabled between July 1 and August 1
flags.is_enabled("launch")

Change callbacks

from philiprehberger_feature_flag import flags

def on_flag_change(name, old, new):
    print(f"Flag {name} changed from {old} to {new}")

flags.on_change(on_flag_change)
flags.load({"dark_mode": True})
# prints: Flag dark_mode changed from None to True

flags.remove_listener(on_flag_change)

Snapshot and restore

from philiprehberger_feature_flag import flags

flags.load({"feature_a": True, "feature_b": False})
snap = flags.snapshot()

# Modify state for testing
flags.override("feature_b", True)
assert flags.is_enabled("feature_b")

# Restore original state
flags.restore(snap)
assert not flags.is_enabled("feature_b")

Load from JSON file

from philiprehberger_feature_flag import flags

flags.load("flags.json")

Load from environment variables

from philiprehberger_feature_flag import flags

# Set FF_DARK_MODE=true, FF_BETA=0, etc.
flags.load()  # reads FF_* env vars

Runtime overrides

from philiprehberger_feature_flag import flags

flags.override("beta_ui", True)   # force-enable for testing
flags.reset()                     # clear all overrides

Flag groups

from philiprehberger_feature_flag import flags

flags.load({
    "ui_dark_mode": True,
    "ui_sidebar": False,
    "api_rate_limit": 100,
})

ui_flags = flags.group("ui_")
# {"ui_dark_mode": True, "ui_sidebar": False}

API

Function / Class Description
FlagStore() Create a new flag store
store.load(config) Load flags from dict, JSON file path, or env vars (None)
store.is_enabled(name, **context) Check if a flag is enabled
store.all() Return all loaded flags as a dict
store.override(name, value) Set a runtime override
store.reset() Clear all runtime overrides
store.on_change(callback) Register a callback fired as callback(flag_name, old_value, new_value) on changes
store.remove_listener(callback) Remove a previously registered change callback
store.group(prefix) Return dict of flags whose name starts with prefix with resolved values
store.define_segment(name, attributes) Define a user segment with required attribute key-value pairs
store.remove_segment(name) Remove a previously defined segment
store.add_dependency(flag, depends_on) Declare that flag requires depends_on to be enabled
store.remove_dependency(flag, depends_on) Remove a dependency from a flag
store.schedule(name, activate_at, deactivate_at) Schedule a flag to activate/deactivate at specific datetimes
store.remove_schedule(name) Remove the schedule for a flag
store.snapshot() Capture full store state (flags, overrides, segments, dependencies, schedules)
store.restore(snap) Restore the store to a previously captured snapshot
flags Module-level FlagStore instance

Development

pip install -e .
python -m pytest tests/ -v

Support

If you find this project useful:

Star the repo

🐛 Report issues

💡 Suggest features

❤️ Sponsor development

🌐 All Open Source Projects

💻 GitHub Profile

🔗 LinkedIn Profile

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

philiprehberger_feature_flag-0.3.0.tar.gz (10.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

philiprehberger_feature_flag-0.3.0-py3-none-any.whl (7.9 kB view details)

Uploaded Python 3

File details

Details for the file philiprehberger_feature_flag-0.3.0.tar.gz.

File metadata

File hashes

Hashes for philiprehberger_feature_flag-0.3.0.tar.gz
Algorithm Hash digest
SHA256 932458684c6dea124d237476a9e3d0df0fd7a3ebba87fa7afdd196aa20a20658
MD5 b3be33062e901a8ae83d2dde4b48a65d
BLAKE2b-256 0daefa7f18696b8e89b8974946744218561928e62932cdd9fda7bc90c78f2e23

See more details on using hashes here.

File details

Details for the file philiprehberger_feature_flag-0.3.0-py3-none-any.whl.

File metadata

File hashes

Hashes for philiprehberger_feature_flag-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 1130942179cb3a9181ba3b407ad61cba29199f6d00d3d431834f481eb07b1399
MD5 6f161e70cc2784ef8ef4cd6756dff420
BLAKE2b-256 c8846aac535a064be318ad1ed7cb738960fd8df69fd9dd7143a9e8d23a7c7f5b

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page