Differences between Python SDK 3.x and 4.x
The Python SDK 4.0 provides significant improvements over previous versions through its rewrite using a shared Eppo core library written in Rust.
Key improvements
- Better Performance: Assignment evaluation is 2-5x faster than previous versions
- Improved Stability: The shared core library provides more robust and reliable operation
- Background Updates: Configuration updates run in a separate thread without blocking the Global Interpreter Lock (GIL)
- Faster Feature Delivery: The shared core architecture allows us to roll out new features more quickly across all SDKs
New API
Evaluation details
Python SDK now support evaluation details.
EppoClient
exposes a set of new methods:
get_string_assignment_details()
get_integer_assignment_details()
get_numeric_assignment_details()
get_boolean_assignment_details()
get_json_assignment_details()
get_bandit_action_details()
These methods trace the evaluation process and collect tons of details (down to individual conditions). All this information is extremely helpful to debug why a specific variation was chosen. However the tracing adds a slight performance overhead, so you should prefer non-detailed methods in production.
All details methods return EvaluationResult
with evaluation details stored in evaluation_details
field:
evaluation = client.get_boolean_assignment_details(
"kill-switch", "test-subject", {"country": "UK", "age": 62}, False
)
print("assignment:", evaluation.variation)
pprint.pp(evaluation.evaluation_details)
Prints the following:
assignment: True
{'flagKey': 'kill-switch',
'subjectKey': 'test-subject',
'subjectAttributes': {'age': 62.0, 'country': 'UK'},
'timestamp': '2024-09-09T14:34:15.983952Z',
'configFetchedAt': '2024-09-09T14:34:15.983905Z',
'configPublishedAt': '2024-04-17T19:40:53.716Z',
'environmentName': 'Test',
'banditEvaluationCode': None,
'flagEvaluationCode': 'MATCH',
'flagEvaluationDescription': 'Supplied attributes match rules defined in '
'allocation "on-for-age-50+".',
'variationKey': 'on',
'variationValue': True,
'banditKey': None,
'banditAction': None,
'allocations': [{'key': 'on-for-NA',
'orderPosition': 1,
'allocationEvaluationCode': 'FAILING_RULE',
'evaluatedRules': [{'matched': False,
'conditions': [{'condition': {'operator': 'ONE_OF',
'attribute': 'country',
'value': ['US',
'Canada',
'Mexico']},
'attributeValue': 'UK',
'matched': False}]}],
'evaluatedSplits': []},
{'key': 'on-for-age-50+',
'orderPosition': 2,
'allocationEvaluationCode': 'MATCH',
'evaluatedRules': [{'matched': True,
'conditions': [{'condition': {'operator': 'GTE',
'attribute': 'age',
'value': 50.0},
'attributeValue': 62.0,
'matched': True}]}],
'evaluatedSplits': [{'variationKey': 'on',
'matched': True,
'shards': [{'matched': True,
'shard': {'salt': 'some-salt',
'ranges': [{'start': 0,
'end': 10000}]},
'shardValue': 1191}]}]},
{'key': 'off-for-all',
'orderPosition': 3,
'allocationEvaluationCode': 'UNEVALUATED',
'evaluatedRules': [],
'evaluatedSplits': []}]}
Wait for initialization
EppoClient
has a new wait_for_initialization()
method. This method parks the current Python thread until the client fetches the configuration. It releases Global Interpreter Lock (GIL) while it waits, so it does not block other Python threads.
If you used sleep
to wait for EppoClient
initialization before getting assignments, you may replace it with client.wait_for_initialization()
now.
Configuration API
This release extends advanced configuration control API introduced in 3.7.0.
EppoClient
now exposes get_configuration()
method that returns currently-active configuration.
Configuration
now exposes new methods:
get_flags_configuration()
get_flag_keys()
get_bandit_keys()
This API can be used for debugging or advanced optimizations: caching configuration, faster client-side initialization from server configuration, etc.