Assignments
Assignments are the mechanism through which a given Subject is assigned to a variation for a feature flag or experiment.
The Eppo SDK supports the following assignment types:
- String
- Boolean
- JSON
- Integer
- Numeric
Assignment Types
String Assignments
String assignments return a string value that is set as the variation. String flags are the most common type of flags and are useful for both A/B/n tests and advanced targeting use cases.
import eppo_client
client = eppo_client.get_instance()
flag_key = "flag-key-123"
subject_key = get_user_id() or "user-123"
default_value = "version-a"
subject_attributes = {
"country": "US",
"age": 30,
"is_returning_user": True
}
variant = client.get_string_assignment(
flag_key,
subject_key,
subject_attributes,
default_value
)
# Use the variant value to determine which component to render
if variant == "version-a":
handle_version_a()
elif variant == "version-b":
handle_version_b()
Boolean Assignments
Boolean flags support simple on/off toggles. They're useful for simple, binary feature switches like blue/green deployments or enabling/disabling a new feature.
variant = client.get_boolean_assignment(
flag_key,
subject_key,
subject_attributes,
False # default value
)
if variant:
handle_feature_enabled()
else:
handle_feature_disabled()
JSON Assignments
JSON flags work best for advanced configuration use cases. The JSON flag can include structured information such as:
- Marketing copy for a promotional campaign
- Configuration parameters for a feature
- UI customization settings
default_campaign = {
"hero": False,
"hero_image": "placeholder.png",
"hero_title": "Placeholder Hero Title",
"hero_description": "Placeholder Hero Description"
}
campaign_json = client.get_json_assignment(
flag_key,
subject_key,
subject_attributes,
default_campaign
)
if campaign_json is not None:
campaign.hero = True
campaign.hero_image = campaign_json.get("hero_image")
campaign.hero_title = campaign_json.get("hero_title", "")
campaign.hero_description = campaign_json.get("hero_description", "")
Numeric Assignments
The SDK provides both integer and floating-point numeric assignments. These are useful for testing different numeric values like:
- Price points
- Number of items to display
- Timeout durations
# Integer assignment example
num_items = client.get_integer_assignment(
flag_key,
subject_key,
subject_attributes,
10 # default value
)
# Floating point assignment example
price = client.get_numeric_assignment(
flag_key,
subject_key,
subject_attributes,
9.99 # default value
)
Assignment Logging
Assignment Logger Schema
The SDK will invoke the log_assignment
function with an assignment
dictionary that contains the following fields:
timestamp
strDefault: undefined
The time when the subject was assigned to the variation in ISO format. Example: "2021-06-22T17:35:12.000Z"
featureFlag
strDefault: undefined
An Eppo feature flag key. Example: "recommendation-algo"
allocation
strDefault: undefined
An Eppo allocation key. Example: "allocation-17"
experiment
strDefault: undefined
An Eppo experiment key. Example: "recommendation-algo-allocation-17"
subject
strDefault: undefined
An identifier of the subject or user assigned to the experiment variation. Example: UUID
subjectAttributes
Dict[str, Any]Default: {}
A free-form map of metadata about the subject. These attributes are only logged if passed to the SDK assignment function. Example: { "country": "US" }
variation
strDefault: undefined
The experiment variation the subject was assigned to. Example: "control"
metaData
Dict[str, Any]Default: {sdkName: 'python'}
A free-form map of metadata about the assignment. By default, the SDK will include the SDK name for logging.
Logging to Your Data Warehouse
Eppo's architecture ensures that raw user data never leaves your system. Instead of pushing subject-level exposure events to Eppo's servers, Eppo's SDKs integrate with your existing logging system.
Here are examples of implementing the AssignmentLogger
class for different logging systems:
- Console
- Segment
- Snowplow
from eppo_client import AssignmentLogger
class ConsoleLogger(AssignmentLogger):
def log_assignment(self, assignment):
print(f"Assignment: {assignment}")
import analytics
from eppo_client import AssignmentLogger
analytics.write_key = '<SEGMENT_WRITE_KEY>'
class SegmentLogger(AssignmentLogger):
def log_assignment(self, assignment):
analytics.track(
assignment["subject"],
"Eppo Randomization Event",
assignment
)
from snowplow_tracker import Tracker, Emitter
from eppo_client import AssignmentLogger
emitter = Emitter("collector.mydomain.net")
tracker = Tracker(emitters=emitter, namespace="eppo", app_id="eppo-app")
class SnowplowLogger(AssignmentLogger):
def log_assignment(self, assignment):
tracker.track_self_describing_event({
"schema": "iglu:com.example_company/eppo-event/jsonschema/1-0-2",
"data": {
"userId": assignment["subject"],
"properties": assignment
}
})
Deduplicating Logs
To prevent duplicate assignment events, the SDK provides a caching assignment logger with configurable cache behavior:
import cachetools
from eppo_client import AssignmentLogger, AssignmentCacheLogger
class MyLogger(AssignmentLogger):
def log_assignment(self, assignment):
# Your logging implementation
pass
client_config = Config(
api_key="<SDK-KEY>",
assignment_logger=AssignmentCacheLogger(
MyLogger(),
# Cache 1024 least recently used assignments
assignment_cache=cachetools.LRUCache(maxsize=1024),
# Cache bandit assignments for 10 minutes
bandit_cache=cachetools.TTLCache(maxsize=2048, ttl=600)
)
)
Debugging Assignments
Starting with v4.0.0, the SDK provides detailed assignment information to help debug why a specific variation was chosen:
evaluation = client.get_boolean_assignment_details(
"kill-switch",
"test-subject",
{"country": "UK", "age": 62},
False
)
print("Assignment:", evaluation.variation)
print("Details:", evaluation.evaluation_details)
The evaluation details include:
- Flag and subject information
- Timestamp and configuration metadata
- Allocation evaluation results
- Rule matching details
- Split calculations
For more information on debugging assignments, see Debugging Flag Assignments.