Python SDK for Flagpool feature flags
Project description
Flagpool SDK for Python
Official Python SDK for Flagpool - the modern feature flag platform for teams who want control without complexity.
Installation
pip install flagpool-sdk
Quick Start
from flagpool_sdk import FlagpoolClient
client = FlagpoolClient(
project_id='your-project-uuid', # Get from Flagpool dashboard
api_key='fp_production_xxx', # Environment-specific API key
decryption_key='fp_dec_xxx', # For CDN URL hash & target lists
context={
'userId': 'user-123',
'email': 'alice@example.com',
'plan': 'pro',
'country': 'US'
}
)
client.init()
# Boolean flag
if client.is_enabled('new-dashboard'):
show_new_dashboard()
# String flag (A/B test)
button_color = client.get_value('cta-button-color')
# 'blue' | 'green' | 'orange'
# Number flag
max_upload = client.get_value('max-upload-size-mb')
# 10 | 100 | 1000
# JSON flag
config = client.get_value('checkout-config')
# { 'showCoupons': True, 'maxItems': 50, ... }
# Clean up when done
client.close()
Features
- ✅ Local evaluation - No server roundtrip per flag check
- ✅ Deterministic rollouts - Same user always gets same variation
- ✅ Multiple flag types - Boolean, string, number, JSON (dict)
- ✅ Advanced targeting - 8 operators including target lists
- ✅ Real-time updates - Automatic polling for flag changes
- ✅ Offline support - Works with cached flags when offline
- ✅ Minimal dependencies - Only requires
requests
Configuration
client = FlagpoolClient(
# Required
project_id='your-project-uuid', # Project ID from dashboard
api_key='fp_production_xxx', # Environment-specific API key
decryption_key='fp_dec_xxx', # For CDN URL hash & target list decryption
# Optional
context={ # User context for targeting
'userId': 'user-123',
'email': 'user@example.com',
'plan': 'pro',
# Add any attributes for targeting
},
polling_interval=30, # Auto-refresh interval (seconds), default: 30
url_override=None, # Complete URL override (for self-hosted/testing)
)
API Reference
Methods
| Method | Description |
|---|---|
init() |
Initialize client and fetch flags (required before evaluation) |
is_enabled(key) |
Check if a boolean flag is enabled |
get_value(key) |
Get flag value (any type) |
get_variation(key) |
Alias for get_value |
get_all_flags() |
Get all evaluated flag values as dict |
update_context(ctx) |
Update user context and re-evaluate flags |
on_change(callback) |
Subscribe to flag value changes |
close() |
Clean up resources (stop polling) |
Flag Types
Boolean Flags
if client.is_enabled('feature-flag'):
# Feature is enabled for this user
pass
String Flags
Perfect for A/B tests and feature variants:
variant = client.get_value('button-color')
# Returns: 'blue' | 'green' | 'orange'
Number Flags
Great for limits, thresholds, and configurations:
limit = client.get_value('rate-limit')
# Returns: 100 | 1000 | 10000
JSON Flags (dict)
For complex configurations:
config = client.get_value('checkout-config')
# Returns: { 'showCoupons': True, 'maxItems': 50, ... }
Targeting Rules
Flagpool supports powerful targeting with 8 operators:
| Operator | Description | Example |
|---|---|---|
eq |
Equals | plan == "enterprise" |
neq |
Not equals | plan != "free" |
in |
In list | country in ["US", "CA"] |
nin |
Not in list | country not in ["CN", "RU"] |
contains |
String contains | email contains "@company.com" |
startsWith |
String starts with | userId startsWith "admin-" |
inTargetList |
In target list | userId in beta-testers |
notInTargetList |
Not in target list | userId not in blocked-users |
Dynamic Context Updates
Update user context on the fly - flags re-evaluate automatically:
client = FlagpoolClient(
api_key='fp_prod_xxx',
environment='production',
context={'userId': 'user-1', 'plan': 'free'}
)
client.init()
# User on free plan
print(client.get_value('max-upload-size-mb')) # 10
# User upgrades to pro
client.update_context({'plan': 'pro'})
# Instantly gets pro limits
print(client.get_value('max-upload-size-mb')) # 100
Real-time Updates
Flags automatically refresh in the background:
client = FlagpoolClient(
api_key='fp_prod_xxx',
environment='production',
context={'userId': 'user-1'},
polling_interval=30 # Refresh every 30 seconds
)
client.init()
# Listen for flag changes
def on_flag_change(flag_key, new_value):
print(f'Flag {flag_key} changed to: {new_value}')
# React to changes
if flag_key == 'maintenance-mode' and new_value:
show_maintenance_banner()
client.on_change(on_flag_change)
Framework Examples
Django
# settings.py
FLAGPOOL_API_KEY = 'fp_production_xxx'
# flags.py
from flagpool_sdk import FlagpoolClient
from django.conf import settings
_client = None
def get_flagpool():
global _client
if _client is None:
_client = FlagpoolClient(
api_key=settings.FLAGPOOL_API_KEY,
environment='production',
)
_client.init()
return _client
# views.py
from .flags import get_flagpool
def my_view(request):
flagpool = get_flagpool()
flagpool.update_context({'userId': request.user.id})
if flagpool.is_enabled('new-checkout'):
return render(request, 'new_checkout.html')
return render(request, 'checkout.html')
Flask
from flask import Flask, g
from flagpool_sdk import FlagpoolClient
app = Flask(__name__)
flagpool = FlagpoolClient(
api_key='fp_production_xxx',
environment='production',
)
flagpool.init()
@app.before_request
def set_user_context():
if hasattr(g, 'user'):
flagpool.update_context({'userId': g.user.id})
@app.route('/dashboard')
def dashboard():
if flagpool.is_enabled('new-dashboard'):
return render_template('new_dashboard.html')
return render_template('dashboard.html')
FastAPI
from fastapi import FastAPI, Depends
from flagpool_sdk import FlagpoolClient
app = FastAPI()
flagpool = FlagpoolClient(
api_key='fp_production_xxx',
environment='production',
)
@app.on_event("startup")
async def startup():
flagpool.init()
@app.on_event("shutdown")
async def shutdown():
flagpool.close()
@app.get("/api/data")
async def get_data(user_id: str):
flagpool.update_context({'userId': user_id})
if flagpool.is_enabled('new-api-response'):
return {"version": "v2", "data": new_data}
return {"version": "v1", "data": legacy_data}
Target List Encryption
By default, target lists (used for inTargetList and notInTargetList operators) are encrypted in SDK exports to protect sensitive user data like emails and user IDs.
Encrypted Target Lists (Default)
If your environment has target list encryption enabled, you must provide a crypto adapter:
from flagpool_sdk import FlagpoolClient, set_crypto_adapter
class MyCryptoAdapter:
def decrypt(self, ciphertext: str, key: str, iv: str, tag: str) -> str:
# Implement AES-256-GCM decryption
# See examples/ for a complete implementation using cryptography library
return decrypted_text
# Set the adapter before creating the client
set_crypto_adapter(MyCryptoAdapter())
client = FlagpoolClient(
project_id='your-project-uuid',
api_key='fp_production_xxx',
decryption_key='fp_dec_xxx',
context={'userId': 'user-123'}
)
Error: "Encrypted target lists received but no crypto adapter configured"
If you see this error, it means:
- Your environment has target list encryption enabled (the default)
- You haven't set up a crypto adapter
Solutions:
-
Set up a crypto adapter (recommended for production):
set_crypto_adapter(MyCryptoAdapter())
-
Disable encryption (for development/testing):
- Go to Flagpool Dashboard → Settings → Environments
- Toggle off "Target List Encryption" for your environment
- This will export target lists in plaintext (values will be visible)
Plaintext Target Lists
If you disable target list encryption in the dashboard, no crypto adapter is needed. The SDK will use target lists directly without decryption.
⚠️ Security Note: Disabling encryption exposes target list values (emails, user IDs, etc.) in plaintext in the SDK exports. Only disable for development environments or non-sensitive data.
Analytics (Paid Plans Only)
Track flag evaluation counts to understand usage patterns. Analytics is opt-in, disabled by default, and only available on paid plans.
Enabling Analytics
from flagpool_sdk import FlagpoolClient, AnalyticsConfig
client = FlagpoolClient(
project_id="your-project-uuid",
api_key="your-api-key",
decryption_key="your-decryption-key",
analytics=AnalyticsConfig(enabled=True),
)
client.init()
Configuration Options
analytics=AnalyticsConfig(
enabled=True,
flush_interval=60, # Flush interval in seconds (min: 30)
flush_threshold=100, # Flush after N evaluations
sample_rate=1.0, # Sample rate 0.0–1.0
sync_flush_on_shutdown=False, # Block on exit until flushed
)
| Option | Type | Default | Description |
|---|---|---|---|
enabled |
bool | False |
Enable/disable analytics |
flush_interval |
int | 60 |
Flush interval in seconds (minimum: 30) |
flush_threshold |
int | 100 |
Flush after N evaluations |
sample_rate |
float | 1.0 |
Sample rate (0.0–1.0) |
sync_flush_on_shutdown |
bool | False |
Flush synchronously on process exit |
How It Works
- Evaluation counts are batched in memory
- Batches are sent asynchronously (fire-and-forget)
- Analytics never blocks flag evaluation
- Data is aggregated daily in your Flagpool dashboard
- Note: Data is silently discarded for free plan projects
Serverless / Short-Lived Processes
For AWS Lambda or similar short-lived environments, lower the threshold and enable sync flush:
analytics=AnalyticsConfig(
enabled=True,
flush_threshold=10,
sync_flush_on_shutdown=True,
)
Debugging Analytics
# Get current analytics state
state = client.get_analytics_state()
print(state.buffer) # {'my-flag': 5}
print(state.buffer_size) # 5
print(state.total_flushes) # 2
# Get all flags with evaluation status
flags = client.get_all_flags_with_state()
# {'my-flag': {'value': True, 'evaluated': True}, ...}
# Manually flush analytics buffer
client.flush_analytics()
Documentation
For complete documentation, guides, and best practices, visit:
Support
License
MIT © Flagpool
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 flagpool_sdk-0.3.2.tar.gz.
File metadata
- Download URL: flagpool_sdk-0.3.2.tar.gz
- Upload date:
- Size: 28.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e83c9ba9713788e22ea0d3c0978f39cfaa7c9ca5cd197979155b4cae300327b9
|
|
| MD5 |
f36f579710452aea13ec68f65d78f201
|
|
| BLAKE2b-256 |
6cc65fc82cd3f7fe392db6ad7406b27d72131053838c4e4d67921fc5f1a79566
|
File details
Details for the file flagpool_sdk-0.3.2-py3-none-any.whl.
File metadata
- Download URL: flagpool_sdk-0.3.2-py3-none-any.whl
- Upload date:
- Size: 17.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
db2234f763e6b0a9cb1575ac0813e9f6143cac97a87ddf5a021d81e13b4ea1e6
|
|
| MD5 |
f91180aa58024ff62abca96f44928ff3
|
|
| BLAKE2b-256 |
22460ba99dc1f6a8bcb72fe16f161290bfa1a410ee53a71b5c08de04c11bc28d
|