Skip to content

Commit 6a5f0d7

Browse files
committed
update openfeature test
1 parent c43afbc commit 6a5f0d7

File tree

1 file changed

+187
-16
lines changed

1 file changed

+187
-16
lines changed

example/openfeature_example.py

Lines changed: 187 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,19 +7,30 @@
77
from openfeature import api
88
from openfeature.evaluation_context import EvaluationContext
99

10-
FLAG_KEY = "test-boolean-variable"
11-
1210
logger = logging.getLogger(__name__)
1311

1412

1513
def main():
1614
"""
1715
Sample usage of the DevCycle OpenFeature Provider along with the Python Server SDK using Local Bucketing.
16+
17+
This example demonstrates how to use all variable types supported by DevCycle through OpenFeature:
18+
- Boolean variables
19+
- String variables
20+
- Number variables (integer and float)
21+
- JSON object variables
22+
23+
See DEVCYCLE_SETUP.md for instructions on creating the required variables in DevCycle.
1824
"""
1925
logging.basicConfig(level="INFO", format="%(levelname)s: %(message)s")
2026

2127
# create an instance of the DevCycle Client object
22-
server_sdk_key = os.environ["DEVCYCLE_SERVER_SDK_KEY"]
28+
server_sdk_key = os.environ.get("DEVCYCLE_SERVER_SDK_KEY")
29+
if not server_sdk_key:
30+
logger.error("DEVCYCLE_SERVER_SDK_KEY environment variable is not set")
31+
logger.error("Please set it with: export DEVCYCLE_SERVER_SDK_KEY='your-sdk-key'")
32+
exit(1)
33+
2334
devcycle_client = DevCycleLocalClient(server_sdk_key, DevCycleLocalOptions())
2435

2536
# Wait for DevCycle to initialize and load the configuration
@@ -32,6 +43,8 @@ def main():
3243
logger.error("DevCycle failed to initialize")
3344
exit(1)
3445

46+
logger.info("DevCycle initialized successfully!\n")
47+
3548
# set the provider for OpenFeature
3649
api.set_provider(devcycle_client.get_openfeature_provider())
3750

@@ -53,22 +66,180 @@ def main():
5366
},
5467
)
5568

