Skip to main content

Configuration

The Toggly Python SDK can be configured using TogglyConfig or through framework-specific settings.

User context belongs to each request​

Normal boolean evaluation fetches global definitions and evaluates with each request's user context. Pass identity, memberships and claims into that local evaluation; do not mutate a shared application's startup identity for each user. Optional remotely evaluated variants have a separate client-scoped context. Configure that fixed context before startup as shown below. It does not replace the request-local context used by ordinary boolean evaluation.

TogglyConfig Options​

from toggly import TogglyConfig

config = TogglyConfig(
# Required
app_key="your-app-key",

# Optional
environment="Production", # Environment name
base_url="https://definitions.toggly.io", # API base URL
refresh_interval=180.0, # Seconds between refreshes
connect_timeout=10.0, # Connection timeout in seconds
request_timeout=30.0, # Request timeout in seconds
enable_usage_tracking=True, # Track feature usage
disable_background_refresh=False, # Disable auto-refresh
use_signed_definitions=False, # Verify signed definitions (ES256)
allowed_key_ids=None, # Optional kid allow-list
enable_live_updates=True, # WebSocket live updates
feature_defaults={}, # Default feature values
debug=False, # Enable debug logging
)

Initial context for remote variants​

from toggly import TogglyClient, TogglyConfig

client = TogglyClient(TogglyConfig(
app_key="your-app-key",
enable_variants=True,
identity="user-123", # Stable ID for this variants client.
variant_groups=["beta"], # Memberships used by targeting rules.
variant_claims={"plan": "pro"}, # String rule attributes.
))
client.init() # The first variants request includes the complete context.

AsyncTogglyClient accepts the same configuration; use await client.init(). Django, Flask and FastAPI accept these startup options in their SDK configuration. They are application-wide defaults, not values to replace for every incoming request. Keep ordinary local boolean checks request-scoped with EvaluationContext. Enabling remote variants uses client-wide evaluated flags and variants.

The client copies collections before startup. Empty collections add no targeting values; blank groups and empty claim names/values are omitted. Claims are strings, with whitespace preserved and at most 20 sorted claim names sent. Cached variants and conditional validators must match the complete context.

Configuration Options Reference​

OptionTypeDefaultDescription
app_keystrRequiredYour Toggly application key
environmentstr"Production"Environment name (Production, Staging, etc.)
base_urlstr"https://definitions.toggly.io"Toggly API base URL
refresh_intervalfloat180.0Seconds between background refreshes
connect_timeoutfloat10.0HTTP connection timeout in seconds
request_timeoutfloat30.0HTTP request timeout in seconds
enable_usage_trackingboolTrueWhether to track feature usage
disable_background_refreshboolFalseDisable automatic background refresh
use_signed_definitionsboolFalseVerify cryptographically signed definitions
allowed_key_idslist[str] | NoneNoneAllowed signing key IDs (None = all)
enable_live_updatesboolTrueWebSocket live updates (toggly[websocket])
feature_defaultsdict{}Default values for features
on_errorcallable | NoneNoneCallback for refresh / signature failures
debugboolFalseEnable debug logging

Signed definitions​

See Signed definitions for JWKS + ES256 verification. Shared contract: Server-side reliability.

Live updates (WebSockets)​

See Live updates. Protocol: WebSocket sync.

Built-in filter inventory​

EvaluatorRegistry ships these evaluators:

Filter namePurpose
AlwaysOn / AlwaysOffStatic on / off
PercentageDeterministic rollout from identity
TimeWindowTime-based availability
TargetingUsers / groups / default rollout %
BrowserFamily, BrowserLanguage, Country / CountryFamily, DeviceType, OS / OperatingSystemHTTP segment filters via request
UserClaimsPrincipal claims via claims
ContextPropertyEntity property filters (fail closed)

Segment and UserClaims filters need EvaluationContext.claims and EvaluationContext.request. Map headers with HttpRequestMapper.from_http_headers (or merge_into) — same country header precedence as Node fromHttpRequest. UserClaims never reads HTTP headers; set claims from your auth layer. Missing context or an unknown filter name fails closed. Matrix: SDK × filter matrix.

from toggly import EvaluationContext, HttpRequestMapper, RequestContext

base = EvaluationContext(
identity=user_id,
claims={"role": role_from_auth},
)
context = HttpRequestMapper.merge_into(request.headers, base)
# Or set request explicitly:
# context = base.with_request(RequestContext(country="US", user_agent=ua))

if client.is_enabled("MobileCheckout", context):
...

