Skip to content

Commit

Permalink
feat(python of provider): Stop using provider.provider (#1772)
Browse files Browse the repository at this point in the history
* Stop using provider.provider as mentionned in open-feature/python-sdk#319

Signed-off-by: Thomas Poignant <[email protected]>

* Remove usage of status

Signed-off-by: Thomas Poignant <[email protected]>

* remove unused init

Signed-off-by: Thomas Poignant <[email protected]>

---------

Signed-off-by: Thomas Poignant <[email protected]>
  • Loading branch information
thomaspoignant authored Apr 30, 2024
1 parent 22882a1 commit 55a85c9
Show file tree
Hide file tree
Showing 5 changed files with 2 additions and 82 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,12 @@
from openfeature.flag_evaluation import FlagResolutionDetails, Reason
from openfeature.hook import Hook
from openfeature.provider.metadata import Metadata
from openfeature.provider.provider import AbstractProvider
from openfeature.provider import AbstractProvider
from pydantic import PrivateAttr, ValidationError

from gofeatureflag_python_provider.data_collector_hook import DataCollectorHook
from gofeatureflag_python_provider.metadata import GoFeatureFlagMetadata
from gofeatureflag_python_provider.options import BaseModel, GoFeatureFlagOptions
from gofeatureflag_python_provider.provider_status import ProviderStatus
from gofeatureflag_python_provider.request_flag_evaluation import (
RequestFlagEvaluation,
convert_evaluation_context,
Expand All @@ -46,7 +45,6 @@ class GoFeatureFlagProvider(BaseModel, AbstractProvider, metaclass=CombinedMetac
options: GoFeatureFlagOptions
_http_client: urllib3.PoolManager = PrivateAttr()
_cache: pylru.lrucache = PrivateAttr()
_status: ProviderStatus = PrivateAttr(ProviderStatus.NOT_READY)
_data_collector_hook: Optional[DataCollectorHook] = PrivateAttr()
_ws: websocket.WebSocketApp = PrivateAttr()
_ws_thread: Thread = PrivateAttr()
Expand Down Expand Up @@ -75,18 +73,8 @@ def __init__(self, **data):
self._ws = websocket.WebSocketApp(
self._build_websocket_uri(),
on_message=self._websocket_message_handler,
on_open=self._websocket_open_handler,
on_close=self._websocket_close_handler,
on_error=self._websocket_error_handler,
)

def get_status(self) -> ProviderStatus:
"""
get_status returns the status of the provider
:return: the status of the provider
"""
return self._status

def initialize(self, evaluation_context: EvaluationContext) -> None:
"""
initialize is called when the provider is initialized.
Expand All @@ -99,8 +87,6 @@ def initialize(self, evaluation_context: EvaluationContext) -> None:
if self.options.disable_cache_invalidation is False:
self._ws_thread = Thread(target=self.run_websocket)
self._ws_thread.start()
else:
self._status = ProviderStatus.READY

def shutdown(self):
if self.options.disable_cache_invalidation is False:
Expand All @@ -114,8 +100,6 @@ def shutdown(self):
self._data_collector_hook.shutdown()
self._data_collector_hook = None

self._status = ProviderStatus.NOT_READY

def get_metadata(self) -> Metadata:
return GoFeatureFlagMetadata()

Expand Down Expand Up @@ -192,14 +176,6 @@ def generic_go_feature_flag_resolver(
:return: a FlagResolutionDetails object containing the response for the SDK.
"""
try:
if self._status != ProviderStatus.READY:
return FlagResolutionDetails[original_type](
value=default_value,
reason=Reason.ERROR,
error_code=ErrorCode.PROVIDER_NOT_READY,
error_message="GO Feature Flag provider is not ready",
)

goff_evaluation_context = convert_evaluation_context(evaluation_context)
goff_request = RequestFlagEvaluation(
user=goff_evaluation_context,
Expand Down Expand Up @@ -310,32 +286,5 @@ def _websocket_message_handler(self, wsapp, message) -> None:
# when we receive a message from go-feature-flag server, we clear the cache.
self._cache.clear()

def _websocket_open_handler(self, ws_app) -> None:
"""
websocket_open_handler is the handler called when the websocket is open
:param ws app: the websocket app
:return: None
"""
self._status = ProviderStatus.READY

def _websocket_error_handler(self, ws_app, error) -> None:
"""
websocket_error_handler is the handler called when we receive an error from the GO Feature Flag server
:param ws_app: the websocket app
:param error: error received
:return: None
"""
self._status = ProviderStatus.ERROR

def _websocket_close_handler(self, ws_app, close_status_code, close_msg) -> None:
"""
websocket_close_handler is the handler called when the websocket is closed
:param wsapp: the websocket app
:param close_status_code: the status code of the close
:param close_msg: the message of the close
:return: None
"""
self._status = ProviderStatus.STALE

def __hash__(self):
return id(self)

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from typing import Optional, Generic, Union, TypeVar
from typing import Optional, Union, TypeVar
from gofeatureflag_python_provider.options import BaseModel


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@

from gofeatureflag_python_provider.options import GoFeatureFlagOptions
from gofeatureflag_python_provider.provider import GoFeatureFlagProvider
from gofeatureflag_python_provider.provider_status import ProviderStatus

_default_evaluation_ctx = EvaluationContext(
targeting_key="d45e303a-38c2-11ed-a261-0242ac120002",
Expand Down Expand Up @@ -43,7 +42,6 @@ def _generic_test(
),
)
api.set_provider(goff_provider)
wait_provider_ready(goff_provider)
client = api.get_client(domain="test-client")

if evaluationType == "bool":
Expand Down Expand Up @@ -148,7 +146,6 @@ def test_should_return_an_error_if_endpoint_not_available(mock_request):
)
)
api.set_provider(goff_provider)
wait_provider_ready(goff_provider)
client = api.get_client(domain="test-client")
res = client.get_boolean_details(
flag_key=flag_key,
Expand Down Expand Up @@ -451,7 +448,6 @@ def test_should_resolve_from_cache_if_multiple_call_to_the_same_flag_with_same_c
)
)
api.set_provider(goff_provider)
wait_provider_ready(goff_provider)
client = api.get_client(domain="test-client")

got = client.get_boolean_details(
Expand Down Expand Up @@ -506,7 +502,6 @@ def test_should_call_data_collector_multiple_times_with_cached_event_waiting_ttl
)
)
api.set_provider(goff_provider)
wait_provider_ready(goff_provider)
client = api.get_client(domain="test-client")

