alignment · featurevisor/featurevisor-python@fc33f51 · GitHub
Skip to content

Commit fc33f51

Browse files
committed
alignment
1 parent 7958a98 commit fc33f51

12 files changed

Lines changed: 154 additions & 116 deletions

‎README.md‎

Lines changed: 39 additions & 42 deletions

‎src/featurevisor/__init__.py‎

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,10 @@
11
from .child import FeaturevisorChildInstance
2-
from .modules import FeaturevisorModule, ModulesManager
3-
from .instance import FeaturevisorInstance as Featurevisor, create_instance
4-
from .logger import Logger
2+
from .modules import FeaturevisorModule
3+
from .instance import Featurevisor, create_featurevisor
54

65
__all__ = [
76
"Featurevisor",
87
"FeaturevisorChildInstance",
98
"FeaturevisorModule",
10-
"ModulesManager",
11-
"Logger",
12-
"create_instance",
9+
"create_featurevisor",
1310
]

‎src/featurevisor/child.py‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@
66
from .events import get_params_for_sticky_set_event
77

88
if TYPE_CHECKING:
9-
from .instance import FeaturevisorInstance
9+
from .instance import Featurevisor
1010

1111

1212
class FeaturevisorChildInstance:
13-
def __init__(self, *, parent: "FeaturevisorInstance", context: dict[str, Any], sticky: dict[str, Any] | None = None) -> None:
13+
def __init__(self, *, parent: "Featurevisor", context: dict[str, Any], sticky: dict[str, Any] | None = None) -> None:
1414
self.parent = parent
1515
self.context = context
1616
self.sticky = sticky or {}

‎src/featurevisor/datafile_reader.py‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,12 @@
55
from typing import Any
66

77
from .conditions import condition_is_matched
8-
from .logger import Logger
8+
from .logger import _Logger
99
from .types import Context, DatafileContent, Feature, Force, Segment, Traffic
1010

1111

1212
class _DatafileReader:
13-
def __init__(self, *, datafile: DatafileContent, logger: Logger) -> None:
13+
def __init__(self, *, datafile: DatafileContent, logger: _Logger) -> None:
1414
self.logger = logger
1515
self.schema_version = datafile["schemaVersion"]
1616
self.revision = datafile["revision"]

‎src/featurevisor/instance.py‎

Lines changed: 53 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,17 +10,20 @@
1010
from .evaluate import evaluate_with_modules
1111
from .events import get_params_for_datafile_set_event, get_params_for_sticky_set_event
1212
from .helpers import get_value_by_type
13-
from .logger import Logger, create_logger
13+
from .logger import _Logger, _create_logger, _default_log_handler
1414
from .modules import FeaturevisorModule, ModulesManager
1515

1616
empty_datafile = {"schemaVersion": "2", "revision": "unknown", "segments": {}, "features": {}}
1717

1818

19-
class FeaturevisorInstance:
19+
class Featurevisor:
2020
def __init__(self, options: dict[str, Any] | None = None) -> None:
2121
options = options or {}
2222
self.context = options.get("context") or {}
23-
self.logger: Logger = options.get("logger") or create_logger({"level": options.get("logLevel") or Logger.default_level})
23+
self.logger: _Logger = _create_logger({
24+
"level": options.get("logLevel") or _Logger.default_level,
25+
"handler": self._handle_internal_log,
26+
})
2427
self.on_diagnostic = options.get("onDiagnostic") or options.get("on_diagnostic")
2528
self.emitter = Emitter()
2629
self.sticky = options.get("sticky")
@@ -48,6 +51,28 @@ def __init__(self, options: dict[str, Any] | None = None) -> None:
4851
def set_log_level(self, level: str) -> None:
4952
self.logger.set_level(level)
5053

