Skip to content

Commit 7780fa4

Browse files
committed
chore: run pre-commit
Signed-off-by: Danju Visvanathan <danju.visvanathan@gmail.com>
1 parent 32d972e commit 7780fa4

9 files changed

Lines changed: 124 additions & 35 deletions

File tree

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -198,8 +198,8 @@ client = api.get_client()
198198

199199
# trigger tracking event action
200200
client.track(
201-
'visited-promo-page',
202-
evaluation_context=EvaluationContext(),
201+
'visited-promo-page',
202+
evaluation_context=EvaluationContext(),
203203
tracking_event_details=openfeature.TrackingEventDetails(99.77).add("currencyCode", "USD"),
204204
)
205205
```

openfeature/client.py

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -955,8 +955,13 @@ def add_handler(self, event: ProviderEvent, handler: EventHandler) -> None:
955955

956956
def remove_handler(self, event: ProviderEvent, handler: EventHandler) -> None:
957957
_event_support.remove_client_handler(self, event, handler)
958-
959-
def track(self, tracking_event_name: str, evaluation_context: EvaluationContext | None = None, tracking_event_details: TrackingEventDetails | None = None) -> None:
958+
959+
def track(
960+
self,
961+
tracking_event_name: str,
962+
evaluation_context: EvaluationContext | None = None,
963+
tracking_event_details: TrackingEventDetails | None = None,
964+
) -> None:
960965
"""
961966
Tracks the occurrence of a particular action or application state.
962967
@@ -967,7 +972,7 @@ def track(self, tracking_event_name: str, evaluation_context: EvaluationContext
967972

968973
if not hasattr(self.provider, "track"):
969974
return
970-
975+
971976
if evaluation_context is None:
972977
evaluation_context = EvaluationContext()
973978

@@ -977,7 +982,10 @@ def track(self, tracking_event_name: str, evaluation_context: EvaluationContext
977982
.merge(self.context)
978983
.merge(evaluation_context)
979984
)
980-
self.provider.track(tracking_event_name, merged_eval_context, tracking_event_details)
985+
self.provider.track(
986+
tracking_event_name, merged_eval_context, tracking_event_details
987+
)
988+
981989

982990
def _typecheck_flag_value(
983991
value: typing.Any, flag_type: FlagType

openfeature/provider/__init__.py

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,12 @@ async def resolve_object_details_async(
117117
Sequence[FlagValueType] | Mapping[str, FlagValueType]
118118
]: ...
119119

120-
def track(self, tracking_event_name: str, evaluation_context: EvaluationContext | None = None, tracking_event_details: TrackingEventDetails | None = None) -> None: ...
120+
def track(
121+
self,
122+
tracking_event_name: str,
123+
evaluation_context: EvaluationContext | None = None,
124+
tracking_event_details: TrackingEventDetails | None = None,
125+
) -> None: ...
121126

122127

123128
class AbstractProvider(FeatureProvider):
@@ -141,7 +146,12 @@ def initialize(self, evaluation_context: EvaluationContext) -> None:
141146
def shutdown(self) -> None:
142147
pass
143148

144-
def track(self, tracking_event_name: str, evaluation_context: EvaluationContext | None = None, tracking_event_details: TrackingEventDetails | None = None) -> None:
149+
def track(
150+
self,
151+
tracking_event_name: str,
152+
evaluation_context: EvaluationContext | None = None,
153+
tracking_event_details: TrackingEventDetails | None = None,
154+
) -> None:
145155
pass
146156

147157
@abstractmethod

openfeature/provider/in_memory_provider.py

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,14 @@
2222
class InMemoryMetadata(Metadata):
2323
name: str = "In-Memory Provider"
2424

25+
2526
@dataclass
26-
class InMemoryTrackingEvent():
27+
class InMemoryTrackingEvent:
2728
value: float | None = None
2829
details: dict[str, typing.Any] = field(default_factory=dict)
29-
eval_context_attributes: Mapping[str, EvaluationContextAttribute] = field(default_factory=dict)
30-
30+
eval_context_attributes: Mapping[str, EvaluationContextAttribute] = field(
31+
default_factory=dict
32+
)
3133

3234

3335
T_co = typing.TypeVar("T_co", covariant=True)
@@ -74,8 +76,11 @@ def resolve(
7476
class InMemoryProvider(AbstractProvider):
7577
_flags: FlagStorage
7678
_tracking_events: TrackingStorage
79+
7780
# tracking_events defaults to an empty dict
78-
def __init__(self, flags: FlagStorage, tracking_events: TrackingStorage | None = None) -> None:
81+
def __init__(
82+
self, flags: FlagStorage, tracking_events: TrackingStorage | None = None
83+
) -> None:
7984
self._flags = flags.copy()
8085
if tracking_events is not None:
8186
self._tracking_events = tracking_events.copy()
@@ -192,10 +197,23 @@ async def _resolve_async(
192197
) -> FlagResolutionDetails[V]:
193198
return self._resolve(flag_key, default_value, evaluation_context)
194199

195-
def track(self, tracking_event_name: str, evaluation_context: EvaluationContext | None = None, tracking_event_details: TrackingEventDetails | None = None) -> None:
196-
value = tracking_event_details.value if tracking_event_details is not None else None
197-
details = tracking_event_details.attributes if tracking_event_details is not None else {}
198-
eval_context_attributes = evaluation_context.attributes if evaluation_context is not None else {}
200+
def track(
201+
self,
202+
tracking_event_name: str,
203+
evaluation_context: EvaluationContext | None = None,
204+
tracking_event_details: TrackingEventDetails | None = None,
205+
) -> None:
206+
value = (
207+
tracking_event_details.value if tracking_event_details is not None else None
208+
)
209+
details = (
210+
tracking_event_details.attributes
211+
if tracking_event_details is not None
212+
else {}
213+
)
214+
eval_context_attributes = (
215+
evaluation_context.attributes if evaluation_context is not None else {}
216+
)
199217

200218
self._tracking_events[tracking_event_name] = InMemoryTrackingEvent(
201219
value=value,

openfeature/provider/no_op_provider.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,5 +84,10 @@ def resolve_object_details(
8484
variant=PASSED_IN_DEFAULT,
8585
)
8686

87-
def track(self, tracking_event_name: str, evaluation_context: EvaluationContext | None = None, tracking_event_details: TrackingEventDetails | None = None) -> None:
87+
def track(
88+
self,
89+
tracking_event_name: str,
90+
evaluation_context: EvaluationContext | None = None,
91+
tracking_event_details: TrackingEventDetails | None = None,
92+
) -> None:
8893
pass

openfeature/track/__init__.py

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,25 @@
11
from __future__ import annotations
22

3-
from collections.abc import Mapping, Sequence
43
import typing
4+
from collections.abc import Mapping, Sequence
5+
6+
TrackingValue: typing.TypeAlias = (
7+
bool | int | float | str | Sequence["TrackingValue"] | Mapping[str, "TrackingValue"]
8+
)
59

6-
TrackingValue: typing.TypeAlias = bool | int | float | str | Sequence["TrackingValue"] | Mapping[str, "TrackingValue"]
710

811
class TrackingEventDetails:
912
value: float | None
1013
attributes: dict[str, TrackingValue]
1114

12-
def __init__(self, value: float | None = None, attributes: dict[str, TrackingValue] | None = None):
15+
def __init__(
16+
self,
17+
value: float | None = None,
18+
attributes: dict[str, TrackingValue] | None = None,
19+
):
1320
self.value = value
1421
self.attributes = attributes or {}
1522

16-
def add(self, key: str, value: TrackingValue) -> "TrackingEventDetails":
23+
def add(self, key: str, value: TrackingValue) -> TrackingEventDetails:
1724
self.attributes[key] = value
1825
return self

tests/provider/test_in_memory_provider.py

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
11
from numbers import Number
22

3-
from openfeature.evaluation_context import EvaluationContext
4-
from openfeature.provider.no_op_provider import NoOpProvider
5-
from openfeature.track import TrackingEventDetails
63
import pytest
74

5+
from openfeature.evaluation_context import EvaluationContext
86
from openfeature.exception import ErrorCode
97
from openfeature.flag_evaluation import FlagResolutionDetails, Reason
10-
from openfeature.provider.in_memory_provider import InMemoryFlag, InMemoryProvider, InMemoryTrackingEvent
8+
from openfeature.provider.in_memory_provider import (
9+
InMemoryFlag,
10+
InMemoryProvider,
11+
InMemoryTrackingEvent,
12+
)
13+
from openfeature.track import TrackingEventDetails
1114

1215

1316
def test_should_return_in_memory_provider_metadata():
@@ -204,5 +207,15 @@ async def test_should_track_event():
204207
provider = InMemoryProvider(
205208
{"Key": InMemoryFlag("hundred", {"zero": 0, "hundred": 100})}
206209
)
207-
provider.track(tracking_event_name="test", evaluation_context=EvaluationContext(attributes={"key": "value"}), tracking_event_details=TrackingEventDetails(value=1, attributes={"key": "value"}))
208-
assert provider._tracking_events == {"test": InMemoryTrackingEvent(value=1, details={"key": "value"}, eval_context_attributes={"key": "value"})}
210+
provider.track(
211+
tracking_event_name="test",
212+
evaluation_context=EvaluationContext(attributes={"key": "value"}),
213+
tracking_event_details=TrackingEventDetails(
214+
value=1, attributes={"key": "value"}
215+
),
216+
)
217+
assert provider._tracking_events == {
218+
"test": InMemoryTrackingEvent(
219+
value=1, details={"key": "value"}, eval_context_attributes={"key": "value"}
220+
)
221+
}

tests/test_client.py

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,17 @@
55
from concurrent.futures import ThreadPoolExecutor
66
from unittest.mock import MagicMock
77

8-
from openfeature.track import TrackingEventDetails
98
import pytest
109

1110
from openfeature import api
12-
from openfeature.api import add_hooks, clear_hooks, get_client, set_evaluation_context, set_provider, set_transaction_context
11+
from openfeature.api import (
12+
add_hooks,
13+
clear_hooks,
14+
get_client,
15+
set_evaluation_context,
16+
set_provider,
17+
set_transaction_context,
18+
)
1319
from openfeature.client import OpenFeatureClient, _typecheck_flag_value
1420
from openfeature.evaluation_context import EvaluationContext
1521
from openfeature.event import EventDetails, ProviderEvent, ProviderEventDetails
@@ -625,21 +631,34 @@ def test_client_should_merge_contexts():
625631
assert context.attributes["client_attr"] == "client_value"
626632
assert context.attributes["invocation_attr"] == "invocation_value"
627633

634+
628635
def test_client_should_track_event():
629636
spy_provider = MagicMock(spec=NoOpProvider)
630637
set_provider(spy_provider)
631638
client = get_client()
632639
client.track(tracking_event_name="test")
633640
spy_provider.track.assert_called_once()
634641

642+
635643
def test_tracking_merges_evaluation_contexts():
636644
spy_provider = MagicMock(spec=NoOpProvider)
637645
api.set_provider(spy_provider)
638646
client = get_client()
639647
set_evaluation_context(EvaluationContext("id", attributes={"key": "eval_value"}))
640-
set_transaction_context(EvaluationContext("id", attributes={"transaction_attr": "transaction_value"}))
641-
client.track(tracking_event_name="test", evaluation_context=EvaluationContext("id", attributes={"key": "value"}))
642-
spy_provider.track.assert_called_once_with("test", EvaluationContext("id", attributes={"transaction_attr": "transaction_value", "key": "value"}), None)
648+
set_transaction_context(
649+
EvaluationContext("id", attributes={"transaction_attr": "transaction_value"})
650+
)
651+
client.track(
652+
tracking_event_name="test",
653+
evaluation_context=EvaluationContext("id", attributes={"key": "value"}),
654+
)
655+
spy_provider.track.assert_called_once_with(
656+
"test",
657+
EvaluationContext(
658+
"id", attributes={"transaction_attr": "transaction_value", "key": "value"}
659+
),
660+
None,
661+
)
643662

644663

645664
def test_should_noop_if_provider_does_not_support_tracking(monkeypatch):

tests/track/test_tracking.py

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,38 @@
11
from openfeature.track import TrackingEventDetails
2-
import pytest
2+
33

44
def test_add_attribute_to_tracking_event_details():
55
tracking_event_details = TrackingEventDetails()
66
tracking_event_details.add("key", "value")
77
assert tracking_event_details.attributes == {"key": "value"}
88

9+
910
def test_add_attribute_to_tracking_event_details_dict():
1011
tracking_event_details = TrackingEventDetails()
1112
tracking_event_details.add("key", {"key1": "value1", "key2": "value2"})
12-
assert tracking_event_details.attributes == {"key": {"key1": "value1", "key2": "value2"}}
13+
assert tracking_event_details.attributes == {
14+
"key": {"key1": "value1", "key2": "value2"}
15+
}
16+
1317

1418
def test_get_value_from_tracking_event_details():
1519
tracking_event_details = TrackingEventDetails(value=1)
1620
assert tracking_event_details.value == 1
1721

22+
1823
def test_get_attributes_from_tracking_event_details():
19-
tracking_event_details = TrackingEventDetails(value=5.0, attributes={"key": "value"})
24+
tracking_event_details = TrackingEventDetails(
25+
value=5.0, attributes={"key": "value"}
26+
)
2027
assert tracking_event_details.attributes == {"key": "value"}
2128

29+
2230
def test_get_attributes_from_tracking_event_details_with_none_value():
2331
tracking_event_details = TrackingEventDetails(attributes={"key": "value"})
2432
assert tracking_event_details.attributes == {"key": "value"}
2533
assert tracking_event_details.value is None
2634

35+
2736
def test_get_attributes_from_tracking_event_details_with_none_attributes():
2837
tracking_event_details = TrackingEventDetails(value=5.0)
2938
assert tracking_event_details.attributes == {}

0 commit comments

Comments
 (0)