Skip to main content

FlagKit SDK for Python - Feature flag evaluation and analytics

Project description

FlagKit Python SDK

Official Python SDK for FlagKit - Feature flag management made simple.

Installation

pip install flagkit

Requirements

  • Python 3.9+
  • httpx (automatically installed)
  • cryptography (automatically installed, for cache encryption)

Quick Start

from flagkit import FlagKit

# Initialize the SDK
client = FlagKit.initialize(
    api_key="sdk_your_api_key",
    polling_interval=30,  # seconds
    cache_ttl=300,        # seconds
)

# Wait for initialization
client.wait_for_ready()

# Identify a user
client.identify("user-123", {"plan": "premium"})

# Evaluate flags
dark_mode = client.get_boolean_value("dark-mode", default=False)
welcome_message = client.get_string_value("welcome-message", default="Hello!")
max_items = client.get_number_value("max-items", default=10)
config = client.get_json_value("feature-config", default={})

# Get full evaluation details
result = client.evaluate("dark-mode")
print(f"Value: {result.value}, Reason: {result.reason}")

# Track custom events
client.track("button_clicked", {"button": "signup"})

# Cleanup when done
client.close()

Features

  • Type-safe evaluation - Boolean, string, number, and JSON flag types
  • Local caching - Fast evaluations with configurable TTL and optional encryption
  • Background polling - Automatic flag updates with jitter
  • Event tracking - Analytics with batching and crash-resilient persistence
  • Resilient - Circuit breaker, retry with exponential backoff, offline support
  • Thread-safe - Safe for concurrent use

API Reference

Initialization

from flagkit import FlagKit

# Using the static factory (recommended)
client = FlagKit.initialize(
    api_key="sdk_...",              # Required
    base_url="https://api.flagkit.dev/api/v1",  # Optional
    polling_interval=30.0,          # Seconds between polls
    enable_polling=True,            # Enable background polling
    cache_enabled=True,             # Enable local caching
    cache_ttl=300.0,                # Cache TTL in seconds
    offline=False,                  # Offline mode
    timeout=5.0,                    # Request timeout in seconds
    retries=3,                      # Number of retries
    bootstrap={"flag": True},       # Initial flag values
    debug=False,                    # Enable debug logging
    on_ready=lambda: print("Ready!"),
    on_error=lambda e: print(f"Error: {e}"),
    on_update=lambda flags: print(f"Updated: {len(flags)} flags"),
)

Flag Evaluation

# Boolean flags
enabled = client.get_boolean_value("feature-flag", default=False)

# String flags
variant = client.get_string_value("button-text", default="Click")

# Number flags
limit = client.get_number_value("rate-limit", default=100)

# JSON flags
config = client.get_json_value("config", default={"enabled": False})

# Full evaluation result
result = client.evaluate("feature-flag")
# result.flag_key, result.value, result.enabled, result.reason, result.version

# Evaluate all flags
all_results = client.evaluate_all()

# Check flag existence
if client.has_flag("my-flag"):
    # ...

# Get all flag keys
keys = client.get_all_flag_keys()

Context Management

from flagkit import EvaluationContext

# Set global context
context = EvaluationContext(
    user_id="user-123",
    email="user@example.com",
    country="US",
    custom={"plan": "premium", "beta_tester": True},
    private_attributes=["email"],  # Not sent to server
)
client.set_context(context)

# Get current context
current = client.get_context()

# Clear context
client.clear_context()

# Identify user (shorthand)
client.identify("user-123", {"email": "user@example.com"})

# Reset to anonymous
client.reset()

# Pass context to evaluation
result = client.get_boolean_value(
    "feature-flag",
    default=False,
    context=EvaluationContext(user_id="other-user"),
)

Event Tracking

# Track custom event
client.track("purchase", {
    "amount": 99.99,
    "currency": "USD",
    "product_id": "prod-123",
})

# Force flush pending events
client.flush()

Lifecycle

# Check if SDK is ready
if client.is_ready():
    # ...

# Wait for ready (blocks until initialized)
client.wait_for_ready()

# Force refresh flags from server
client.refresh()

# Close SDK and cleanup
client.close()

Error Handling

from flagkit import FlagKitError, InitializationError, NetworkError

try:
    client = FlagKit.initialize(api_key="sdk_...")
except InitializationError as e:
    print(f"Failed to initialize: {e.code} - {e}")
except NetworkError as e:
    if e.recoverable:
        # Retry logic
        pass
except FlagKitError as e:
    print(f"Error [{e.code}]: {e}")
    print(f"Recoverable: {e.recoverable}")
    print(f"Details: {e.to_dict()}")

Local Development

# Connect to local FlagKit server at http://localhost:8200/api/v1
client = FlagKit.initialize(
    api_key="sdk_...",
    local_port=8200,
)

# Or use a custom port
client = FlagKit.initialize(
    api_key="sdk_...",
    local_port=3000,  # Uses http://localhost:3000/api/v1
)

Offline Mode

# Start in offline mode
client = FlagKit.initialize(
    api_key="sdk_...",
    offline=True,
    bootstrap={"feature-flag": True},
)

# Uses bootstrap values without network requests
value = client.get_boolean_value("feature-flag", default=False)

PII Detection

The SDK can detect and warn about potential PII in contexts and events:

# Enable strict PII mode - raises errors instead of warnings
client = FlagKit.initialize(
    api_key="sdk_...",
    strict_pii_mode=True,
)

# Use private attributes to mark fields as intentionally containing PII
context = EvaluationContext(
    user_id="user-123",
    email="user@example.com",
    private_attributes=["email"],  # Marks email as intentionally private
)

Request Signing

POST requests to the FlagKit API are signed with HMAC-SHA256 for integrity. This is enabled by default and can be disabled via the enable_request_signing option.

Thread Safety

All SDK methods are safe for concurrent use from multiple threads. The client uses internal synchronization (threading.Lock) to ensure thread-safe access to:

  • Flag cache
  • Event queue
  • Context management
  • Polling state

License

MIT License - see LICENSE for details.

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

flagkit-1.0.7.tar.gz (52.2 kB view details)

Uploaded Source

Built Distribution

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

flagkit-1.0.7-py3-none-any.whl (67.1 kB view details)

Uploaded Python 3

File details

Details for the file flagkit-1.0.7.tar.gz.

File metadata

  • Download URL: flagkit-1.0.7.tar.gz
  • Upload date:
  • Size: 52.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.14

File hashes

Hashes for flagkit-1.0.7.tar.gz
Algorithm Hash digest
SHA256 9067d712f05e55216e43a49d06d366e1b1ce5f587ceaa1922ab37eddb5abf86f
MD5 1c1e1b5ce78f7fde44a9e6933d85480d
BLAKE2b-256 2ddcebaa29acca59978f3935aff1baf5555388648fca7ef76f5c827b6a591194

See more details on using hashes here.

File details

Details for the file flagkit-1.0.7-py3-none-any.whl.

File metadata

  • Download URL: flagkit-1.0.7-py3-none-any.whl
  • Upload date:
  • Size: 67.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.14

File hashes

Hashes for flagkit-1.0.7-py3-none-any.whl
Algorithm Hash digest
SHA256 37a4743fc705013b26e49cba12f344a3ef084199154fd3d72fa7b238577bd87a
MD5 61d47cdbfae576d0a1691e9e6c9736d9
BLAKE2b-256 48b35baef88101e908268dbb06cebe29e8bb4079f4e5cc4dc4eb2c0d309e31e2

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