Django / Flask / FastAPI helpers may not auto-map segment headers — wire HttpRequestMapper (or request=) when you need those filters.

Register custom filters via the evaluator registry (see Advanced Usage).

Framework-Specific Configuration​

# settings.py: read by the toggly_django AppConfig at startup.
import os

TOGGLY = {
"APP_KEY": os.environ.get("TOGGLY_APP_KEY"),
"ENVIRONMENT": "Production",
"BASE_URL": "https://definitions.toggly.io",
"REFRESH_INTERVAL": 180.0,
"CONNECT_TIMEOUT": 10.0,
"REQUEST_TIMEOUT": 30.0,
"ENABLE_USAGE_TRACKING": True,
"DISABLE_BACKGROUND_REFRESH": False,
"USE_SIGNED_DEFINITIONS": False,
"FEATURE_DEFAULTS": {},
"DEBUG": False,
# Optional fixed context for a remote-variants client:
"ENABLE_VARIANTS": False,
"IDENTITY": None,
"VARIANT_GROUPS": [],
"VARIANT_CLAIMS": {},
}
Live updates

enable_live_updates is not a Django settings key; it defaults to True on TogglyConfig. Override by constructing a client and wiring it yourself — see Live updates.

Environment Variables​

Read environment variables in your application setup and pass typed values to the SDK:

export TOGGLY_APP_KEY="your-app-key"
export TOGGLY_ENVIRONMENT="Production"
export TOGGLY_BASE_URL="https://definitions.toggly.io"
export TOGGLY_REFRESH_INTERVAL="180"
export TOGGLY_CONNECT_TIMEOUT="10"
export TOGGLY_REQUEST_TIMEOUT="30"
export TOGGLY_ENABLE_USAGE_TRACKING="true"
export TOGGLY_DISABLE_BACKGROUND_REFRESH="false"
export TOGGLY_USE_SIGNED_DEFINITIONS="false"
export TOGGLY_DEBUG="false"
import os
from toggly import TogglyConfig

config = TogglyConfig(
app_key=os.environ.get("TOGGLY_APP_KEY"),
environment=os.environ.get("TOGGLY_ENVIRONMENT", "Production"),
refresh_interval=float(os.environ.get("TOGGLY_REFRESH_INTERVAL", "180")),
enable_usage_tracking=os.environ.get(
"TOGGLY_ENABLE_USAGE_TRACKING", "true"
).lower() == "true",
)

TogglyConfig does not read the process environment itself. Map the options you use, including parsing numbers and booleans. The framework examples read Django/Flask configuration or explicit FastAPI arguments before initialization.

Feature Defaults​

You can specify default values for features that will be used when the feature definition is not found or the API is unavailable:

config = TogglyConfig(
app_key="your-app-key",
feature_defaults={
"new-checkout": False, # Disabled by default
"dark-mode": True, # Enabled by default
"api-v2": False, # Disabled by default
}
)

Initialization​

Synchronous Client​

from toggly import TogglyClient, TogglyConfig

config = TogglyConfig(app_key="your-app-key")
client = TogglyClient(config)

# Initialize the client (fetches feature definitions)
client.init()

# Use the client
if client.is_enabled("my-feature"):
print("Feature enabled!")

# Cleanup when done
client.close()

Async Client​

import asyncio
from toggly import AsyncTogglyClient, TogglyConfig

config = TogglyConfig(app_key="your-app-key")
client = AsyncTogglyClient(config)

async def main():
# Initialize the client
await client.init()

# Use the client
if await client.is_enabled("my-feature"):
print("Feature enabled!")

# Cleanup when done
await client.close()

asyncio.run(main())

Context Manager​

Both clients support the context manager pattern for automatic cleanup:

# Synchronous
with TogglyClient(config) as client:
client.init()
if client.is_enabled("my-feature"):
print("Feature enabled!")

# Async
async with AsyncTogglyClient(config) as client:
await client.init()
if await client.is_enabled("my-feature"):
print("Feature enabled!")

Global Client​

For convenience, you can set a global default client:

from toggly import TogglyClient, TogglyConfig, set_default_client, get_default_client

config = TogglyConfig(app_key="your-app-key")
client = TogglyClient(config)
client.init()

# Set as default
set_default_client(client)

# Later, retrieve from anywhere
client = get_default_client()
if client and client.is_enabled("my-feature"):
print("Feature enabled!")

Framework-owned initialization registers the default client. When supplying a preconfigured Flask client, also call set_default_client(client) once at startup so native decorators use it. Never replace the global client or its identity for each user.