Skip to content

Commit caa7f36

Browse files
authored
feat: add FeatureProvider protocol (#268)
Signed-off-by: Federico Bond <[email protected]>
1 parent 3b89760 commit caa7f36

File tree

5 files changed

+74
-12
lines changed

5 files changed

+74
-12
lines changed

openfeature/api.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@
44
from openfeature.evaluation_context import EvaluationContext
55
from openfeature.exception import GeneralError
66
from openfeature.hook import Hook
7+
from openfeature.provider import FeatureProvider
78
from openfeature.provider.metadata import Metadata
89
from openfeature.provider.no_op_provider import NoOpProvider
9-
from openfeature.provider.provider import AbstractProvider
1010

11-
_provider: AbstractProvider = NoOpProvider()
11+
_provider: FeatureProvider = NoOpProvider()
1212

1313
_evaluation_context = EvaluationContext()
1414

@@ -21,7 +21,7 @@ def get_client(
2121
return OpenFeatureClient(name=name, version=version, provider=_provider)
2222

2323

24-
def set_provider(provider: AbstractProvider) -> None:
24+
def set_provider(provider: FeatureProvider) -> None:
2525
global _provider
2626
if provider is None:
2727
raise GeneralError(error_message="No provider")
@@ -31,7 +31,7 @@ def set_provider(provider: AbstractProvider) -> None:
3131
provider.initialize(_evaluation_context)
3232

3333

34-
def get_provider() -> typing.Optional[AbstractProvider]:
34+
def get_provider() -> typing.Optional[FeatureProvider]:
3535
global _provider
3636
return _provider
3737

openfeature/client.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@
2424
before_hooks,
2525
error_hooks,
2626
)
27+
from openfeature.provider import FeatureProvider
2728
from openfeature.provider.no_op_provider import NoOpProvider
28-
from openfeature.provider.provider import AbstractProvider
2929

3030
logger = logging.getLogger("openfeature")
3131

@@ -69,7 +69,7 @@ def __init__(
6969
self,
7070
name: typing.Optional[str],
7171
version: typing.Optional[str],
72-
provider: AbstractProvider,
72+
provider: FeatureProvider,
7373
context: typing.Optional[EvaluationContext] = None,
7474
hooks: typing.Optional[typing.List[Hook]] = None,
7575
) -> None:

openfeature/provider/__init__.py

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
import typing
2+
3+
from openfeature.evaluation_context import EvaluationContext
4+
from openfeature.flag_evaluation import FlagResolutionDetails
5+
from openfeature.hook import Hook
6+
7+
from .metadata import Metadata
8+
9+
10+
class FeatureProvider(typing.Protocol): # pragma: no cover
11+
def initialize(self, evaluation_context: EvaluationContext) -> None:
12+
...
13+
14+
def shutdown(self) -> None:
15+
...
16+
17+
def get_metadata(self) -> Metadata:
18+
...
19+
20+
def get_provider_hooks(self) -> typing.List[Hook]:
21+
...
22+
23+
def resolve_boolean_details(
24+
self,
25+
flag_key: str,
26+
default_value: bool,
27+
evaluation_context: typing.Optional[EvaluationContext] = None,
28+
) -> FlagResolutionDetails[bool]:
29+
...
30+
31+
def resolve_string_details(
32+
self,
33+
flag_key: str,
34+
default_value: str,
35+
evaluation_context: typing.Optional[EvaluationContext] = None,
36+
) -> FlagResolutionDetails[str]:
37+
...
38+
39+
def resolve_integer_details(
40+
self,
41+
flag_key: str,
42+
default_value: int,
43+
evaluation_context: typing.Optional[EvaluationContext] = None,
44+
) -> FlagResolutionDetails[int]:
45+
...
46+
47+
def resolve_float_details(
48+
self,
49+
flag_key: str,
50+
default_value: float,
51+
evaluation_context: typing.Optional[EvaluationContext] = None,
52+
) -> FlagResolutionDetails[float]:
53+
...
54+
55+
def resolve_object_details(
56+
self,
57+
flag_key: str,
58+
default_value: typing.Union[dict, list],
59+
evaluation_context: typing.Optional[EvaluationContext] = None,
60+
) -> FlagResolutionDetails[typing.Union[dict, list]]:
61+
...

openfeature/provider/provider.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,11 @@
44
from openfeature.evaluation_context import EvaluationContext
55
from openfeature.flag_evaluation import FlagResolutionDetails
66
from openfeature.hook import Hook
7+
from openfeature.provider import FeatureProvider
78
from openfeature.provider.metadata import Metadata
89

910

10-
class AbstractProvider:
11+
class AbstractProvider(FeatureProvider):
1112
def initialize(self, evaluation_context: EvaluationContext) -> None:
1213
pass
1314

tests/test_api.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
from openfeature.hook import Hook
2020
from openfeature.provider.metadata import Metadata
2121
from openfeature.provider.no_op_provider import NoOpProvider
22-
from openfeature.provider.provider import AbstractProvider
22+
from openfeature.provider.provider import FeatureProvider
2323

2424

2525
def test_should_not_raise_exception_with_noop_client():
@@ -61,7 +61,7 @@ def test_should_try_set_provider_and_fail_if_none_provided():
6161
def test_should_invoke_provider_initialize_function_on_newly_registered_provider():
6262
# Given
6363
evaluation_context = EvaluationContext("targeting_key", {"attr1": "val1"})
64-
provider = MagicMock(spec=AbstractProvider)
64+
provider = MagicMock(spec=FeatureProvider)
6565

6666
# When
6767
set_evaluation_context(evaluation_context)
@@ -73,8 +73,8 @@ def test_should_invoke_provider_initialize_function_on_newly_registered_provider
7373

7474
def test_should_invoke_provider_shutdown_function_once_provider_is_no_longer_in_use():
7575
# Given
76-
provider_1 = MagicMock(spec=AbstractProvider)
77-
provider_2 = MagicMock(spec=AbstractProvider)
76+
provider_1 = MagicMock(spec=FeatureProvider)
77+
provider_2 = MagicMock(spec=FeatureProvider)
7878

7979
# When
8080
set_provider(provider_1)
@@ -148,7 +148,7 @@ def test_should_add_hooks_to_api_hooks():
148148

149149
def test_should_call_provider_shutdown_on_api_shutdown():
150150
# Given
151-
provider = MagicMock(spec=AbstractProvider)
151+
provider = MagicMock(spec=FeatureProvider)
152152
set_provider(provider)
153153

154154
# When

0 commit comments

Comments
 (0)