From 59261cf28dcdff5dc98cf2b45983efcc445128b8 Mon Sep 17 00:00:00 2001 From: Federico Bond Date: Thu, 31 Aug 2023 18:04:54 +1200 Subject: [PATCH 1/2] refactor!: move api hooks methods to api module Signed-off-by: Federico Bond --- open_feature/hooks/__init__.py | 21 --------------------- open_feature/open_feature_api.py | 18 ++++++++++++++++++ open_feature/open_feature_client.py | 3 +-- readme.md | 2 +- tests/hooks/test_init.py | 18 ------------------ tests/test_open_feature_api.py | 20 ++++++++++++++++++++ tests/test_open_feature_client.py | 2 +- 7 files changed, 41 insertions(+), 43 deletions(-) delete mode 100644 tests/hooks/test_init.py diff --git a/open_feature/hooks/__init__.py b/open_feature/hooks/__init__.py index c790bb2e..e69de29b 100644 --- a/open_feature/hooks/__init__.py +++ b/open_feature/hooks/__init__.py @@ -1,21 +0,0 @@ -import typing - -from open_feature.hooks.hook import Hook - - -_hooks: typing.List[Hook] = [] - - -def add_api_hooks(hooks: typing.List[Hook]): - global _hooks - _hooks = _hooks + hooks - - -def clear_api_hooks(): - global _hooks - _hooks = [] - - -def api_hooks() -> typing.List[Hook]: - global _hooks - return _hooks diff --git a/open_feature/open_feature_api.py b/open_feature/open_feature_api.py index fc57b531..7df9f2db 100644 --- a/open_feature/open_feature_api.py +++ b/open_feature/open_feature_api.py @@ -2,6 +2,7 @@ from open_feature.evaluation_context.evaluation_context import EvaluationContext from open_feature.exception.exceptions import GeneralError +from open_feature.hooks.hook import Hook from open_feature.open_feature_client import OpenFeatureClient from open_feature.provider.metadata import Metadata from open_feature.provider.no_op_provider import NoOpProvider @@ -11,6 +12,8 @@ _evaluation_context = EvaluationContext() +_hooks: typing.List[Hook] = [] + def get_client( name: typing.Optional[str] = None, version: typing.Optional[str] = None @@ -45,3 +48,18 @@ def set_evaluation_context(evaluation_context: EvaluationContext): if evaluation_context is None: raise GeneralError(error_message="No api level evaluation context") _evaluation_context = evaluation_context + + +def add_api_hooks(hooks: typing.List[Hook]): + global _hooks + _hooks = _hooks + hooks + + +def clear_api_hooks(): + global _hooks + _hooks = [] + + +def api_hooks() -> typing.List[Hook]: + global _hooks + return _hooks diff --git a/open_feature/open_feature_client.py b/open_feature/open_feature_client.py index 162696b4..ea5645af 100644 --- a/open_feature/open_feature_client.py +++ b/open_feature/open_feature_client.py @@ -15,7 +15,6 @@ from open_feature.flag_evaluation.flag_type import FlagType from open_feature.flag_evaluation.reason import Reason from open_feature.flag_evaluation.resolution_details import FlagResolutionDetails -from open_feature.hooks import api_hooks from open_feature.hooks.hook import Hook from open_feature.hooks.hook_context import HookContext from open_feature.hooks.hook_support import ( @@ -259,7 +258,7 @@ def evaluate_flag_details( # in the flag evaluation # before: API, Client, Invocation, Provider merged_hooks = ( - api_hooks() + api.api_hooks() + self.hooks + evaluation_hooks + self.provider.get_provider_hooks() diff --git a/readme.md b/readme.md index 865a7e72..01859485 100644 --- a/readme.md +++ b/readme.md @@ -150,7 +150,7 @@ class MyHook(Hook): # set global hooks at the API-level -from open_feature.hooks import add_api_hooks +from open_feature.open_feature_api import add_api_hooks add_api_hooks([MyHook()]) # or configure them in the client diff --git a/tests/hooks/test_init.py b/tests/hooks/test_init.py deleted file mode 100644 index 21a1948c..00000000 --- a/tests/hooks/test_init.py +++ /dev/null @@ -1,18 +0,0 @@ -from unittest.mock import MagicMock - -from open_feature.hooks.hook import Hook -from open_feature.hooks import add_api_hooks, clear_api_hooks, api_hooks - - -def test_should_add_hooks_to_api_hooks(): - # Given - hook_1 = MagicMock(spec=Hook) - hook_2 = MagicMock(spec=Hook) - clear_api_hooks() - - # When - add_api_hooks([hook_1]) - add_api_hooks([hook_2]) - - # Then - assert api_hooks() == [hook_1, hook_2] diff --git a/tests/test_open_feature_api.py b/tests/test_open_feature_api.py index f9e3af3d..3dd1c21f 100644 --- a/tests/test_open_feature_api.py +++ b/tests/test_open_feature_api.py @@ -1,6 +1,9 @@ +from unittest.mock import MagicMock + import pytest from open_feature.evaluation_context.evaluation_context import EvaluationContext +from open_feature.hooks.hook import Hook from open_feature.exception.error_code import ErrorCode from open_feature.exception.exceptions import GeneralError from open_feature.open_feature_api import ( @@ -10,6 +13,9 @@ get_provider_metadata, get_evaluation_context, set_evaluation_context, + api_hooks, + add_api_hooks, + clear_api_hooks, ) from open_feature.provider.metadata import Metadata from open_feature.provider.no_op_provider import NoOpProvider @@ -97,3 +103,17 @@ def test_should_successfully_set_evaluation_context_for_api(): assert global_evaluation_context assert global_evaluation_context.targeting_key == evaluation_context.targeting_key assert global_evaluation_context.attributes == evaluation_context.attributes + + +def test_should_add_hooks_to_api_hooks(): + # Given + hook_1 = MagicMock(spec=Hook) + hook_2 = MagicMock(spec=Hook) + clear_api_hooks() + + # When + add_api_hooks([hook_1]) + add_api_hooks([hook_2]) + + # Then + assert api_hooks() == [hook_1, hook_2] diff --git a/tests/test_open_feature_client.py b/tests/test_open_feature_client.py index 6ac18962..6a1826fc 100644 --- a/tests/test_open_feature_client.py +++ b/tests/test_open_feature_client.py @@ -2,10 +2,10 @@ import pytest +from open_feature.open_feature_api import clear_api_hooks, add_api_hooks from open_feature.exception.error_code import ErrorCode from open_feature.exception.exceptions import OpenFeatureError from open_feature.flag_evaluation.reason import Reason -from open_feature.hooks import clear_api_hooks, add_api_hooks from open_feature.hooks.hook import Hook from open_feature.open_feature_client import OpenFeatureClient from open_feature.provider.no_op_provider import NoOpProvider From 49a9c790a018c21e0f376adc2efb284a8a77de82 Mon Sep 17 00:00:00 2001 From: Federico Bond Date: Thu, 31 Aug 2023 18:33:23 +1200 Subject: [PATCH 2/2] refactor!: rename api-level hook methods Signed-off-by: Federico Bond --- open_feature/open_feature_api.py | 6 +++--- open_feature/open_feature_client.py | 2 +- readme.md | 4 ++-- tests/test_open_feature_api.py | 14 +++++++------- tests/test_open_feature_client.py | 6 +++--- 5 files changed, 16 insertions(+), 16 deletions(-) diff --git a/open_feature/open_feature_api.py b/open_feature/open_feature_api.py index 7df9f2db..cc07c8e4 100644 --- a/open_feature/open_feature_api.py +++ b/open_feature/open_feature_api.py @@ -50,16 +50,16 @@ def set_evaluation_context(evaluation_context: EvaluationContext): _evaluation_context = evaluation_context -def add_api_hooks(hooks: typing.List[Hook]): +def add_hooks(hooks: typing.List[Hook]): global _hooks _hooks = _hooks + hooks -def clear_api_hooks(): +def clear_hooks(): global _hooks _hooks = [] -def api_hooks() -> typing.List[Hook]: +def get_hooks() -> typing.List[Hook]: global _hooks return _hooks diff --git a/open_feature/open_feature_client.py b/open_feature/open_feature_client.py index ea5645af..fcaf9588 100644 --- a/open_feature/open_feature_client.py +++ b/open_feature/open_feature_client.py @@ -258,7 +258,7 @@ def evaluate_flag_details( # in the flag evaluation # before: API, Client, Invocation, Provider merged_hooks = ( - api.api_hooks() + api.get_hooks() + self.hooks + evaluation_hooks + self.provider.get_provider_hooks() diff --git a/readme.md b/readme.md index 01859485..bb79e364 100644 --- a/readme.md +++ b/readme.md @@ -150,8 +150,8 @@ class MyHook(Hook): # set global hooks at the API-level -from open_feature.open_feature_api import add_api_hooks -add_api_hooks([MyHook()]) +from open_feature.open_feature_api import add_hooks +add_hooks([MyHook()]) # or configure them in the client client = OpenFeatureClient() diff --git a/tests/test_open_feature_api.py b/tests/test_open_feature_api.py index 3dd1c21f..9a976f72 100644 --- a/tests/test_open_feature_api.py +++ b/tests/test_open_feature_api.py @@ -13,9 +13,9 @@ get_provider_metadata, get_evaluation_context, set_evaluation_context, - api_hooks, - add_api_hooks, - clear_api_hooks, + get_hooks, + add_hooks, + clear_hooks, ) from open_feature.provider.metadata import Metadata from open_feature.provider.no_op_provider import NoOpProvider @@ -109,11 +109,11 @@ def test_should_add_hooks_to_api_hooks(): # Given hook_1 = MagicMock(spec=Hook) hook_2 = MagicMock(spec=Hook) - clear_api_hooks() + clear_hooks() # When - add_api_hooks([hook_1]) - add_api_hooks([hook_2]) + add_hooks([hook_1]) + add_hooks([hook_2]) # Then - assert api_hooks() == [hook_1, hook_2] + assert get_hooks() == [hook_1, hook_2] diff --git a/tests/test_open_feature_client.py b/tests/test_open_feature_client.py index 6a1826fc..b8171ba4 100644 --- a/tests/test_open_feature_client.py +++ b/tests/test_open_feature_client.py @@ -2,7 +2,7 @@ import pytest -from open_feature.open_feature_api import clear_api_hooks, add_api_hooks +from open_feature.open_feature_api import add_hooks, clear_hooks from open_feature.exception.error_code import ErrorCode from open_feature.exception.exceptions import OpenFeatureError from open_feature.flag_evaluation.reason import Reason @@ -149,9 +149,9 @@ def test_should_return_client_metadata_with_name(): def test_should_call_api_level_hooks(no_op_provider_client): # Given - clear_api_hooks() + clear_hooks() api_hook = MagicMock(spec=Hook) - add_api_hooks([api_hook]) + add_hooks([api_hook]) # When no_op_provider_client.get_boolean_details(flag_key="Key", default_value=True)