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

Uploaded Python 3

File details

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

File metadata

  • Download URL: flagkit-1.0.2.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.2.tar.gz
Algorithm Hash digest
SHA256 48e86ff1c1e23ff93590d854c53bd8caeac31b1d87f681407cb7122efc3bae35
MD5 eaf90b1e053e9ef4db60ac2e506180c1
BLAKE2b-256 77075673490da1b5ab8d19e4b286cc516731b9eb6e70d404d1f3a51143b0cd46

See more details on using hashes here.

File details

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

File metadata

  • Download URL: flagkit-1.0.2-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.2-py3-none-any.whl
Algorithm Hash digest
SHA256 a6700f57a265e32d9177aa4f7d31186bba49f6ce64ba95a2b11d9a1b186e558d
MD5 996809ffea15bb7b4383a315f60ca7ac
BLAKE2b-256 b36d6922d7be88f80664f50c852cc6481983932394315fa6d95b59fcf88d3ef5

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