Skip to content
This repository was archived by the owner on Nov 8, 2024. It is now read-only.

Commit 8b221aa

Browse files
authored
Implement allow list (#7)
* implement allowlist * fix type error
1 parent 7947d6b commit 8b221aa

File tree

3 files changed

+30
-0
lines changed

3 files changed

+30
-0
lines changed

eppo_client/client.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import hashlib
12
from typing import Optional
23
from eppo_client.configuration_requestor import (
34
ExperimentConfigurationDto,
@@ -37,6 +38,9 @@ def assign(self, subject: str, experiment_key: str) -> Optional[str]:
3738
)
3839
):
3940
return None
41+
override = self._get_subject_variation_override(experiment_config, subject)
42+
if override:
43+
return override
4044
shard = get_shard(
4145
"assignment-{}-{}".format(subject, experiment_key),
4246
experiment_config.subject_shards,
@@ -56,6 +60,14 @@ def _shutdown(self):
5660
"""
5761
self.__poller.stop()
5862

63+
def _get_subject_variation_override(
64+
self, experiment_config: ExperimentConfigurationDto, subject: str
65+
) -> Optional[str]:
66+
subject_hash = hashlib.md5(subject.encode("utf-8")).hexdigest()
67+
if subject_hash in experiment_config.overrides:
68+
return experiment_config.overrides[subject_hash]
69+
return None
70+
5971
def _is_in_experiment_sample(
6072
self,
6173
subject: str,

eppo_client/configuration_requestor.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ class ExperimentConfigurationDto(SdkBaseModel):
2020
enabled: bool
2121
variations: List[VariationDto]
2222
name: Optional[str]
23+
overrides: Dict[str, str] = {}
2324

2425

2526
RAC_ENDPOINT = "/randomized_assignment/config"

test/client_test.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,11 +75,28 @@ def test_assign_subject_not_in_sample(mock_config_requestor):
7575
VariationDto(name="control", shardRange=ShardRange(start=0, end=100))
7676
],
7777
name="recommendation_algo",
78+
overrides=dict(),
7879
)
7980
client = EppoClient(config_requestor=mock_config_requestor)
8081
assert client.assign("user-1", "experiment-key-1") is None
8182

8283

84+
@patch("eppo_client.configuration_requestor.ExperimentConfigurationRequestor")
85+
def test_with_subject_in_overrides(mock_config_requestor):
86+
mock_config_requestor.get_configuration.return_value = ExperimentConfigurationDto(
87+
subjectShards=10000,
88+
percentExposure=100,
89+
enabled=True,
90+
variations=[
91+
VariationDto(name="control", shardRange=ShardRange(start=0, end=100))
92+
],
93+
name="recommendation_algo",
94+
overrides={"d6d7705392bc7af633328bea8c4c6904": "override-variation"},
95+
)
96+
client = EppoClient(config_requestor=mock_config_requestor)
97+
assert client.assign("user-1", "experiment-key-1") == "override-variation"
98+
99+
83100
@pytest.mark.parametrize("test_case", test_data)
84101
def test_assign_subject_in_sample(test_case):
85102
print("---- Test case for {} Experiment".format(test_case["experiment"]))

0 commit comments

Comments
 (0)