Skip to main content

Official Python SDK for Zenmanage feature flags with local evaluation

Project description

Zenmanage Python SDK

PyPI version CI Codacy Badge Coverage

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

  1. Get your server key (srv_...) from zenmanage.com
  2. Initialize the SDK:
from zenmanage import ConfigBuilder, Zenmanage

zenmanage = Zenmanage(
    ConfigBuilder.create()
    .with_environment_token("srv_your_server_key_here")
    .build()
)
  1. 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_TOKEN
  • ZENMANAGE_CACHE_TTL
  • ZENMANAGE_CACHE_BACKEND
  • ZENMANAGE_CACHE_DIR
  • ZENMANAGE_ENABLE_USAGE_REPORTING
  • ZENMANAGE_API_ENDPOINT
config = ConfigBuilder.from_environment().build()

Cache Backends

  • memory: default, fastest, process-local
  • filesystem: durable between process restarts
  • null: 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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

zenmanage-1.0.0.tar.gz (24.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

zenmanage-1.0.0-py3-none-any.whl (23.9 kB view details)

Uploaded Python 3

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

Hashes for zenmanage-1.0.0.tar.gz
Algorithm Hash digest
SHA256 f678b3d316bc51e09a224c7ebc228a850502a15444fce655f56c6da86c5b2ae0
MD5 ea635d9d5f0002010aa563b7036290cf
BLAKE2b-256 c2cb26c18b5fd8ad62c4f582f67ef3786a8ebaf806b0c01966f58563a560b236

See more details on using hashes here.

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

Hashes for zenmanage-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 fbd0923b4205cba9cffad7ca3951f6c37cd7e12feab5ab3e8072b461fe50b384
MD5 4522b2dcb5618059836bc931b4e00b17
BLAKE2b-256 152b19eba53d4a9b7af238c9c00686720d2abb1e00ddd025e70f8de50ed9f285

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page