Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(python of provider): Stop using provider.provider #1772

Merged
merged 7 commits into from
Apr 30, 2024
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
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