Skip to content

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 enabled
if 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 exist
enabled = 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) # True
print(flag.percentage) # 50 (for percentage flags) or None

Getting 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
pass

This 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 result
user_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 down
enabled = client.is_enabled("my-flag")
# Returns False (or your default) on error

The SDK also maintains a stale cache. If the API fails, it returns the last known values:

# Even if API is down, this returns cached values
flags = client.get_all_flags()

Clearing the Cache

Force fresh data on the next flag check:

client.clear_cache()
# Next call will fetch from API
enabled = client.is_enabled("my-flag")

Switching Environments

Change environments at runtime:

# Switch to staging
client.set_environment("staging")
# Cache is automatically cleared
# Flags will now be fetched from staging

Best Practices

1. Initialize Once

Create a single SDK instance and reuse it:

lib/featsync_client.py
import os
from featsync import Featsync
client = Featsync(api_key=os.environ["FEATSYNC_API_KEY"])
anywhere.py
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 check
if client.is_enabled("new-checkout"):
return new_checkout()
return old_checkout()
# After: Flag removed, feature is default
return new_checkout()

Framework Integration

Django

views.py
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

app.py
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

main.py
from fastapi import FastAPI
from 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