From 86e0052bf0108c1903cfd17a69a6015e77591d9a Mon Sep 17 00:00:00 2001 From: Andrew Helsby Date: Fri, 7 Oct 2022 15:55:12 +0400 Subject: [PATCH 1/4] feature/flagsmith-implementation: Initialise flagsmith client in flagsmith provider --- .../providers/flagsmith/flagsmith_provider.py | 56 +++++++++++++++++++ requirements.in | 2 + 2 files changed, 58 insertions(+) create mode 100644 open_feature_contrib/providers/flagsmith/flagsmith_provider.py diff --git a/open_feature_contrib/providers/flagsmith/flagsmith_provider.py b/open_feature_contrib/providers/flagsmith/flagsmith_provider.py new file mode 100644 index 00000000..823626e6 --- /dev/null +++ b/open_feature_contrib/providers/flagsmith/flagsmith_provider.py @@ -0,0 +1,56 @@ +from numbers import Number + +from open_feature_sdk.provider.provider import AbstractProvider +from open_feature_sdk.evaluation_context.evaluation_context import EvaluationContext + +class FlagsmithProvider(AbstractProvider): + + def __init__(self, api_key: str): + self.api_key = api_key if api_key else os.environ.get("FLAGSMITH_ENVIRONMENT_KEY") + + self.flagsmith = Flagsmith( + environment_key=self.api_key, + enable_local_evaluation=False, + api_url="https://api.yourselfhostedflagsmith.com/api/v1/", + request_timeout_seconds=10, + environment_refresh_interval_seconds= 60, + retries=None, + enable_analytics= False, + custom_headers = None, + default_flag_handler=DefaultFlag(enabled=False, value=None) + ) + + def get_name(self) -> str: + return "Flagsmith" + + def get_boolean_details( + self, + key: str, + default_value: bool, + evaluation_context: EvaluationContext = EvaluationContext(), + ): + pass + + def get_string_details( + self, + key: str, + default_value: str, + evaluation_context: EvaluationContext = EvaluationContext(), + ): + pass + + def get_number_details( + self, + key: str, + default_value: Number, + evaluation_context: EvaluationContext = EvaluationContext(), + ): + pass + + def get_object_details( + self, + key: str, + default_value: dict, + evaluation_context: EvaluationContext = EvaluationContext(), + ): + pass diff --git a/requirements.in b/requirements.in index e69de29b..9c959138 100644 --- a/requirements.in +++ b/requirements.in @@ -0,0 +1,2 @@ +open_feature_sdk +flagsmith \ No newline at end of file From a2e10e629a81dcc8cbfbb5693aa94c470229350a Mon Sep 17 00:00:00 2001 From: Andrew Helsby Date: Tue, 11 Oct 2022 14:23:21 +0400 Subject: [PATCH 2/4] feature/flagsmith-implementation: resolve different flag types --- open_feature_contrib/providers/__init__.py | 0 .../providers/flagsmith/flagsmith_provider.py | 56 --------- .../open_feature_flagsmith}/__init__.py | 0 .../open_feature_flagsmith/exceptions.py | 14 +++ .../flagsmith_provider.py | 106 ++++++++++++++++++ .../providers/flagsmith/requirements.in | 0 .../providers/flagsmith/requirements.txt | 30 +++++ .../flagsmith/tests}/__init__.py | 0 requirements-dev.in | 3 +- requirements-dev.txt | 30 +---- requirements.txt | 0 tests/__init__.py | 0 12 files changed, 157 insertions(+), 82 deletions(-) delete mode 100644 open_feature_contrib/providers/__init__.py delete mode 100644 open_feature_contrib/providers/flagsmith/flagsmith_provider.py rename open_feature_contrib/{ => providers/flagsmith/open_feature_flagsmith}/__init__.py (100%) create mode 100644 open_feature_contrib/providers/flagsmith/open_feature_flagsmith/exceptions.py create mode 100644 open_feature_contrib/providers/flagsmith/open_feature_flagsmith/flagsmith_provider.py rename requirements.in => open_feature_contrib/providers/flagsmith/requirements.in (100%) create mode 100644 open_feature_contrib/providers/flagsmith/requirements.txt rename open_feature_contrib/{hooks => providers/flagsmith/tests}/__init__.py (100%) delete mode 100644 requirements.txt delete mode 100644 tests/__init__.py diff --git a/open_feature_contrib/providers/__init__.py b/open_feature_contrib/providers/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/open_feature_contrib/providers/flagsmith/flagsmith_provider.py b/open_feature_contrib/providers/flagsmith/flagsmith_provider.py deleted file mode 100644 index 823626e6..00000000 --- a/open_feature_contrib/providers/flagsmith/flagsmith_provider.py +++ /dev/null @@ -1,56 +0,0 @@ -from numbers import Number - -from open_feature_sdk.provider.provider import AbstractProvider -from open_feature_sdk.evaluation_context.evaluation_context import EvaluationContext - -class FlagsmithProvider(AbstractProvider): - - def __init__(self, api_key: str): - self.api_key = api_key if api_key else os.environ.get("FLAGSMITH_ENVIRONMENT_KEY") - - self.flagsmith = Flagsmith( - environment_key=self.api_key, - enable_local_evaluation=False, - api_url="https://api.yourselfhostedflagsmith.com/api/v1/", - request_timeout_seconds=10, - environment_refresh_interval_seconds= 60, - retries=None, - enable_analytics= False, - custom_headers = None, - default_flag_handler=DefaultFlag(enabled=False, value=None) - ) - - def get_name(self) -> str: - return "Flagsmith" - - def get_boolean_details( - self, - key: str, - default_value: bool, - evaluation_context: EvaluationContext = EvaluationContext(), - ): - pass - - def get_string_details( - self, - key: str, - default_value: str, - evaluation_context: EvaluationContext = EvaluationContext(), - ): - pass - - def get_number_details( - self, - key: str, - default_value: Number, - evaluation_context: EvaluationContext = EvaluationContext(), - ): - pass - - def get_object_details( - self, - key: str, - default_value: dict, - evaluation_context: EvaluationContext = EvaluationContext(), - ): - pass diff --git a/open_feature_contrib/__init__.py b/open_feature_contrib/providers/flagsmith/open_feature_flagsmith/__init__.py similarity index 100% rename from open_feature_contrib/__init__.py rename to open_feature_contrib/providers/flagsmith/open_feature_flagsmith/__init__.py diff --git a/open_feature_contrib/providers/flagsmith/open_feature_flagsmith/exceptions.py b/open_feature_contrib/providers/flagsmith/open_feature_flagsmith/exceptions.py new file mode 100644 index 00000000..6391e33a --- /dev/null +++ b/open_feature_contrib/providers/flagsmith/open_feature_flagsmith/exceptions.py @@ -0,0 +1,14 @@ +class FlagsmithConfigurationError(OpenFeatureError): + """ + This exception should be raised when the Flagsmith provider has not been set up correctly + """ + + def __init__(self, error_message: str = None): + """ + Constructor for the FlagsmithConfigurationError. The error code for + this type of exception is ErrorCode.PROVIDER_NOT_READY. + @param error_message: a string message representing why the error has been + raised + @return: the generic FlagNotFoundError exception + """ + super().__init__(error_message, ErrorCode.PROVIDER_NOT_READY) diff --git a/open_feature_contrib/providers/flagsmith/open_feature_flagsmith/flagsmith_provider.py b/open_feature_contrib/providers/flagsmith/open_feature_flagsmith/flagsmith_provider.py new file mode 100644 index 00000000..44005ef5 --- /dev/null +++ b/open_feature_contrib/providers/flagsmith/open_feature_flagsmith/flagsmith_provider.py @@ -0,0 +1,106 @@ +import os +from numbers import Number + +from flagsmith.flagsmith import Flagsmith +from open_feature_sdk.provider.provider import AbstractProvider +from open_feature_sdk.evaluation_context.evaluation_context import EvaluationContext +from open_feature_sdk.flag_evaluation.flag_evaluation_details import FlagEvaluationDetails + +from open_feature_contrib.providers.flagsmith.open_feature_flagsmith.exceptions import FlagsmithConfigurationError + + +class FlagsmithProvider(AbstractProvider): + + def __init__( + self, + enable_local_evaluation: bool = False, + api_url: str = None, + request_timeout_seconds: int = None, + environment_refresh_interval_seconds: int = None, + retries: int = None, + enable_analytics: bool = False, + custom_headers: dict = None, + ): + kwargs = {} + if environment_key := os.environ.get("FLAGSMITH_ENVIRONMENT_KEY"): + kwargs["environment_key"] = environment_key + else: + raise FlagsmithConfigurationError("No environment key set for Flagsmith") + + for arg in locals(): + kwargs[arg.title] = arg + + self.flagsmith = Flagsmith(**kwargs) + + def get_name(self) -> str: + return "Flagsmith" + + def get_boolean_details( + self, + key: str, + default_value: bool, + evaluation_context: EvaluationContext = EvaluationContext(), + ): + flag = self._get_flag(key, default_value, evaluation_context) + if isinstance(flag, bool): + return FlagEvaluationDetails(key, flag) + else: + raise TypeMismatchError() + + def get_string_details( + self, + key: str, + default_value: str, + evaluation_context: EvaluationContext = EvaluationContext(), + ): + flag = self._get_flag(key, default_value, evaluation_context) + if isinstance(flag, str): + return FlagEvaluationDetails(key, flag) + else: + raise TypeMismatchError() + + def get_number_details( + self, + key: str, + default_value: Number, + evaluation_context: EvaluationContext = EvaluationContext(), + ): + flag = self._get_flag(key, default_value, evaluation_context) + if isinstance(flag, Number): + return FlagEvaluationDetails(key, flag) + else: + raise TypeMismatchError() + + def get_object_details( + self, + key: str, + default_value: dict, + evaluation_context: EvaluationContext = EvaluationContext(), + ): + flag = self._get_flag(key, default_value, evaluation_context) + if isinstance(flag, dict): + return FlagEvaluationDetails(key, flag) + else: + raise TypeMismatchError() + + def _get_flag( + self, + key: str, + default_value, + evaluation_context: EvaluationContext = EvaluationContext(), + ): + flags = self._get_flags(evaluation_context) + if flags.is_feature_enabled(key): + return flags.get_feature_value(key) + else: + return default_value + + def _get_flags(self, evaluation_context: EvaluationContext = EvaluationContext()): + kwargs = { + "identifier": evaluation_context.attrubutes.get("identifier"), + "traits": evaluation_context.attrubutes.get("traits"), + } + + if kwargs.get("identifier") or kwargs.get("traits"): + return self.flagsmith.get_identity_flags(**kwargs) + return self.flagsmith.get_environment_flags() diff --git a/requirements.in b/open_feature_contrib/providers/flagsmith/requirements.in similarity index 100% rename from requirements.in rename to open_feature_contrib/providers/flagsmith/requirements.in diff --git a/open_feature_contrib/providers/flagsmith/requirements.txt b/open_feature_contrib/providers/flagsmith/requirements.txt new file mode 100644 index 00000000..9a9f34e0 --- /dev/null +++ b/open_feature_contrib/providers/flagsmith/requirements.txt @@ -0,0 +1,30 @@ +# +# This file is autogenerated by pip-compile with python 3.9 +# To update, run: +# +# pip-compile open_feature_contrib/providers/flagsmith/requirements.in +# +certifi==2022.9.24 + # via requests +charset-normalizer==2.1.1 + # via requests +flagsmith==3.0.1 + # via -r open_feature_contrib/providers/flagsmith/requirements.in +flagsmith-flag-engine==1.6.6 + # via flagsmith +idna==3.4 + # via requests +marshmallow==3.18.0 + # via flagsmith-flag-engine +packaging==21.3 + # via marshmallow +pyparsing==3.0.9 + # via packaging +requests==2.28.1 + # via + # flagsmith + # requests-futures +requests-futures==1.0.0 + # via flagsmith +urllib3==1.26.12 + # via requests diff --git a/open_feature_contrib/hooks/__init__.py b/open_feature_contrib/providers/flagsmith/tests/__init__.py similarity index 100% rename from open_feature_contrib/hooks/__init__.py rename to open_feature_contrib/providers/flagsmith/tests/__init__.py diff --git a/requirements-dev.in b/requirements-dev.in index 84463ebd..b8b618ff 100644 --- a/requirements-dev.in +++ b/requirements-dev.in @@ -5,4 +5,5 @@ black pip-tools pre-commit flake8 -pytest-mock \ No newline at end of file +pytest-mock +isort \ No newline at end of file diff --git a/requirements-dev.txt b/requirements-dev.txt index 9a10979d..7fb50c89 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -8,16 +8,10 @@ astroid==2.11.5 # via pylint attrs==21.4.0 # via pytest -autopep8==1.6.0 - # via -r requirements-dev.in black==22.3.0 # via -r requirements-dev.in -certifi==2021.10.8 - # via requests cfgv==3.3.1 # via pre-commit -charset-normalizer==2.0.12 - # via requests click==8.1.3 # via # black @@ -32,12 +26,12 @@ flake8==4.0.1 # via -r requirements-dev.in identify==2.5.0 # via pre-commit -idna==3.3 - # via requests iniconfig==1.1.1 # via pytest isort==5.10.1 - # via pylint + # via + # -r requirements-dev.in + # pylint lazy-object-proxy==1.7.1 # via astroid mccabe==0.6.1 @@ -54,8 +48,6 @@ pathspec==0.9.0 # via black pep517==0.12.0 # via pip-tools -pep8==1.7.1 - # via -r requirements-dev.in pip-tools==6.6.0 # via -r requirements-dev.in platformdirs==2.5.2 @@ -70,9 +62,7 @@ pre-commit==2.19.0 py==1.11.0 # via pytest pycodestyle==2.8.0 - # via - # autopep8 - # flake8 + # via flake8 pyflakes==2.4.0 # via flake8 pylint==2.13.8 @@ -87,16 +77,10 @@ pytest-mock==3.7.0 # via -r requirements-dev.in pyyaml==6.0 # via pre-commit -requests==2.27.1 - # via responses -responses==0.20.0 - # via -r requirements-dev.in six==1.16.0 # via virtualenv toml==0.10.2 - # via - # autopep8 - # pre-commit + # via pre-commit tomli==2.0.1 # via # black @@ -108,10 +92,6 @@ typing-extensions==4.2.0 # astroid # black # pylint -urllib3==1.26.9 - # via - # requests - # responses virtualenv==20.14.1 # via pre-commit wheel==0.37.1 diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index e69de29b..00000000 diff --git a/tests/__init__.py b/tests/__init__.py deleted file mode 100644 index e69de29b..00000000 From 466c11b1f9ba4d15dd92430e8a08962c0dd57bf1 Mon Sep 17 00:00:00 2001 From: Andrew Helsby Date: Tue, 11 Oct 2022 15:24:29 +0400 Subject: [PATCH 3/4] feature/flagsmith-implementation: reformat files using black --- .../flagsmith/open_feature_flagsmith/exceptions.py | 6 +++--- .../open_feature_flagsmith/flagsmith_provider.py | 10 +++++++--- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/open_feature_contrib/providers/flagsmith/open_feature_flagsmith/exceptions.py b/open_feature_contrib/providers/flagsmith/open_feature_flagsmith/exceptions.py index 6391e33a..e7470387 100644 --- a/open_feature_contrib/providers/flagsmith/open_feature_flagsmith/exceptions.py +++ b/open_feature_contrib/providers/flagsmith/open_feature_flagsmith/exceptions.py @@ -1,7 +1,7 @@ class FlagsmithConfigurationError(OpenFeatureError): """ - This exception should be raised when the Flagsmith provider has not been set up correctly - """ + This exception should be raised when the Flagsmith provider has not been set up correctly + """ def __init__(self, error_message: str = None): """ @@ -9,6 +9,6 @@ def __init__(self, error_message: str = None): this type of exception is ErrorCode.PROVIDER_NOT_READY. @param error_message: a string message representing why the error has been raised - @return: the generic FlagNotFoundError exception + @return: a FlagsmithConfigurationError exception """ super().__init__(error_message, ErrorCode.PROVIDER_NOT_READY) diff --git a/open_feature_contrib/providers/flagsmith/open_feature_flagsmith/flagsmith_provider.py b/open_feature_contrib/providers/flagsmith/open_feature_flagsmith/flagsmith_provider.py index 44005ef5..40d4bdf3 100644 --- a/open_feature_contrib/providers/flagsmith/open_feature_flagsmith/flagsmith_provider.py +++ b/open_feature_contrib/providers/flagsmith/open_feature_flagsmith/flagsmith_provider.py @@ -4,13 +4,17 @@ from flagsmith.flagsmith import Flagsmith from open_feature_sdk.provider.provider import AbstractProvider from open_feature_sdk.evaluation_context.evaluation_context import EvaluationContext -from open_feature_sdk.flag_evaluation.flag_evaluation_details import FlagEvaluationDetails +from open_feature_sdk.exception.exception import TypeMismatchError +from open_feature_sdk.flag_evaluation.flag_evaluation_details import ( + FlagEvaluationDetails, +) -from open_feature_contrib.providers.flagsmith.open_feature_flagsmith.exceptions import FlagsmithConfigurationError +from open_feature_contrib.providers.flagsmith.open_feature_flagsmith.exceptions import ( + FlagsmithConfigurationError, +) class FlagsmithProvider(AbstractProvider): - def __init__( self, enable_local_evaluation: bool = False, From 2d76c0b27949c87a373646f484ee81477fac9650 Mon Sep 17 00:00:00 2001 From: Andrew Helsby Date: Thu, 13 Oct 2022 18:24:08 +0400 Subject: [PATCH 4/4] feature/flagsmith-implementation: Restructure flagmsith project to allow for easier packaging Signed-off-by: Andrew Helsby --- .../providers/flagsmith/requirements.in | 2 -- .../providers/flagsmith/tests/__init__.py | 0 .../hooks/README.md | 0 .../providers/README.md | 0 .../providers/flagd/__init__.py | 0 .../openfeature_flagsmith}/__init__.py | 0 .../openfeature_flagsmith}/exceptions.py | 4 +++ .../openfeature_flagsmith/provider.py | 36 ++++++++++--------- .../providers/flagsmith/requirements.in | 2 ++ .../providers/flagsmith/requirements.txt | 2 ++ .../providers/flagsmith/tests}/__init__.py | 0 .../flagsmith/tests/test_provider.py | 31 ++++++++++++++++ 12 files changed, 58 insertions(+), 19 deletions(-) delete mode 100644 open_feature_contrib/providers/flagsmith/requirements.in delete mode 100644 open_feature_contrib/providers/flagsmith/tests/__init__.py rename {open_feature_contrib => openfeature_contrib}/hooks/README.md (100%) rename {open_feature_contrib => openfeature_contrib}/providers/README.md (100%) rename {open_feature_contrib => openfeature_contrib}/providers/flagd/__init__.py (100%) rename {open_feature_contrib/providers/flagsmith => openfeature_contrib/providers/flagsmith/openfeature_flagsmith}/__init__.py (100%) rename {open_feature_contrib/providers/flagsmith/open_feature_flagsmith => openfeature_contrib/providers/flagsmith/openfeature_flagsmith}/exceptions.py (82%) rename open_feature_contrib/providers/flagsmith/open_feature_flagsmith/flagsmith_provider.py => openfeature_contrib/providers/flagsmith/openfeature_flagsmith/provider.py (71%) create mode 100644 openfeature_contrib/providers/flagsmith/requirements.in rename {open_feature_contrib => openfeature_contrib}/providers/flagsmith/requirements.txt (88%) rename {open_feature_contrib/providers/flagsmith/open_feature_flagsmith => openfeature_contrib/providers/flagsmith/tests}/__init__.py (100%) create mode 100644 openfeature_contrib/providers/flagsmith/tests/test_provider.py diff --git a/open_feature_contrib/providers/flagsmith/requirements.in b/open_feature_contrib/providers/flagsmith/requirements.in deleted file mode 100644 index 9c959138..00000000 --- a/open_feature_contrib/providers/flagsmith/requirements.in +++ /dev/null @@ -1,2 +0,0 @@ -open_feature_sdk -flagsmith \ No newline at end of file diff --git a/open_feature_contrib/providers/flagsmith/tests/__init__.py b/open_feature_contrib/providers/flagsmith/tests/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/open_feature_contrib/hooks/README.md b/openfeature_contrib/hooks/README.md similarity index 100% rename from open_feature_contrib/hooks/README.md rename to openfeature_contrib/hooks/README.md diff --git a/open_feature_contrib/providers/README.md b/openfeature_contrib/providers/README.md similarity index 100% rename from open_feature_contrib/providers/README.md rename to openfeature_contrib/providers/README.md diff --git a/open_feature_contrib/providers/flagd/__init__.py b/openfeature_contrib/providers/flagd/__init__.py similarity index 100% rename from open_feature_contrib/providers/flagd/__init__.py rename to openfeature_contrib/providers/flagd/__init__.py diff --git a/open_feature_contrib/providers/flagsmith/__init__.py b/openfeature_contrib/providers/flagsmith/openfeature_flagsmith/__init__.py similarity index 100% rename from open_feature_contrib/providers/flagsmith/__init__.py rename to openfeature_contrib/providers/flagsmith/openfeature_flagsmith/__init__.py diff --git a/open_feature_contrib/providers/flagsmith/open_feature_flagsmith/exceptions.py b/openfeature_contrib/providers/flagsmith/openfeature_flagsmith/exceptions.py similarity index 82% rename from open_feature_contrib/providers/flagsmith/open_feature_flagsmith/exceptions.py rename to openfeature_contrib/providers/flagsmith/openfeature_flagsmith/exceptions.py index e7470387..b88e03a4 100644 --- a/open_feature_contrib/providers/flagsmith/open_feature_flagsmith/exceptions.py +++ b/openfeature_contrib/providers/flagsmith/openfeature_flagsmith/exceptions.py @@ -1,3 +1,7 @@ +from open_feature.exception.exceptions import OpenFeatureError +from open_feature.flag_evaluation.error_code import ErrorCode + + class FlagsmithConfigurationError(OpenFeatureError): """ This exception should be raised when the Flagsmith provider has not been set up correctly diff --git a/open_feature_contrib/providers/flagsmith/open_feature_flagsmith/flagsmith_provider.py b/openfeature_contrib/providers/flagsmith/openfeature_flagsmith/provider.py similarity index 71% rename from open_feature_contrib/providers/flagsmith/open_feature_flagsmith/flagsmith_provider.py rename to openfeature_contrib/providers/flagsmith/openfeature_flagsmith/provider.py index 40d4bdf3..3e7d9ecb 100644 --- a/open_feature_contrib/providers/flagsmith/open_feature_flagsmith/flagsmith_provider.py +++ b/openfeature_contrib/providers/flagsmith/openfeature_flagsmith/provider.py @@ -2,21 +2,18 @@ from numbers import Number from flagsmith.flagsmith import Flagsmith -from open_feature_sdk.provider.provider import AbstractProvider -from open_feature_sdk.evaluation_context.evaluation_context import EvaluationContext -from open_feature_sdk.exception.exception import TypeMismatchError -from open_feature_sdk.flag_evaluation.flag_evaluation_details import ( - FlagEvaluationDetails, -) +from open_feature.evaluation_context.evaluation_context import EvaluationContext +from open_feature.exception.exceptions import TypeMismatchError +from open_feature.flag_evaluation.flag_evaluation_details import FlagEvaluationDetails +from open_feature.provider.provider import AbstractProvider -from open_feature_contrib.providers.flagsmith.open_feature_flagsmith.exceptions import ( - FlagsmithConfigurationError, -) +from openfeature_flagsmith.exceptions import FlagsmithConfigurationError class FlagsmithProvider(AbstractProvider): def __init__( self, + environment_key: str = None, enable_local_evaluation: bool = False, api_url: str = None, request_timeout_seconds: int = None, @@ -28,11 +25,16 @@ def __init__( kwargs = {} if environment_key := os.environ.get("FLAGSMITH_ENVIRONMENT_KEY"): kwargs["environment_key"] = environment_key + elif environment_key: + kwargs["environment_key"] = environment_key else: - raise FlagsmithConfigurationError("No environment key set for Flagsmith") + raise FlagsmithConfigurationError( + error_message="No environment key set for Flagsmith" + ) for arg in locals(): - kwargs[arg.title] = arg + if arg.title not in ("environment_key", self): + kwargs[arg.title] = arg self.flagsmith = Flagsmith(**kwargs) @@ -47,7 +49,7 @@ def get_boolean_details( ): flag = self._get_flag(key, default_value, evaluation_context) if isinstance(flag, bool): - return FlagEvaluationDetails(key, flag) + return FlagEvaluationDetails(key, flag, None) else: raise TypeMismatchError() @@ -59,7 +61,7 @@ def get_string_details( ): flag = self._get_flag(key, default_value, evaluation_context) if isinstance(flag, str): - return FlagEvaluationDetails(key, flag) + return FlagEvaluationDetails(key, flag, None) else: raise TypeMismatchError() @@ -71,7 +73,7 @@ def get_number_details( ): flag = self._get_flag(key, default_value, evaluation_context) if isinstance(flag, Number): - return FlagEvaluationDetails(key, flag) + return FlagEvaluationDetails(key, flag, None) else: raise TypeMismatchError() @@ -83,7 +85,7 @@ def get_object_details( ): flag = self._get_flag(key, default_value, evaluation_context) if isinstance(flag, dict): - return FlagEvaluationDetails(key, flag) + return FlagEvaluationDetails(key, flag, None) else: raise TypeMismatchError() @@ -101,8 +103,8 @@ def _get_flag( def _get_flags(self, evaluation_context: EvaluationContext = EvaluationContext()): kwargs = { - "identifier": evaluation_context.attrubutes.get("identifier"), - "traits": evaluation_context.attrubutes.get("traits"), + "identifier": evaluation_context.attributes.get("identifier"), + "traits": evaluation_context.attributes.get("traits"), } if kwargs.get("identifier") or kwargs.get("traits"): diff --git a/openfeature_contrib/providers/flagsmith/requirements.in b/openfeature_contrib/providers/flagsmith/requirements.in new file mode 100644 index 00000000..3cb1e92f --- /dev/null +++ b/openfeature_contrib/providers/flagsmith/requirements.in @@ -0,0 +1,2 @@ +openfeature_sdk +flagsmith \ No newline at end of file diff --git a/open_feature_contrib/providers/flagsmith/requirements.txt b/openfeature_contrib/providers/flagsmith/requirements.txt similarity index 88% rename from open_feature_contrib/providers/flagsmith/requirements.txt rename to openfeature_contrib/providers/flagsmith/requirements.txt index 9a9f34e0..2af1bbed 100644 --- a/open_feature_contrib/providers/flagsmith/requirements.txt +++ b/openfeature_contrib/providers/flagsmith/requirements.txt @@ -16,6 +16,8 @@ idna==3.4 # via requests marshmallow==3.18.0 # via flagsmith-flag-engine +openfeature-sdk==0.0.1 + # via -r open_feature_contrib/providers/flagsmith/requirements.in packaging==21.3 # via marshmallow pyparsing==3.0.9 diff --git a/open_feature_contrib/providers/flagsmith/open_feature_flagsmith/__init__.py b/openfeature_contrib/providers/flagsmith/tests/__init__.py similarity index 100% rename from open_feature_contrib/providers/flagsmith/open_feature_flagsmith/__init__.py rename to openfeature_contrib/providers/flagsmith/tests/__init__.py diff --git a/openfeature_contrib/providers/flagsmith/tests/test_provider.py b/openfeature_contrib/providers/flagsmith/tests/test_provider.py new file mode 100644 index 00000000..421d3a35 --- /dev/null +++ b/openfeature_contrib/providers/flagsmith/tests/test_provider.py @@ -0,0 +1,31 @@ +import os +import pytest +from open_feature.flag_evaluation.error_code import ErrorCode + +from openfeature_flagsmith.exceptions import FlagsmithConfigurationError +from openfeature_flagsmith.provider import FlagsmithProvider + + +def test_should_fail_to_configure_flagsmith_with_no_environment_key(): + # Given + # When + with pytest.raises(FlagsmithConfigurationError) as fge: + FlagsmithProvider() + + # Then + assert fge.error_code == ErrorCode.PROVIDER_NOT_READY + assert fge.error_message == "No environment key set for Flagsmith" + + +def test_should_fail_to_configure_flagsmith(): + # Given + # When + FlagsmithProvider() + # Then + + +def test_should_succeed_configuring_flagsmith(): + # Given + # When + FlagsmithProvider() + # Then