Basic Usage
Learn how to check flags, handle defaults, and integrate feature flags into your Python application.
Checking a Flag
The most common operation is checking if a flag is enabled:
from featsync import Featsync
client = Featsync(api_key="fs_your_api_key")
# Check if a flag is enabledif client.is_enabled("new-feature"): show_new_feature()else: show_old_feature()Default Values
If a flag doesn’t exist or there’s an error, is_enabled returns False by default. You can specify a different default:
# Returns True if flag doesn't existenabled = client.is_enabled("beta-feature", default_value=True)Getting Flag Details
For more information about a flag, use get_flag:
flag = client.get_flag("gradual-rollout")
print(flag.key) # 'gradual-rollout'print(flag.enabled) # Trueprint(flag.percentage) # 50 (for percentage flags) or NoneGetting All Flags
Fetch all flags in a single API call:
flags = client.get_all_flags()
if flags.get("feature-a") and flags["feature-a"].enabled: # Feature A is on pass
if flags.get("feature-b") and flags["feature-b"].enabled: # Feature B is on passThis is useful when you need to check multiple flags and want to minimize API calls.
Percentage Rollouts
For percentage-based rollouts, use is_enabled_for_user() to ensure consistent behavior per user:
# Same user always gets same resultuser_id = get_current_user_id()
if client.is_enabled_for_user("new-checkout", user_id): show_new_checkout()else: show_old_checkout()The SDK uses consistent hashing to ensure the same user always gets the same result.
Conditional Rendering
Use flags to conditionally render responses:
def get_navigation(): if client.is_enabled("new-navigation"): return render_new_navigation() return render_old_navigation()Feature Variations
Use flags to switch between different implementations:
def get_payment_processor(): if client.is_enabled("use-stripe"): return StripeProcessor() return PayPalProcessor()Error Handling
The SDK is designed to be resilient. It won’t raise exceptions during normal operation:
# This won't raise even if the API is downenabled = client.is_enabled("my-flag")# Returns False (or your default) on errorThe SDK also maintains a stale cache. If the API fails, it returns the last known values:
# Even if API is down, this returns cached valuesflags = client.get_all_flags()Clearing the Cache
Force fresh data on the next flag check:
client.clear_cache()
# Next call will fetch from APIenabled = client.is_enabled("my-flag")Switching Environments
Change environments at runtime:
# Switch to stagingclient.set_environment("staging")
# Cache is automatically cleared# Flags will now be fetched from stagingBest Practices
1. Initialize Once
Create a single SDK instance and reuse it:
import osfrom featsync import Featsync
client = Featsync(api_key=os.environ["FEATSYNC_API_KEY"])from lib.featsync_client import client
if client.is_enabled("my-flag"): # ...2. Use Meaningful Flag Names
# Good"new-checkout-flow""enable-dark-mode""show-beta-banner"
# Bad"flag1""test""temp"3. Have a Fallback
Always consider what happens when the flag is off:
if client.is_enabled("experimental-search"): return experimental_search(query)# Don't forget the else case!return standard_search(query)4. Clean Up Old Flags
Once a feature is fully rolled out, remove the flag check from your code:
# Before: Flag checkif client.is_enabled("new-checkout"): return new_checkout()return old_checkout()
# After: Flag removed, feature is defaultreturn new_checkout()Framework Integration
Django
from lib.featsync_client import client
def my_view(request): if client.is_enabled_for_user("new-feature", str(request.user.id)): return render(request, "new_feature.html") return render(request, "old_feature.html")Flask
from featsync import Featsync
featsync = Featsync(api_key=os.environ.get("FEATSYNC_API_KEY"))
@app.route("/")def index(): if featsync.is_enabled("new-homepage"): return render_template("new_index.html") return render_template("index.html")FastAPI
from fastapi import FastAPIfrom featsync import Featsync
app = FastAPI()featsync = Featsync(api_key=os.environ.get("FEATSYNC_API_KEY"))
@app.get("/")async def root(user_id: str = None): if user_id and featsync.is_enabled_for_user("new-api", user_id): return {"version": "v2"} return {"version": "v1"}Next Steps
- Set up targeting rules for user-specific flags
- View configuration options for advanced setup