Python SDK
Use Flagpool feature flags in Python applications
The official Python SDK for Flagpool. Evaluate feature flags locally with deterministic rollouts, advanced targeting, and automatic polling.
Installation
pip install flagpool-sdk
Requirements: Python 3.8+
Quick Start
from flagpool_sdk import FlagpoolClient
client = FlagpoolClient(
project_id="your-project-uuid",
api_key="your-api-key",
decryption_key="your-decryption-key",
context={
"userId": "user-123",
"email": "alice@example.com",
"plan": "pro",
},
)
client.init()
# Boolean flag
if client.is_enabled("new-dashboard"):
show_new_dashboard()
# String, number, or JSON flag
button_color = client.get_value("cta-button-color")
# Clean up when done
client.close()
Configuration
client = FlagpoolClient(
# Required
project_id="your-project-uuid",
api_key="your-api-key",
decryption_key="your-decryption-key",
# Optional
context={
"userId": "user-123",
"email": "user@example.com",
"plan": "pro",
},
polling_interval=30, # Auto-refresh interval in seconds (default: 30)
url_override=None, # Complete URL override (for self-hosted/testing)
)
| Option | Type | Required | Description |
|---|---|---|---|
project_id | str | Yes | Project UUID from the dashboard |
api_key | str | Yes | Environment-specific API key |
decryption_key | str | Yes | For CDN URL hashing and target list decryption |
context | dict | No | User context for targeting rules |
polling_interval | int | No | Polling interval in seconds (default: 30) |
url_override | str | No | Complete URL override for self-hosted setups |
analytics | AnalyticsConfig | No | Analytics configuration (opt-in) |
API Reference
| 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 a dict |
update_context(ctx) | Update user context — flags re-evaluate automatically |
on_change(callback) | Subscribe to flag value changes |
close() | Stop polling and clean up resources |
Flag Types
Boolean Flags
if client.is_enabled("feature-flag"):
# Feature is enabled for this user
pass
String Flags
variant = client.get_value("button-color")
# "blue" | "green" | "orange"
Number Flags
limit = client.get_value("rate-limit")
# 100 | 1000 | 10000
JSON Flags
config = client.get_value("checkout-config")
# {"showCoupons": True, "maxItems": 50, ...}
Dynamic Context Updates
Update user context on the fly — flags re-evaluate automatically:
# 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. Listen for changes:
def on_flag_change(flag_key, new_value):
print(f"Flag {flag_key} changed to: {new_value}")
if flag_key == "maintenance-mode" and new_value:
show_maintenance_banner()
client.on_change(on_flag_change)
Framework Examples
Django
# 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(
project_id=settings.FLAGPOOL_PROJECT_ID,
api_key=settings.FLAGPOOL_API_KEY,
decryption_key=settings.FLAGPOOL_DECRYPTION_KEY,
)
_client.init()
return _client
# views.py
from .flags import get_flagpool
def my_view(request):
flagpool = get_flagpool()
flagpool.update_context({"userId": str(request.user.id)})
if flagpool.is_enabled("new-checkout"):
return render(request, "new_checkout.html")
return render(request, "checkout.html")
FastAPI
from fastapi import FastAPI
from flagpool_sdk import FlagpoolClient
app = FastAPI()
flagpool = FlagpoolClient(
project_id="your-project-uuid",
api_key="your-api-key",
decryption_key="your-decryption-key",
)
@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}
Flask
from flask import Flask
from flagpool_sdk import FlagpoolClient
app = Flask(__name__)
flagpool = FlagpoolClient(
project_id="your-project-uuid",
api_key="your-api-key",
decryption_key="your-decryption-key",
)
flagpool.init()
@app.route("/dashboard")
def dashboard():
if flagpool.is_enabled("new-dashboard"):
return render_template("new_dashboard.html")
return render_template("dashboard.html")
Analytics
Track flag evaluation counts. Analytics is opt-in and disabled by default.
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,
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)
),
)
| 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) |
Targeting 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 |
Next Steps
- Getting Started — full setup guide
- Using Flags in Code — evaluation patterns across all SDKs