feat: pass flag_metadata from resolution to evaluation details (#212)
Signed-off-by: Federico Bond <federicobond@gmail.com>
This commit is contained in:
parent
d41cea270e
commit
88a204dc27
|
|
@ -377,6 +377,7 @@ class OpenFeatureClient:
|
|||
flag_key=flag_key,
|
||||
value=resolution.value,
|
||||
variant=resolution.variant,
|
||||
flag_metadata=resolution.flag_metadata or {},
|
||||
reason=resolution.reason,
|
||||
error_code=resolution.error_code,
|
||||
error_message=resolution.error_message,
|
||||
|
|
|
|||
|
|
@ -29,6 +29,8 @@ class Reason(StrEnum):
|
|||
UNKNOWN = "UNKNOWN"
|
||||
|
||||
|
||||
FlagMetadata = typing.Mapping[str, typing.Any]
|
||||
|
||||
T = typing.TypeVar("T", covariant=True)
|
||||
|
||||
|
||||
|
|
@ -37,6 +39,7 @@ class FlagEvaluationDetails(typing.Generic[T]):
|
|||
flag_key: str
|
||||
value: T
|
||||
variant: typing.Optional[str] = None
|
||||
flag_metadata: FlagMetadata = field(default_factory=dict)
|
||||
reason: typing.Optional[Reason] = None
|
||||
error_code: typing.Optional[ErrorCode] = None
|
||||
error_message: typing.Optional[str] = None
|
||||
|
|
@ -58,4 +61,4 @@ class FlagResolutionDetails(typing.Generic[U]):
|
|||
error_message: typing.Optional[str] = None
|
||||
reason: typing.Optional[Reason] = None
|
||||
variant: typing.Optional[str] = None
|
||||
flag_metadata: typing.Optional[str] = None
|
||||
flag_metadata: FlagMetadata = field(default_factory=dict)
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
import typing
|
||||
from dataclasses import dataclass
|
||||
from dataclasses import dataclass, field
|
||||
|
||||
from openfeature._backports.strenum import StrEnum
|
||||
from openfeature.evaluation_context import EvaluationContext
|
||||
from openfeature.exception import ErrorCode
|
||||
from openfeature.flag_evaluation import FlagResolutionDetails, Reason
|
||||
from openfeature.flag_evaluation import FlagMetadata, FlagResolutionDetails, Reason
|
||||
from openfeature.hook import Hook
|
||||
from openfeature.provider.metadata import Metadata
|
||||
from openfeature.provider.provider import AbstractProvider
|
||||
|
|
@ -29,6 +29,7 @@ class InMemoryFlag(typing.Generic[T]):
|
|||
flag_key: str
|
||||
default_variant: str
|
||||
variants: typing.Dict[str, T]
|
||||
flag_metadata: FlagMetadata = field(default_factory=dict)
|
||||
state: State = State.ENABLED
|
||||
context_evaluator: typing.Optional[
|
||||
typing.Callable[["InMemoryFlag", EvaluationContext], FlagResolutionDetails[T]]
|
||||
|
|
@ -46,6 +47,7 @@ class InMemoryFlag(typing.Generic[T]):
|
|||
value=self.variants[self.default_variant],
|
||||
reason=Reason.STATIC,
|
||||
variant=self.default_variant,
|
||||
flag_metadata=self.flag_metadata,
|
||||
)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ from openfeature.client import OpenFeatureClient
|
|||
from openfeature.exception import ErrorCode, OpenFeatureError
|
||||
from openfeature.flag_evaluation import Reason
|
||||
from openfeature.hook import Hook
|
||||
from openfeature.provider.in_memory_provider import InMemoryFlag, InMemoryProvider
|
||||
from openfeature.provider.no_op_provider import NoOpProvider
|
||||
|
||||
|
||||
|
|
@ -97,6 +98,28 @@ def test_should_raise_exception_when_invalid_flag_type_provided(no_op_provider_c
|
|||
assert flag.reason == Reason.ERROR
|
||||
|
||||
|
||||
def test_should_pass_flag_metadata_from_resolution_to_evaluation_details():
|
||||
# Given
|
||||
provider = InMemoryProvider(
|
||||
{
|
||||
"Key": InMemoryFlag(
|
||||
"Key",
|
||||
"true",
|
||||
{"true": True, "false": False},
|
||||
flag_metadata={"foo": "bar"},
|
||||
)
|
||||
}
|
||||
)
|
||||
client = OpenFeatureClient("my-client", None, provider)
|
||||
|
||||
# When
|
||||
details = client.get_boolean_details(flag_key="Key", default_value=False)
|
||||
|
||||
# Then
|
||||
assert details is not None
|
||||
assert details.flag_metadata == {"foo": "bar"}
|
||||
|
||||
|
||||
def test_should_handle_a_generic_exception_thrown_by_a_provider(no_op_provider_client):
|
||||
# Given
|
||||
exception_hook = MagicMock(spec=Hook)
|
||||
|
|
|
|||
|
|
@ -2,11 +2,12 @@ from openfeature.exception import ErrorCode
|
|||
from openfeature.flag_evaluation import FlagEvaluationDetails, Reason
|
||||
|
||||
|
||||
def test_evaulation_details_reason_should_be_a_string():
|
||||
def test_evaluation_details_reason_should_be_a_string():
|
||||
# Given
|
||||
flag_key = "my-flag"
|
||||
flag_value = 100
|
||||
variant = "1-hundred"
|
||||
flag_metadata = {}
|
||||
reason = Reason.DEFAULT
|
||||
error_code = ErrorCode.GENERAL
|
||||
error_message = "message"
|
||||
|
|
@ -16,6 +17,7 @@ def test_evaulation_details_reason_should_be_a_string():
|
|||
flag_key,
|
||||
flag_value,
|
||||
variant,
|
||||
flag_metadata,
|
||||
reason,
|
||||
error_code,
|
||||
error_message,
|
||||
|
|
@ -30,7 +32,7 @@ def test_evaulation_details_reason_should_be_a_string():
|
|||
assert reason == flag_details.reason
|
||||
|
||||
|
||||
def test_evaulation_details_reason_should_be_a_string_when_set():
|
||||
def test_evaluation_details_reason_should_be_a_string_when_set():
|
||||
# Given
|
||||
flag_key = "my-flag"
|
||||
flag_value = 100
|
||||
|
|
|
|||
Loading…
Reference in New Issue