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

fix(python): Fix URL formatting + authorized key #2707

Merged
merged 3 commits into from
Nov 23, 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 @@ -109,10 +109,14 @@ def _collect_data(self):
meta={"provider": "open-feature-python-sdk"},
events=self._event_queue,
)
headers = {"Content-Type": "application/json"}
if self._options.api_key:
headers["Authorization"] = "Bearer {}".format(self._options.api_key)

response = self._http_client.request(
method="POST",
url=urljoin(str(self._options.endpoint), "/v1/data/collector"),
headers={"Content-Type": "application/json"},
headers=headers,
body=goff_request.model_dump_json(),
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,8 @@ class GoFeatureFlagOptions(BaseModel):
# config changes.
# default: false
disable_cache_invalidation: typing.Optional[bool] = False

# api_key (optional) If the relay proxy is configured to authenticate the requests, you should provide
# an API Key to the provider. Please ask the administrator of the relay proxy to provide an API Key.
# Default: None
api_key: typing.Optional[str] = None
Original file line number Diff line number Diff line change
Expand Up @@ -188,13 +188,18 @@ def generic_go_feature_flag_resolver(
response_body = self._cache[evaluation_context_hash]
is_from_cache = True
else:
headers = {"Content-Type": "application/json"}
if self.options.api_key is not None:
headers["Authorization"] = "Bearer {}".format(self.options.api_key)
url = "{}{}".format(
str(self.options.endpoint).rstrip("/"),
"/v1/feature/{}/eval".format(flag_key),
)

response = self._http_client.request(
method="POST",
url=urljoin(
str(self.options.endpoint),
"/v1/feature/{}/eval".format(flag_key),
),
headers={"Content-Type": "application/json"},
url=url,
headers=headers,
body=goff_request.model_dump_json(),
)

Expand Down Expand Up @@ -261,10 +266,15 @@ def _build_websocket_uri(self):
_build_websocket_uri is a helper to build the websocket uri to connect to the GO Feature Flag relay proxy.
:return: a string representing the websocket uri
"""
http_uri = urljoin(
str(self.options.endpoint),
"/ws/v1/flag/change",
url = "/ws/v1/flag/change"
if self.options.api_key is not None:
url = "{}?apiKey={}".format(url, self.options.api_key)

http_uri = "{}{}".format(
str(self.options.endpoint).rstrip("/"),
url,
)

http_uri = http_uri.replace("http", "ws")
http_uri = http_uri.replace("https", "wss")
return http_uri
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,6 @@ services:
- POLLINGINTERVAL=1000
- RETRIEVER_KIND=file
- RETRIEVER_PATH=/config.goff.yaml
- AUTHORIZEDKEYS_EVALUATION=apikey1
volumes:
- ./config.goff.yaml:/config.goff.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ def _generic_test(
endpoint="https://gofeatureflag.org/",
data_flush_interval=100,
disable_cache_invalidation=True,
api_key="apikey1",
),
)
api.set_provider(goff_provider)
Expand Down Expand Up @@ -610,6 +611,31 @@ def _create_hook_context():
assert len(hook._event_queue) == 1


@patch("urllib3.poolmanager.PoolManager.request")
def test_url_parsing(mock_request):
flag_key = "bool_targeting_match"
mock_request.return_value = Mock(status="200", data=_read_mock_file(flag_key))
default_value = False
goff_provider = GoFeatureFlagProvider(
options=GoFeatureFlagOptions(
endpoint="https://gofeatureflag.org/ff/",
data_flush_interval=100,
disable_cache_invalidation=True,
api_key="apikey1",
),
)
api.set_provider(goff_provider)
client = api.get_client(domain="test-client")
t = client.get_boolean_details(
flag_key=flag_key,
default_value=default_value,
evaluation_context=_default_evaluation_ctx,
)
got = mock_request.call_args[1]["url"]
want = "https://gofeatureflag.org/ff/v1/feature/bool_targeting_match/eval"
assert got == want


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 @@ -50,6 +50,7 @@ def test_test_websocket_cache_invalidation(goff):
endpoint=goff,
data_flush_interval=100,
disable_data_collection=True,
api_key="apikey1",
)
)
api.set_provider(goff_provider)
Expand Down
Loading