56-
# Look up the value of the flag
57-
if open_feature_client.get_boolean_value(FLAG_KEY, False, context):
58-
logger.info(f"Variable {FLAG_KEY} is enabled")
69+
logger.info("=" * 60)
70+
logger.info("Testing Boolean Variable")
71+
logger.info("=" * 60)
72+
73+
# Test Boolean Variable
74+
boolean_details = open_feature_client.get_boolean_details(
75+
"test-boolean-variable", False, context
76+
)
77+
logger.info(f"Variable Key: test-boolean-variable")
78+
logger.info(f"Value: {boolean_details.value}")
79+
logger.info(f"Reason: {boolean_details.reason}")
80+
if boolean_details.value:
81+
logger.info("✓ Boolean variable is ENABLED")
5982
else:
60-
logger.info(f"Variable {FLAG_KEY} is not enabled")
61-
62-
# Fetch a JSON object variable
63-
json_object = open_feature_client.get_object_value(
83+
logger.info("✗ Boolean variable is DISABLED")
84+
85+
logger.info("\n" + "=" * 60)
86+
logger.info("Testing String Variable")
87+
logger.info("=" * 60)
88+
89+
# Test String Variable
90+
string_details = open_feature_client.get_string_details(
91+
"test-string-variable", "default string", context
92+
)
93+
logger.info(f"Variable Key: test-string-variable")
94+
logger.info(f"Value: {string_details.value}")
95+
logger.info(f"Reason: {string_details.reason}")
96+
97+
logger.info("\n" + "=" * 60)
98+
logger.info("Testing Number Variable (Integer)")
99+
logger.info("=" * 60)
100+
101+
# Test Number Variable (Integer)
102+
integer_details = open_feature_client.get_integer_details(
103+
"test-number-variable", 0, context
104+
)
105+
logger.info(f"Variable Key: test-number-variable")
106+
logger.info(f"Value: {integer_details.value}")
107+
logger.info(f"Reason: {integer_details.reason}")
108+
109+
logger.info("\n" + "=" * 60)
110+
logger.info("Testing Number Variable (Float)")
111+
logger.info("=" * 60)
112+
113+
# Test Number Variable as Float
114+
# Note: If the DevCycle variable is an integer, it will be cast to float
115+
float_value = open_feature_client.get_float_value(
116+
"test-number-variable", 0.0, context
117+
)
118+
logger.info(f"Variable Key: test-number-variable (as float)")
119+
logger.info(f"Value: {float_value}")
120+
121+
logger.info("\n" + "=" * 60)
122+
logger.info("Testing JSON Object Variable")
123+
logger.info("=" * 60)
124+
125+
# Test JSON Object Variable
126+
json_details = open_feature_client.get_object_details(
64127
"test-json-variable", {"default": "value"}, context
65128
)
66-
logger.info(f"JSON Object Value: {json_object}")
67-
68-
# Retrieve a string variable along with resolution details
69-
details = open_feature_client.get_string_details("doesnt-exist", "default", context)
70-
logger.info(f"String Value: {details.value}")
71-
logger.info(f"Eval Reason: {details.reason}")
129+
logger.info(f"Variable Key: test-json-variable")
130+
logger.info(f"Value: {json_details.value}")
131+
logger.info(f"Reason: {json_details.reason}")
132+
133+
logger.info("\n" + "=" * 60)
134+
logger.info("Testing Object Variable - Empty Dictionary")
135+
logger.info("=" * 60)
136+
137+
# Test with empty dictionary default (valid per OpenFeature spec)
138+
empty_dict_result = open_feature_client.get_object_value(
139+
"test-json-variable", {}, context
140+
)
141+
logger.info(f"Variable Key: test-json-variable (with empty default)")
142+
logger.info(f"Value: {empty_dict_result}")
143+
144+
logger.info("\n" + "=" * 60)
145+
logger.info("Testing Object Variable - Mixed Types")
146+
logger.info("=" * 60)
147+
148+
# Test with flat dictionary containing mixed primitive types
149+
# OpenFeature allows string, int, float, bool, and None in flat dictionaries
150+
mixed_default = {
151+
"string_key": "hello",
152+
"int_key": 42,
153+
"float_key": 3.14,
154+
"bool_key": True,
155+
"none_key": None
156+
}
157+
mixed_result = open_feature_client.get_object_value(
158+
"test-json-variable", mixed_default, context
159+
)
160+
logger.info(f"Variable Key: test-json-variable (with mixed types)")
161+
logger.info(f"Value: {mixed_result}")
162+
logger.info(f"Value types: {[(k, type(v).__name__) for k, v in mixed_result.items()]}")
163+
164+
logger.info("\n" + "=" * 60)
165+
logger.info("Testing Object Variable - All String Values")
166+
logger.info("=" * 60)
167+
168+
# Test with all string values
169+
string_dict_default = {
170+
"name": "John Doe",
171+
"email": "[email protected]",
172+
"status": "active"
173+
}
174+
string_dict_result = open_feature_client.get_object_value(
175+
"test-json-variable", string_dict_default, context
176+
)
177+
logger.info(f"Variable Key: test-json-variable (all strings)")
178+
logger.info(f"Value: {string_dict_result}")
179+
180+
logger.info("\n" + "=" * 60)
181+
logger.info("Testing Object Variable - Numeric Values")
182+
logger.info("=" * 60)
183+
184+
# Test with numeric values (integers and floats)
185+
numeric_dict_default = {
186+
"count": 100,
187+
"percentage": 85.5,
188+
"threshold": 0
189+
}
190+
numeric_dict_result = open_feature_client.get_object_value(
191+
"test-json-variable", numeric_dict_default, context
192+
)
193+
logger.info(f"Variable Key: test-json-variable (numeric)")
194+
logger.info(f"Value: {numeric_dict_result}")
195+
196+
logger.info("\n" + "=" * 60)
197+
logger.info("Testing Object Variable - Boolean Flags")
198+
logger.info("=" * 60)
199+
200+
# Test with boolean values
201+
bool_dict_default = {
202+
"feature_a": True,
203+
"feature_b": False,
204+
"feature_c": True
205+
}
206+
bool_dict_result = open_feature_client.get_object_value(
207+
"test-json-variable", bool_dict_default, context
208+
)
209+
logger.info(f"Variable Key: test-json-variable (booleans)")
210+
logger.info(f"Value: {bool_dict_result}")
211+
212+
logger.info("\n" + "=" * 60)
213+
logger.info("Testing Object Variable - With None Values")
214+
logger.info("=" * 60)
215+
216+
# Test with None values (valid per OpenFeature spec for flat dictionaries)
217+
none_dict_default = {
218+
"optional_field": None,
219+
"required_field": "value",
220+
"nullable_count": None
221+
}
222+
none_dict_result = open_feature_client.get_object_value(
223+
"test-json-variable", none_dict_default, context
224+
)
225+
logger.info(f"Variable Key: test-json-variable (with None)")
226+
logger.info(f"Value: {none_dict_result}")
227+
228+
logger.info("\n" + "=" * 60)
229+
logger.info("Testing Non-Existent Variable (Should Return Default)")
230+
logger.info("=" * 60)
231+
232+
# Test non-existent variable to demonstrate default handling
233+
nonexistent_details = open_feature_client.get_string_details(
234+
"doesnt-exist", "default fallback value", context
235+
)
236+
logger.info(f"Variable Key: doesnt-exist")
237+
logger.info(f"Value: {nonexistent_details.value}")
238+
logger.info(f"Reason: {nonexistent_details.reason}")
239+
240+
logger.info("\n" + "=" * 60)
241+
logger.info("All tests completed!")
242+
logger.info("=" * 60)
72243

73244
devcycle_client.close()
74245

0 commit comments

Comments
 (0)