Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions ld_openfeature/impl/context_converter.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
from logging import getLogger
from typing import Any, Dict, List, Optional
from typing import Any, Dict, List, Mapping, Optional

from ldclient.context import Context, ContextBuilder, ContextMultiBuilder
from openfeature.evaluation_context import EvaluationContext
from openfeature.evaluation_context import EvaluationContext, EvaluationContextAttribute


logger = getLogger("launchdarkly-openfeature-server")
Expand Down Expand Up @@ -78,7 +78,7 @@ def __build_multi_context(self, context: EvaluationContext) -> Context:

return builder.build()

def __build_single_context(self, attributes: Dict, kind: str, key: str) -> Context:
def __build_single_context(self, attributes: Mapping[str, EvaluationContextAttribute], kind: str, key: str) -> Context:
builder = ContextBuilder(key)
builder.kind(kind)

Expand Down
16 changes: 9 additions & 7 deletions ld_openfeature/provider.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import threading
from typing import Any, List, Optional, Union
from typing import Any, List, Mapping, Optional, Sequence, Union

from ldclient.evaluation import EvaluationDetail
from ldclient import LDClient, Config
from ldclient.interfaces import DataSourceStatus, FlagChange, DataSourceState
from openfeature.evaluation_context import EvaluationContext
from openfeature.exception import ErrorCode, ProviderFatalError
from openfeature.flag_evaluation import FlagResolutionDetails, FlagType, Reason
from openfeature.flag_evaluation import FlagResolutionDetails, FlagType, FlagValueType, Reason
from openfeature.hook import Hook
from openfeature.provider.metadata import Metadata
from openfeature.provider import AbstractProvider
Expand Down Expand Up @@ -133,7 +133,9 @@ def resolve_float_details(
def resolve_object_details(
self,
flag_key: str,
default_value: Union[dict, list],
default_value: Union[
Sequence[FlagValueType], Mapping[str, FlagValueType]
],
evaluation_context: Optional[EvaluationContext] = None,
) -> FlagResolutionDetails[Union[dict, list]]:
"""Resolves the flag value for the provided flag key as a list or dictionary"""
Expand All @@ -154,15 +156,15 @@ def __resolve_value(self, flag_type: FlagType, flag_key: str, default_value: Any
resolved_value = self.__validate_and_cast_value(flag_type, result.value)
if resolved_value is None:
return self.__mismatched_type_details(default_value)

resolved_detail = EvaluationDetail(
value=resolved_value,
variation_index=result.variation_index,
reason=result.reason,
)

return self.__details_converter.to_resolution_details(resolved_detail)

def __validate_and_cast_value(self, flag_type: FlagType, value: Any):
"""Serializes the raw flag value to the expected type based on flag_type."""
if flag_type == FlagType.BOOLEAN and isinstance(value, bool):
Expand All @@ -175,7 +177,7 @@ def __validate_and_cast_value(self, flag_type: FlagType, value: Any):
return float(value)
elif flag_type == FlagType.OBJECT and isinstance(value, (dict, list)):
return value
return None
return None

@staticmethod
def __mismatched_type_details(default_value: Any) -> FlagResolutionDetails:
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ packages = [

[tool.poetry.dependencies]
python = "^3.9"
openfeature-sdk = ">=0.7.0,<1"
openfeature-sdk = ">=0.8.0,<1"
launchdarkly-server-sdk = "<10"


Expand Down
13 changes: 7 additions & 6 deletions tests/impl/test_context_converter.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from typing import Mapping
import pytest
from openfeature.evaluation_context import EvaluationContext
from openfeature.evaluation_context import EvaluationContext, EvaluationContextAttribute

from ld_openfeature.impl.context_converter import EvaluationContextConverter

Expand Down Expand Up @@ -49,7 +50,7 @@ def test_invalid_private_attribute_types_are_ignored(context_converter: Evaluati


def test_create_multi_context_with_invalid_targeting_key(context_converter: EvaluationContextConverter):
attributes = {
attributes: Mapping[str, EvaluationContextAttribute] = {
'kind': 'multi',
'user': {'targetingKey': False, 'key': 'user-key', 'name': 'User name'},
'org': {'key': 'org-key', 'name': 'Org name'},
Expand Down Expand Up @@ -142,7 +143,7 @@ def test_private_attributes_are_processed_correctly(context_converter: Evaluatio


def test_can_create_multi_kind_context(context_converter: EvaluationContextConverter):
attributes = {
attributes: Mapping[str, EvaluationContextAttribute] = {
'kind': 'multi',
'user': {'key': 'user-key', 'name': 'User name'},
'org': {'key': 'org-key', 'name': 'Org name'},
Expand All @@ -167,7 +168,7 @@ def test_can_create_multi_kind_context(context_converter: EvaluationContextConve


def test_can_multi_kind_ignores_kind_attribute(context_converter: EvaluationContextConverter):
attributes = {
attributes: Mapping[str, EvaluationContextAttribute] = {
'kind': 'multi',
'user': {'key': 'user-key', 'kind': 'device', 'name': 'User name'},
'org': {'key': 'org-key', 'name': 'Org name'},
Expand All @@ -192,7 +193,7 @@ def test_can_multi_kind_ignores_kind_attribute(context_converter: EvaluationCont


def test_multi_context_discards_invalid_single_kind(context_converter: EvaluationContextConverter):
attributes = {
attributes: Mapping[str, EvaluationContextAttribute] = {
'kind': 'multi',
'user': False,
'org': {'key': 'org-key', 'name': 'Org name'},
Expand All @@ -208,7 +209,7 @@ def test_multi_context_discards_invalid_single_kind(context_converter: Evaluatio


def test_handles_invalid_nested_contexts(context_converter: EvaluationContextConverter):
attributes = {
attributes: Mapping[str, EvaluationContextAttribute] = {
'kind': 'multi',
'user': 'invalid format',
'org': False
Expand Down