got = client.get_boolean_details(
Expand Down Expand Up @@ -563,7 +558,6 @@ def test_should_not_call_data_collector_if_not_having_cache(mock_request: Mock):
)

api.set_provider(goff_provider)
wait_provider_ready(goff_provider)
client = api.get_client(domain="test-client")

client.get_boolean_details(
Expand All @@ -575,18 +569,6 @@ def test_should_not_call_data_collector_if_not_having_cache(mock_request: Mock):
assert mock_request.call_count == 1


def wait_provider_ready(provider: GoFeatureFlagProvider):
# check the provider get_status method until it returns ProviderStatus.READY or, we waited more than 5 seconds
start = time.time()
while provider.get_status() != ProviderStatus.READY:
time.sleep(0.1)
if time.time() - start > 5:
break

if provider.get_status() != ProviderStatus.READY:
raise Exception("Provider is not ready")


def _read_mock_file(flag_key: str) -> str:
# This hacky if is here to make test run inside pycharm and from the root of the project
if os.getcwd().endswith("/tests"):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
from gofeatureflag_python_provider.options import GoFeatureFlagOptions
from gofeatureflag_python_provider.provider import GoFeatureFlagProvider
from tests.test_gofeatureflag_python_provider import (
wait_provider_ready,
_default_evaluation_ctx,
)

Expand Down Expand Up @@ -54,7 +53,6 @@ def test_test_websocket_cache_invalidation(goff):
)
)
api.set_provider(goff_provider)
wait_provider_ready(goff_provider)
client = api.get_client(domain="test-client")

want = FlagEvaluationDetails(
Expand Down

0 comments on commit 55a85c9

Please sign in to comment.