Official Python SDK for Zenmanage feature flags with local evaluation
Project description
Zenmanage Python SDK
Add feature flags to your Python application in minutes. Control feature rollouts, A/B test, and manage configurations without deploying code.
Why Zenmanage?
- Fast: rules cached locally for low-latency evaluation
- Targeted: roll out by user, organization, or custom attributes
- Safe: graceful defaults and typed accessors
- Insightful: optional usage reporting
- Testable: deterministic rollout logic and isolated rule engine
Installation
pip install zenmanage
Requirements: Python 3.9+
Key Compatibility
- Supported in Python SDK: case-sensitive server keys prefixed with
srv_ - Not supported in Python SDK: client keys (
cli_) and mobile keys (mob_) (initialization fails fast)
Get Started in 60 Seconds
- Get your server key (
srv_...) from zenmanage.com - Initialize the SDK:
from zenmanage import ConfigBuilder, Zenmanage
zenmanage = Zenmanage(
ConfigBuilder.create()
.with_environment_token("srv_your_server_key_here")
.build()
)
- Check a feature flag:
flag = zenmanage.flags().single("new-dashboard", False)
if flag.is_enabled():
show_new_dashboard()
else:
show_old_dashboard()
Common Use Cases
Async Frameworks (FastAPI, Starlette, etc.)
from zenmanage import AsyncZenmanage, ConfigBuilder, Context
zenmanage = AsyncZenmanage(
ConfigBuilder.from_environment().build()
)
async def is_enabled_for_user(user_id: str) -> bool:
context = Context.single("user", user_id)
flag = await zenmanage.flags().with_context(context).single("new-dashboard", False)
return flag.is_enabled()
Remember to close the async client on shutdown:
await zenmanage.aclose()
Roll Out a New Feature Gradually
from zenmanage import Context
context = Context.single("user", user_id, user_name)
beta_access = (
zenmanage.flags()
.with_context(context)
.single("beta-program", False)
.is_enabled()
)
if beta_access:
enable_beta_features()
A/B Testing
from zenmanage import Attribute, Context
context = Context.single("user", user.id, user.name)
context.add_attribute(Attribute.from_strings("country", [user.country]))
context.add_attribute(Attribute.from_strings("plan", [user.subscription_plan]))
variant = (
zenmanage.flags()
.with_context(context)
.single("checkout-flow", "multi-page")
.as_string()
)
if variant == "one-page":
render_one_page_checkout()
else:
render_multi_page_checkout()
Percentage Rollouts
from zenmanage import Context
context = Context.single("user", user_id)
flag = (
zenmanage.flags()
.with_context(context)
.single("new-checkout-flow", False)
)
if flag.is_enabled():
render_new_checkout()
else:
render_classic_checkout()
How it works:
- Configure rollout percentage (0-100) and salt in Zenmanage
- SDK computes CRC32B bucket from
salt:contextIdentifier - Same user always lands in same bucket
- Increasing percentage only adds users, never removes included users
Use Defaults Across Many Flags
from zenmanage import DefaultsCollection
defaults = DefaultsCollection.from_dict(
{
"new-ui": True,
"api-version": "v2",
"max-items": 100,
}
)
flag_manager = zenmanage.flags().with_defaults(defaults)
new_ui = flag_manager.single("new-ui").as_bool()
Fetch All Flags
for flag in zenmanage.flags().all():
print(flag.key, flag.get_value())
Configuration
import logging
config = (
ConfigBuilder.create()
.with_environment_token("srv_your_server_key_here")
.with_cache_ttl(3600)
.with_cache_backend("memory") # memory | filesystem | null
.with_cache_directory(".cache/zenmanage") # required for filesystem
.with_usage_reporting(True)
.with_api_endpoint("https://api.zenmanage.com")
.with_logger(logging.getLogger("my-app"))
.build()
)
You can also load from environment variables:
ZENMANAGE_ENVIRONMENT_TOKENZENMANAGE_CACHE_TTLZENMANAGE_CACHE_BACKENDZENMANAGE_CACHE_DIRZENMANAGE_ENABLE_USAGE_REPORTINGZENMANAGE_API_ENDPOINT
config = ConfigBuilder.from_environment().build()
Cache Backends
memory: default, fastest, process-localfilesystem: durable between process restartsnull: disables caching
Custom cache objects are supported with with_cache(...) as long as they implement get, set, has, delete, and clear.
Examples
See examples/README.md for runnable examples:
- simple-flags
- ab-testing
- caching
- context-based-flags
- defaults
- percentage-rollouts
- django-integration
- flask-integration
- fastapi-async
Framework integrations: docs/FRAMEWORK_INTEGRATIONS.md
Development
python -m venv .venv
source .venv/bin/activate
pip install -e .[dev]
pytest
ruff check .
mypy src
Publishing
Validate tag/version/changelog consistency locally:
python scripts/validate_release.py --tag v1.0.0
License
MIT
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 zenmanage-1.0.0.tar.gz.
File metadata
- Download URL: zenmanage-1.0.0.tar.gz
- Upload date:
- Size: 24.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f678b3d316bc51e09a224c7ebc228a850502a15444fce655f56c6da86c5b2ae0
|
|
| MD5 |
ea635d9d5f0002010aa563b7036290cf
|
|
| BLAKE2b-256 |
c2cb26c18b5fd8ad62c4f582f67ef3786a8ebaf806b0c01966f58563a560b236
|
File details
Details for the file zenmanage-1.0.0-py3-none-any.whl.
File metadata
- Download URL: zenmanage-1.0.0-py3-none-any.whl
- Upload date:
- Size: 23.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fbd0923b4205cba9cffad7ca3951f6c37cd7e12feab5ab3e8072b461fe50b384
|
|
| MD5 |
4522b2dcb5618059836bc931b4e00b17
|
|
| BLAKE2b-256 |
152b19eba53d4a9b7af238c9c00686720d2abb1e00ddd025e70f8de50ed9f285
|