Skip to content

Commit 070447d

Browse files
authored
Merge pull request #604 from splitio/development
Development
2 parents 400a105 + a13509b commit 070447d

File tree

5 files changed

+71
-4
lines changed

5 files changed

+71
-4
lines changed

CHANGES.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
10.5.1 (Oct 15, 2025)
2+
- Added using String only parameter for treatments in FallbackTreatmentConfiguration class.
3+
14
10.5.0 (Sep 15, 2025)
25
- Changed the log level from error to debug when renewing the token for Streaming service in asyncio mode.
36
- Added new configuration for Fallback Treatments, which allows setting a treatment value and optional config to be returned in place of "control", either globally or by flag. Read more in our docs.

splitio/models/fallback_config.py

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ def __init__(self, global_fallback_treatment=None, by_flag_fallback_treatment=No
1515
:param by_flag_fallback_treatment: Dict of flags and their fallback treatment
1616
:type by_flag_fallback_treatment: {str: FallbackTreatment}
1717
"""
18-
self._global_fallback_treatment = global_fallback_treatment
19-
self._by_flag_fallback_treatment = by_flag_fallback_treatment
18+
self._global_fallback_treatment = self._build_global_fallback(global_fallback_treatment)
19+
self._by_flag_fallback_treatment = self._build_by_flag_fallback(by_flag_fallback_treatment)
2020

2121
@property
2222
def global_fallback_treatment(self):
@@ -37,7 +37,26 @@ def by_flag_fallback_treatment(self):
3737
def by_flag_fallback_treatment(self, new_value):
3838
"""Set global fallback treatment."""
3939
self.by_flag_fallback_treatment = new_value
40-
40+
41+
def _build_global_fallback(self, global_fallback_treatment):
42+
if isinstance(global_fallback_treatment, str):
43+
return FallbackTreatment(global_fallback_treatment)
44+
45+
return global_fallback_treatment
46+
47+
def _build_by_flag_fallback(self, by_flag_fallback_treatment):
48+
if not isinstance(by_flag_fallback_treatment, dict):
49+
return by_flag_fallback_treatment
50+
51+
parsed_by_flag_fallback = {}
52+
for key, value in by_flag_fallback_treatment.items():
53+
if isinstance(value, str):
54+
parsed_by_flag_fallback[key] = FallbackTreatment(value)
55+
else:
56+
parsed_by_flag_fallback[key] = value
57+
58+
return parsed_by_flag_fallback
59+
4160
class FallbackTreatmentCalculator(object):
4261
"""FallbackTreatmentCalculator object class."""
4362

splitio/version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = '10.5.0'
1+
__version__ = '10.5.1'

tests/integration/test_client_e2e.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1393,6 +1393,27 @@ def test_localhost_e2e(self):
13931393
factory.destroy(event)
13941394
event.wait()
13951395

1396+
def test_fallback_treatments(self):
1397+
"""Instantiate a client with a JSON file and issue get_treatment() calls."""
1398+
self._update_temp_file(splits_json['splitChange2_1'])
1399+
filename = os.path.join(os.path.dirname(__file__), 'files', 'split_changes_temp.json')
1400+
factory = get_factory('localhost',
1401+
config={
1402+
'splitFile': filename,
1403+
'fallbackTreatments': FallbackTreatmentsConfiguration("on-global", {'fallback_feature': "on-local"})
1404+
}
1405+
)
1406+
factory.block_until_ready(1)
1407+
client = factory.client()
1408+
1409+
assert client.get_treatment("key", "feature") == "on-global"
1410+
assert client.get_treatment("key", "fallback_feature") == "on-local"
1411+
1412+
event = threading.Event()
1413+
factory.destroy(event)
1414+
event.wait()
1415+
1416+
13961417
class PluggableIntegrationTests(object):
13971418
"""Pluggable storage-based integration tests."""
13981419

@@ -3335,6 +3356,23 @@ async def test_localhost_e2e(self):
33353356
assert split.configs == {}
33363357
await factory.destroy()
33373358

3359+
@pytest.mark.asyncio
3360+
async def test_fallback_treatments(self):
3361+
"""Instantiate a client with a JSON file and issue get_treatment() calls."""
3362+
self._update_temp_file(splits_json['splitChange2_1'])
3363+
filename = os.path.join(os.path.dirname(__file__), 'files', 'split_changes_temp.json')
3364+
factory = await get_factory_async('localhost',
3365+
config={
3366+
'splitFile': filename,
3367+
'fallbackTreatments': FallbackTreatmentsConfiguration("on-global", {'fallback_feature': "on-local"})
3368+
}
3369+
)
3370+
await factory.block_until_ready(1)
3371+
client = factory.client()
3372+
3373+
assert await client.get_treatment("key", "feature") == "on-global"
3374+
assert await client.get_treatment("key", "fallback_feature") == "on-local"
3375+
await factory.destroy()
33383376

33393377
class PluggableIntegrationAsyncTests(object):
33403378
"""Pluggable storage-based integration tests."""

tests/models/test_fallback.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,13 @@ def test_working(self):
2828

2929
fallback_config.by_flag_fallback_treatment["flag2"] = flag_fb
3030
assert fallback_config.by_flag_fallback_treatment == {"flag1": flag_fb, "flag2": flag_fb}
31+
32+
fallback_config = FallbackTreatmentsConfiguration("on", {"flag1": "off"})
33+
assert isinstance(fallback_config.global_fallback_treatment, FallbackTreatment)
34+
assert fallback_config.global_fallback_treatment.treatment == "on"
35+
36+
assert isinstance(fallback_config.by_flag_fallback_treatment["flag1"], FallbackTreatment)
37+
assert fallback_config.by_flag_fallback_treatment["flag1"].treatment == "off"
3138

3239

3340
class FallbackTreatmentCalculatorTests(object):

0 commit comments

Comments
 (0)