54+
def _handle_internal_log(self, level: str, message: str, details: dict[str, Any] | None = None) -> None:
55+
details = dict(details or {})
56+
code = str(details.get("reason") or message)
57+
if message == "feature is deprecated":
58+
code = "deprecated_feature"
59+
elif message == "variable is deprecated":
60+
code = "deprecated_variable"
61+
elif message == "feature not found":
62+
code = "feature_not_found"
63+
elif message == "variable schema not found":
64+
code = "variable_not_found"
65+
elif message == "no variations":
66+
code = "no_variations"
67+
elif message == "invalid bucketBy":
68+
code = "invalid_bucket_by"
69+
self.report_diagnostic({
70+
"level": level,
71+
"code": code,
72+
"message": message,
73+
"details": details,
74+
})
75+
5176
def set_datafile(self, datafile, replace: bool = False) -> None:
5277
if self.closed:
5378
return
@@ -75,6 +100,21 @@ def set_sticky(self, sticky: dict[str, Any], replace: bool = False) -> None:
75100
def get_revision(self) -> str:
76101
return self.datafile_reader.get_revision()
77102

103+
def get_schema_version(self) -> str:
104+
return self.datafile_reader.get_schema_version()
105+
106+
def get_segment(self, segment_key: str):
107+
return self.datafile_reader.get_segment(segment_key)
108+
109+
def get_feature_keys(self) -> list[str]:
110+
return self.datafile_reader.get_feature_keys()
111+
112+
def get_variable_keys(self, feature_key: str) -> list[str]:
113+
return self.datafile_reader.get_variable_keys(feature_key)
114+
115+
def has_variations(self, feature_key: str) -> bool:
116+
return self.datafile_reader.has_variations(feature_key)
117+
78118
def get_feature(self, feature_key: str):
79119
return self.datafile_reader.get_feature(feature_key)
80120

@@ -268,15 +308,15 @@ def report_diagnostic(self, diagnostic: dict[str, Any], source_module: Featurevi
268308
self.on_diagnostic(diagnostic)
269309
except Exception as exc:
270310
print("[Featurevisor] Diagnostic handler failed:", exc)
271-
else:
272-
self.logger.log(diagnostic["level"], diagnostic.get("message", ""), diagnostic)
311+
elif self._should_report_diagnostic(diagnostic["level"], self.logger.level):
312+
_default_log_handler(diagnostic["level"], diagnostic.get("message", ""), diagnostic)
273313

274314
if diagnostic["level"] in {"error", "fatal"}:
275315
self.emitter.trigger("error", diagnostic)
276316

277317
def _should_report_diagnostic(self, diagnostic_level: str, subscriber_level: str) -> bool:
278318
try:
279-
return Logger.all_levels.index(subscriber_level) >= Logger.all_levels.index(diagnostic_level)
319+
return _Logger.all_levels.index(subscriber_level) >= _Logger.all_levels.index(diagnostic_level)
280320
except ValueError:
281321
return False
282322

@@ -293,6 +333,11 @@ def _merge_datafiles(self, previous: dict[str, Any], incoming: dict[str, Any]) -
293333
setDatafile = set_datafile
294334
setSticky = set_sticky
295335
getRevision = get_revision
336+
getSchemaVersion = get_schema_version
337+
getSegment = get_segment
338+
getFeatureKeys = get_feature_keys
339+
getVariableKeys = get_variable_keys
340+
hasVariations = has_variations
296341
getFeature = get_feature
297342
addModule = add_module
298343
removeModule = remove_module
@@ -314,5 +359,5 @@ def _merge_datafiles(self, previous: dict[str, Any], incoming: dict[str, Any]) -
314359
getAllEvaluations = get_all_evaluations
315360

316361

317-
def create_instance(options: dict[str, Any] | None = None) -> FeaturevisorInstance:
318-
return FeaturevisorInstance(options or {})
362+
def create_featurevisor(options: dict[str, Any] | None = None) -> Featurevisor:
363+
return Featurevisor(options or {})

‎src/featurevisor/logger.py‎

Lines changed: 7 additions & 8 deletions

0 commit comments

Comments
 (0)