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.4.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.4-py3-none-any.whl (67.1 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: flagkit-1.0.4.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.4.tar.gz
Algorithm Hash digest
SHA256 8c333d3e93bbdf576da390f4f8ff6fb304a54dfa9af32e8eb6976b16705ea98a
MD5 325e2a2a07e09b25464870f70c249094
BLAKE2b-256 372ab786f8736df5bb932d373963d511ee6354224bf76f9ad3c2cd1ccfbdf625

See more details on using hashes here.

File details

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

File metadata

  • Download URL: flagkit-1.0.4-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.4-py3-none-any.whl
Algorithm Hash digest
SHA256 00b8f25f3504e5da93d38797c3b194fd13652365ac8d6a0ea9ab8c3be0e0c909
MD5 06e7b0cbe6ca8a5c26fc60b55d35d90a
BLAKE2b-256 0f772003ac5c9ed65e0bcd082853181cdad6bc4cd2e5a9cdff89f9b74e0dc9fc

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