Feature flag management SDK for Python - zero dependencies core library
Project description
toggly
Feature flag management SDK for Python - zero dependencies core library.
Can be used WITH or WITHOUT Toggly.io.
What is a Feature Flag
A feature flag (or feature toggle) is a software development technique that allows you to enable or disable features in your application without deploying new code. This enables:
- Gradual Rollouts: Release features to a percentage of users
- A/B Testing: Test different implementations with different user groups
- Kill Switches: Instantly disable problematic features
- Environment-Specific: Different feature states per environment
Installation
pip install toggly
Quick Start
Basic Usage with Toggly.io
from toggly import TogglyClient, TogglyConfig
# Create configuration
config = TogglyConfig(
app_key="your-app-key",
environment="Production"
)
# Initialize client
client = TogglyClient(config)
client.init()
# Check if a feature is enabled
if client.is_enabled("new-checkout-flow"):
# New checkout implementation
pass
else:
# Original checkout implementation
pass
Using Decorators
from toggly import TogglyClient, TogglyConfig, feature_flag, set_default_client
# Set up default client
config = TogglyConfig(app_key="your-app-key")
client = TogglyClient(config)
client.init()
set_default_client(client)
# Use decorator to control function execution
@feature_flag("new-algorithm")
def calculate_score(data):
return new_algorithm(data)
# Or with a fallback
@feature_flag("new-algorithm", fallback=old_algorithm)
def calculate_score(data):
return new_algorithm(data)
Using Context Manager
with client.feature_context("new-feature") as enabled:
if enabled:
# Feature is enabled
do_new_thing()
else:
# Feature is disabled
do_old_thing()
Async Support
from toggly import AsyncTogglyClient, TogglyConfig
config = TogglyConfig(app_key="your-app-key")
client = AsyncTogglyClient(config)
async def main():
await client.init()
if await client.is_enabled("new-feature"):
await do_new_thing()
Feature Gates (Multiple Features)
Evaluate multiple features together:
from toggly import FeatureRequirement
# All features must be enabled
if client.evaluate_gate(
["feature-a", "feature-b"],
requirement=FeatureRequirement.ALL
):
# Both features are enabled
pass
# Any feature must be enabled
if client.evaluate_gate(
["feature-a", "feature-b"],
requirement=FeatureRequirement.ANY
):
# At least one feature is enabled
pass
User Targeting
Target features to specific users or groups:
from toggly import EvaluationContext
# Create user context
context = EvaluationContext(
identity="user-123",
groups=["beta-testers", "premium"],
traits={"country": "US", "plan": "enterprise"}
)
# Evaluate with context
if client.is_enabled("premium-feature", context):
# Feature is enabled for this user
pass
Offline Mode (Without Toggly.io)
Use feature flags without a server connection:
from toggly import TogglyClient, TogglyConfig
config = TogglyConfig(
feature_defaults={
"feature-a": True,
"feature-b": False,
"feature-c": True
}
)
client = TogglyClient(config)
client.init()
# Works completely offline using defaults
if client.is_enabled("feature-a"):
pass
Caching
Use file-based caching for offline support:
from toggly import TogglyClient, TogglyConfig, FileSnapshotProvider
provider = FileSnapshotProvider(directory="/path/to/cache")
config = TogglyConfig(
app_key="your-app-key",
snapshot_provider=provider
)
client = TogglyClient(config)
client.init() # Loads from cache if server unavailable
State Change Handlers
React to feature flag changes:
def on_feature_change(key: str, old_value: bool, new_value: bool):
print(f"Feature {key} changed: {old_value} -> {new_value}")
config = TogglyConfig(
app_key="your-app-key",
state_change_handlers=[on_feature_change]
)
Custom Evaluators
Register custom filter evaluators:
from toggly.evaluator import FilterEvaluator, FeatureFilter
from toggly import EvaluationContext
class CustomEvaluator(FilterEvaluator):
def evaluate(
self,
filter_: FeatureFilter,
feature_key: str,
context: EvaluationContext,
) -> bool:
# Custom evaluation logic
return context.traits.get("custom_field") == filter_.parameters.get("value")
# Register with client
client.registry.register("CustomFilter", CustomEvaluator())
Configuration Options
| Option | Type | Default | Description |
|---|---|---|---|
app_key |
str |
None |
Your Toggly application key |
environment |
str |
"Production" |
Environment name |
base_url |
str |
"https://client.toggly.io" |
API base URL |
identity |
str |
None |
Default user identity |
feature_defaults |
dict |
{} |
Default feature flag values |
refresh_interval |
float |
180.0 |
Auto-refresh interval (seconds) |
use_signed_definitions |
bool |
False |
Verify definition signatures |
connect_timeout |
float |
10.0 |
Connection timeout (seconds) |
request_timeout |
float |
30.0 |
Request timeout (seconds) |
snapshot_provider |
SnapshotProvider |
None |
Cache provider |
enable_usage_tracking |
bool |
True |
Track feature usage |
disable_background_refresh |
bool |
False |
Disable auto-refresh |
Debug Information
Get current client state:
info = client.get_debug_info()
print(f"Environment: {info.environment}")
print(f"Feature count: {info.feature_count}")
print(f"Last refresh: {info.last_refresh}")
print(f"Initialized: {info.is_initialized}")
Framework Integrations
For framework-specific features, use the integration packages:
- Django:
pip install toggly toggly-django - Flask:
pip install toggly toggly-flask - FastAPI:
pip install toggly toggly-fastapi - Redis/Memcached caching:
pip install toggly toggly-cache[redis]
Requirements
- Python 3.8+
- No dependencies (zero dependencies core)
Type Hints
The library is fully typed with Python type hints and includes py.typed marker for static type checkers.
from toggly import TogglyClient, TogglyConfig, EvaluationContext
config: TogglyConfig = TogglyConfig(app_key="key")
client: TogglyClient = TogglyClient(config)
enabled: bool = client.is_enabled("feature")
Thread Safety
The TogglyClient is thread-safe and can be shared across threads. Internal state is protected with locks.
License
MIT
Find Out More
Visit Toggly.io for more information and to create your free account.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file toggly-0.0.1.tar.gz.
File metadata
- Download URL: toggly-0.0.1.tar.gz
- Upload date:
- Size: 37.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c9a1f6e0c8c9237ce2c7816299d4caff750df24f752ed7f9f28b08e44cde8686
|
|
| MD5 |
c12868ceda3000d955071a322ce9e685
|
|
| BLAKE2b-256 |
57e4df18a29d3d301b4c535a2327e7d72c08328031f886ddf2fe7ec8c5e69da9
|
Provenance
The following attestation bundles were made for toggly-0.0.1.tar.gz:
Publisher:
sdk-python-release.yml on ops-ai/Toggly.FeatureManagement
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
toggly-0.0.1.tar.gz -
Subject digest:
c9a1f6e0c8c9237ce2c7816299d4caff750df24f752ed7f9f28b08e44cde8686 - Sigstore transparency entry: 1014759071
- Sigstore integration time:
-
Permalink:
ops-ai/Toggly.FeatureManagement@f4c8b6d84d507b28881dbb00ec1c96888ab38cea -
Branch / Tag:
refs/heads/develop - Owner: https://github.com/ops-ai
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
sdk-python-release.yml@f4c8b6d84d507b28881dbb00ec1c96888ab38cea -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file toggly-0.0.1-py3-none-any.whl.
File metadata
- Download URL: toggly-0.0.1-py3-none-any.whl
- Upload date:
- Size: 31.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
65378d8cce882dc978b658f6af70418b42fbed0751f8665013e4a919b13539f2
|
|
| MD5 |
5204fa2a236ba72130b65b2d349429df
|
|
| BLAKE2b-256 |
09117edcbf7fcac99b82ec3c43be7bc9e79c6fb1d0e7d8a30bc9a1ac6707e3ae
|
Provenance
The following attestation bundles were made for toggly-0.0.1-py3-none-any.whl:
Publisher:
sdk-python-release.yml on ops-ai/Toggly.FeatureManagement
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
toggly-0.0.1-py3-none-any.whl -
Subject digest:
65378d8cce882dc978b658f6af70418b42fbed0751f8665013e4a919b13539f2 - Sigstore transparency entry: 1014759105
- Sigstore integration time:
-
Permalink:
ops-ai/Toggly.FeatureManagement@f4c8b6d84d507b28881dbb00ec1c96888ab38cea -
Branch / Tag:
refs/heads/develop - Owner: https://github.com/ops-ai
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
sdk-python-release.yml@f4c8b6d84d507b28881dbb00ec1c96888ab38cea -
Trigger Event:
workflow_dispatch
-
Statement type: