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: new headers and payload ( connection id and interval) #346

Merged
merged 24 commits into from
Mar 5, 2025
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
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
10 changes: 9 additions & 1 deletion UnleashClient/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ def __init__(
self.unleash_app_name = app_name
self.unleash_environment = environment
self.unleash_instance_id = instance_id
self.connection_id = str(uuid.uuid4())
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we had connection id before. is this code moved?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it was initialized only in headers before, now we can use it also in body if needed.

https://github.com/Unleash/unleash-client-python/pull/346/files#diff-d8684313c6cfe7bbd96df3385f5b28c7f337cd5159fc08f79b518df75cc13475L218

self.unleash_refresh_interval = refresh_interval
self.unleash_request_timeout = request_timeout
self.unleash_request_retries = request_retries
Expand Down Expand Up @@ -183,6 +184,10 @@ def __init__(
engine=self.engine,
)

@property
def unleash_refresh_interval_str_millis(self) -> str:
return str(self.unleash_refresh_interval * 1000)

def initialize_client(self, fetch_toggles: bool = True) -> None:
"""
Initializes client and starts communication with central unleash server(s).
Expand Down Expand Up @@ -215,7 +220,8 @@ def initialize_client(self, fetch_toggles: bool = True) -> None:
try:
headers = {
**self.unleash_custom_headers,
"unleash-connection-id": str(uuid.uuid4()),
"unleash-connection-id": self.connection_id,
"unleash-interval-id": self.unleash_refresh_interval_str_millis,
"unleash-appname": self.unleash_app_name,
"unleash-sdk": f"{SDK_NAME}:{SDK_VERSION}",
}
Expand All @@ -224,6 +230,7 @@ def initialize_client(self, fetch_toggles: bool = True) -> None:
metrics_args = {
"url": self.unleash_url,
"app_name": self.unleash_app_name,
"connection_id": self.connection_id,
"instance_id": self.unleash_instance_id,
"headers": headers,
"custom_options": self.unleash_custom_options,
Expand All @@ -237,6 +244,7 @@ def initialize_client(self, fetch_toggles: bool = True) -> None:
self.unleash_url,
self.unleash_app_name,
self.unleash_instance_id,
self.connection_id,
self.unleash_metrics_interval,
headers,
self.unleash_custom_options,
Expand Down
2 changes: 2 additions & 0 deletions UnleashClient/api/register.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ def register_client(
url: str,
app_name: str,
instance_id: str,
connection_id: str,
metrics_interval: int,
headers: dict,
custom_options: dict,
Expand All @@ -47,6 +48,7 @@ def register_client(
registration_request = {
"appName": app_name,
"instanceId": instance_id,
"connectionId": connection_id,
"sdkVersion": f"{SDK_NAME}:{SDK_VERSION}",
"strategies": [*supported_strategies],
"started": datetime.now(timezone.utc).isoformat(),
Expand Down
2 changes: 2 additions & 0 deletions UnleashClient/periodic_tasks/send_metrics.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ def aggregate_and_send_metrics(
url: str,
app_name: str,
instance_id: str,
connection_id: str,
headers: dict,
custom_options: dict,
request_timeout: int,
Expand All @@ -22,6 +23,7 @@ def aggregate_and_send_metrics(
metrics_request = {
"appName": app_name,
"instanceId": instance_id,
"connectionId": connection_id,
"bucket": metrics_bucket,
"platformName": python_implementation(),
"platformVersion": python_version(),
Expand Down
6 changes: 6 additions & 0 deletions tests/unit_tests/api/test_metrics.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import json

import responses
from pytest import mark, param
from requests import ConnectionError
Expand Down Expand Up @@ -36,5 +38,9 @@ def test_send_metrics(payload, status, expected):
URL, MOCK_METRICS_REQUEST, CUSTOM_HEADERS, CUSTOM_OPTIONS, REQUEST_TIMEOUT
)

request = json.loads(responses.calls[0].request.body)

assert len(responses.calls) == 1
assert expected(result)

assert request["connectionId"] == MOCK_METRICS_REQUEST.get("connectionId")
4 changes: 4 additions & 0 deletions tests/unit_tests/api/test_register.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

from tests.utilities.testing_constants import (
APP_NAME,
CONNECTION_ID,
CUSTOM_HEADERS,
CUSTOM_OPTIONS,
INSTANCE_ID,
Expand Down Expand Up @@ -40,6 +41,7 @@ def test_register_client(payload, status, expected):
URL,
APP_NAME,
INSTANCE_ID,
CONNECTION_ID,
METRICS_INTERVAL,
CUSTOM_HEADERS,
CUSTOM_OPTIONS,
Expand All @@ -59,6 +61,7 @@ def test_register_includes_metadata():
URL,
APP_NAME,
INSTANCE_ID,
CONNECTION_ID,
METRICS_INTERVAL,
CUSTOM_HEADERS,
CUSTOM_OPTIONS,
Expand All @@ -71,5 +74,6 @@ def test_register_includes_metadata():

assert request["yggdrasilVersion"] is not None
assert request["specVersion"] == CLIENT_SPEC_VERSION
assert request["connectionId"] == CONNECTION_ID
assert request["platformName"] is not None
assert request["platformVersion"] is not None
35 changes: 35 additions & 0 deletions tests/unit_tests/test_client.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import json
import time
import warnings
from datetime import datetime, timezone
Expand Down Expand Up @@ -1078,3 +1079,37 @@ def test_identification_headers_unique_connection_id():
"UNLEASH-CONNECTION-ID"
]
assert connection_id_first_client != connection_id_second_client


@responses.activate
def test_identification_values_are_passed_in():
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is testing all 3 requests, headers and body

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

responses.add(responses.POST, URL + REGISTER_URL, json={}, status=202)
responses.add(
responses.GET, URL + FEATURES_URL, json=MOCK_FEATURE_RESPONSE, status=200
)
responses.add(responses.POST, URL + METRICS_URL, json={}, status=202)

input_interval = 1
unleash_client = UnleashClient(
URL, APP_NAME, refresh_interval=input_interval, metrics_interval=1
)
expected_connection_id = unleash_client.connection_id
expected_interval = str(input_interval * 1000)

unleash_client.initialize_client()
register_request = responses.calls[0].request
reqister_body = json.loads(register_request.body)

assert register_request.headers["UNLEASH-CONNECTION-ID"] == expected_connection_id
assert reqister_body["connectionId"] == expected_connection_id

features_request = responses.calls[1].request

assert features_request.headers["UNLEASH-CONNECTION-ID"] == expected_connection_id
assert features_request.headers["UNLEASH-INTERVAL-ID"] == expected_interval

time.sleep(2)
metrics_request = responses.calls[2].request

assert metrics_request.headers["UNLEASH-CONNECTION-ID"] == expected_connection_id
assert metrics_request.headers["UNLEASH-INTERVAL-ID"] == expected_interval
1 change: 1 addition & 0 deletions tests/utilities/mocks/mock_metrics.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
MOCK_METRICS_REQUEST = {
"appName": "appName",
"instanceId": "instanceId",
"connectionId": "connectionId",
"bucket": {
"start": "2016-11-03T07:16:43.572Z",
"stop": "2016-11-03T07:16:53.572Z",
Expand Down
1 change: 1 addition & 0 deletions tests/utilities/testing_constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
APP_NAME = "pytest"
ENVIRONMENT = "unit"
INSTANCE_ID = "123"
CONNECTION_ID = "test-connection-id"
REFRESH_INTERVAL = 3
REFRESH_JITTER = None
METRICS_INTERVAL = 2
Expand Down
Loading