Skip to content

Commit 0b01169

Browse files
committed
feat: misc-improvement
1 parent fece10c commit 0b01169

5 files changed

Lines changed: 38 additions & 47 deletions

File tree

src/edge_proxy/cache.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from abc import ABC
1+
from abc import ABC, abstractmethod
22
from typing import Any
33

44
from edge_proxy.feature_utils import build_feature_types_lookup
@@ -25,18 +25,18 @@ def put_environment(
2525
return True
2626
return False
2727

28+
@abstractmethod
2829
def _put_environment(
2930
self,
3031
environment_api_key: str,
3132
environment_document: dict[str, Any],
32-
) -> None:
33-
raise NotImplementedError()
33+
) -> None: ...
3434

35-
def get_environment(self, environment_api_key: str) -> dict[str, Any] | None:
36-
raise NotImplementedError()
35+
@abstractmethod
36+
def get_environment(self, environment_api_key: str) -> dict[str, Any] | None: ...
3737

38-
def get_feature_types(self, environment_api_key: str) -> dict[int, str] | None:
39-
return None
38+
@abstractmethod
39+
def get_feature_types(self, environment_api_key: str) -> dict[int, str] | None: ...
4040

4141

4242
_LocalCacheDict = dict[str, dict[str, Any]]

src/edge_proxy/environments.py

Lines changed: 24 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@
3333
SERVER_API_KEY_PREFIX = "ser."
3434

3535

36+
def _get_hide_disabled_flags(environment_document: dict[str, Any]) -> bool:
37+
return environment_document.get("project", {}).get("hide_disabled_flags", False)
38+
39+
3640
class EnvironmentService:
3741
def __init__(
3842
self,
@@ -77,26 +81,25 @@ async def refresh_environment_caches(self):
7781
self.last_updated_at = datetime.now()
7882

7983
def get_flags_response_data(
80-
self, environment_key: str, feature: str = ""
84+
self, environment_key: str, feature: str | None = None
8185
) -> dict[str, Any] | list[dict[str, Any]]:
82-
environment_document = self.get_environment(environment_key=environment_key)
83-
8486
is_server_key = environment_key.startswith(SERVER_API_KEY_PREFIX)
87+
if is_server_key:
88+
environment_key = self._get_client_key_from_server_key(environment_key)
89+
90+
environment_document = self.get_environment(environment_key=environment_key)
8591
server_key_only_feature_ids = environment_document.get("project", {}).get(
8692
"server_key_only_feature_ids", []
8793
)
94+
hide_disabled_flags = _get_hide_disabled_flags(environment_document)
8895

8996
context = map_environment_document_to_context(environment_document)
9097
evaluation_result = get_evaluation_result(context)
9198

92-
feature_types = None
93-
if hasattr(self.cache, "get_feature_types"):
94-
feature_types = self.cache.get_feature_types(environment_key)
99+
feature_types = self.cache.get_feature_types(environment_key)
95100
if feature_types is None:
96101
feature_types = build_feature_types_lookup(environment_document)
97102

98-
data: dict[str, Any] | list[dict[str, Any]]
99-
100103
if feature:
101104
if feature not in evaluation_result["flags"]:
102105
raise FeatureNotFoundError()
@@ -110,38 +113,31 @@ def get_flags_response_data(
110113
if not filtered:
111114
raise FeatureNotFoundError()
112115

113-
hide_disabled_flags = environment_document.get("project", {}).get(
114-
"hide_disabled_flags", False
115-
)
116116
if hide_disabled_flags and not flag_result.get("enabled", False):
117117
raise FeatureNotFoundError()
118118

119-
data = map_flag_result_to_response_data(flag_result, feature_types)
119+
return map_flag_result_to_response_data(flag_result, feature_types)
120120

121-
else:
122-
flags = list(evaluation_result["flags"].values())
123-
124-
if not is_server_key:
125-
flags = filter_out_server_key_only_flags(
126-
flags, server_key_only_feature_ids
127-
)
128-
hide_disabled_flags = environment_document.get("project", {}).get(
129-
"hide_disabled_flags", False
130-
)
131-
flags = filter_disabled_flags(flags, hide_disabled_flags)
121+
flags = list(evaluation_result["flags"].values())
132122

133-
data = map_flag_results_to_response_data(flags, feature_types)
123+
if not is_server_key:
124+
flags = filter_out_server_key_only_flags(flags, server_key_only_feature_ids)
125+
flags = filter_disabled_flags(flags, hide_disabled_flags)
134126

135-
return data
127+
return map_flag_results_to_response_data(flags, feature_types)
136128

137129
def get_identity_response_data(
138130
self, input_data: IdentityWithTraits, environment_key: str
139131
) -> dict[str, Any]:
140-
environment_document = self.get_environment(environment_key=environment_key)
141132
is_server_key = environment_key.startswith(SERVER_API_KEY_PREFIX)
133+
if is_server_key:
134+
environment_key = self._get_client_key_from_server_key(environment_key)
135+
136+
environment_document = self.get_environment(environment_key=environment_key)
142137
server_key_only_feature_ids = environment_document.get("project", {}).get(
143138
"server_key_only_feature_ids", []
144139
)
140+
hide_disabled_flags = _get_hide_disabled_flags(environment_document)
145141

146142
environment_context = map_environment_document_to_context(environment_document)
147143
context = map_context_and_identity_data_to_context(
@@ -151,25 +147,19 @@ def get_identity_response_data(
151147
)
152148
evaluation_result = get_evaluation_result(context)
153149

154-
feature_types = None
155-
if hasattr(self.cache, "get_feature_types"):
156-
feature_types = self.cache.get_feature_types(environment_key)
150+
feature_types = self.cache.get_feature_types(environment_key)
157151
if feature_types is None:
158152
feature_types = build_feature_types_lookup(environment_document)
159153

160154
flags = list(evaluation_result["flags"].values())
161155
if not is_server_key:
162156
flags = filter_out_server_key_only_flags(flags, server_key_only_feature_ids)
163-
hide_disabled_flags = environment_document.get("project", {}).get(
164-
"hide_disabled_flags", False
165-
)
166157
flags = filter_disabled_flags(flags, hide_disabled_flags)
167158

168-
data = {
159+
return {
169160
"traits": map_traits_to_response_data(input_data.traits),
170161
"flags": map_flag_results_to_response_data(flags, feature_types),
171162
}
172-
return data
173163

174164
def get_environment(
175165
self,

src/edge_proxy/mappers.py

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,8 @@
11
from typing import Any
2+
23
from flag_engine.engine import ContextValue
34
from flag_engine.result.types import FlagResult
45

5-
from edge_proxy.schemas import APIFeatureStateSchema
6-
7-
_api_feature_state_schema = APIFeatureStateSchema()
8-
96

107
def map_flag_result_to_response_data(
118
flag_result: FlagResult[Any],
@@ -37,5 +34,4 @@ def map_flag_results_to_response_data(
3734
def map_traits_to_response_data(
3835
traits: dict[str, ContextValue],
3936
) -> list[dict[str, Any]]:
40-
"""Convert traits dict to API response format (list of trait objects)."""
4137
return [{"trait_key": k, "trait_value": v} for k, v in traits.items()]

tests/conftest.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ def environment_service() -> "EnvironmentService":
7070

7171

7272
@pytest.fixture
73-
def mocked_environment_cache(mocker: MockerFixture):
73+
def mocked_environment_cache(mocker: MockerFixture) -> typing.Any:
7474
mock = mocker.patch("edge_proxy.server.environment_service.cache")
7575
mock.get_environment.return_value = None
7676
mock.get_feature_types.return_value = None

tests/test_server.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,11 @@ def test_get_flags__server_key__hide_disabled_flags_enabled__returns_all_flags(
316316
assert response.status_code == 200
317317
flags = response.json()
318318
assert len(flags) == 3
319+
# Verify disabled flags are included (bypasses hide_disabled_flags for server keys)
320+
flag_names = {f["feature"]["name"] for f in flags}
321+
assert "feature_1" in flag_names # disabled flag
322+
assert "feature_2" in flag_names # enabled flag
323+
assert "feature_3" in flag_names # disabled flag
319324

320325

321326
def test_get_flags__client_key__hide_disabled_flags_enabled__single_disabled_feature__returns_404(

0 commit comments

Comments
 (0)