From 80d77df8313633eea22192ec7b6fbd3fbd003670 Mon Sep 17 00:00:00 2001 From: Bilal Al-Shahwany Date: Tue, 22 Aug 2023 14:01:27 -0700 Subject: [PATCH 1/5] updated api.split and api.commons --- splitio/api/commons.py | 15 ++++++++++++++- splitio/api/splits.py | 3 +++ tests/api/test_splits_api.py | 8 ++++---- 3 files changed, 21 insertions(+), 5 deletions(-) diff --git a/splitio/api/commons.py b/splitio/api/commons.py index 92004cb8..2b83fd02 100644 --- a/splitio/api/commons.py +++ b/splitio/api/commons.py @@ -57,7 +57,7 @@ def record_telemetry(status_code, elapsed, metric_name, telemetry_runtime_produc class FetchOptions(object): """Fetch Options object.""" - def __init__(self, cache_control_headers=False, change_number=None): + def __init__(self, cache_control_headers=False, change_number=None, sets=None): """ Class constructor. @@ -66,9 +66,13 @@ def __init__(self, cache_control_headers=False, change_number=None): :param change_number: ChangeNumber to use for bypassing CDN in request. :type change_number: int + + :param sets: list of flag sets + :type sets: list """ self._cache_control_headers = cache_control_headers self._change_number = change_number + self._sets = sets @property def cache_control_headers(self): @@ -80,12 +84,19 @@ def change_number(self): """Return change number.""" return self._change_number + @property + def sets(self): + """Return change number.""" + return self._sets + def __eq__(self, other): """Match between other options.""" if self._cache_control_headers != other._cache_control_headers: return False if self._change_number != other._change_number: return False + if self._sets != other._sets: + return False return True @@ -113,4 +124,6 @@ def build_fetch(change_number, fetch_options, metadata): extra_headers[_CACHE_CONTROL] = _CACHE_CONTROL_NO_CACHE if fetch_options.change_number is not None: query['till'] = fetch_options.change_number + if fetch_options.sets is not None: + query['sets'] = ','.join(fetch_options.sets) return query, extra_headers \ No newline at end of file diff --git a/splitio/api/splits.py b/splitio/api/splits.py index b584111b..8cb23cfc 100644 --- a/splitio/api/splits.py +++ b/splitio/api/splits.py @@ -56,6 +56,9 @@ def fetch_splits(self, change_number, fetch_options): query=query, ) record_telemetry(response.status_code, get_current_epoch_time_ms() - start, HTTPExceptionsAndLatencies.SPLIT, self._telemetry_runtime_producer) + if response.status_code == 414: + _LOGGER.error('Error fetching feature flags; the amount of flag sets provided are too big, causing uri length error.') + if 200 <= response.status_code < 300: return json.loads(response.body) else: diff --git a/tests/api/test_splits_api.py b/tests/api/test_splits_api.py index 3c37b199..8caa55ae 100644 --- a/tests/api/test_splits_api.py +++ b/tests/api/test_splits_api.py @@ -19,7 +19,7 @@ def test_fetch_split_changes(self, mocker): httpclient.get.return_value = client.HttpResponse(200, '{"prop1": "value1"}') split_api = splits.SplitsAPI(httpclient, 'some_api_key', SdkMetadata('1.0', 'some', '1.2.3.4'), mocker.Mock()) - response = split_api.fetch_splits(123, FetchOptions()) + response = split_api.fetch_splits(123, FetchOptions(False, None, ['set1', 'set2'])) assert response['prop1'] == 'value1' assert httpclient.get.mock_calls == [mocker.call('sdk', '/splitChanges', 'some_api_key', extra_headers={ @@ -27,7 +27,7 @@ def test_fetch_split_changes(self, mocker): 'SplitSDKMachineIP': '1.2.3.4', 'SplitSDKMachineName': 'some' }, - query={'since': 123})] + query={'since': 123, 'sets': 'set1,set2'})] httpclient.reset_mock() response = split_api.fetch_splits(123, FetchOptions(True)) @@ -42,7 +42,7 @@ def test_fetch_split_changes(self, mocker): query={'since': 123})] httpclient.reset_mock() - response = split_api.fetch_splits(123, FetchOptions(True, 123)) + response = split_api.fetch_splits(123, FetchOptions(True, 123, ['set3'])) assert response['prop1'] == 'value1' assert httpclient.get.mock_calls == [mocker.call('sdk', '/splitChanges', 'some_api_key', extra_headers={ @@ -51,7 +51,7 @@ def test_fetch_split_changes(self, mocker): 'SplitSDKMachineName': 'some', 'Cache-Control': 'no-cache' }, - query={'since': 123, 'till': 123})] + query={'since': 123, 'till': 123, 'sets': 'set3'})] httpclient.reset_mock() def raise_exception(*args, **kwargs): From cc10af76ce0ed73eee058c167c4d7e6f564a6dd2 Mon Sep 17 00:00:00 2001 From: Bilal Al-Shahwany Date: Tue, 22 Aug 2023 14:04:14 -0700 Subject: [PATCH 2/5] polish --- splitio/api/commons.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/splitio/api/commons.py b/splitio/api/commons.py index 2b83fd02..9126c861 100644 --- a/splitio/api/commons.py +++ b/splitio/api/commons.py @@ -86,7 +86,7 @@ def change_number(self): @property def sets(self): - """Return change number.""" + """Return sets.""" return self._sets def __eq__(self, other): From 231281fc4095fe819d192c5bebe4c5fd657d3373 Mon Sep 17 00:00:00 2001 From: Bilal Al-Shahwany Date: Tue, 22 Aug 2023 14:15:26 -0700 Subject: [PATCH 3/5] added sorting sets in uri --- splitio/api/commons.py | 2 +- tests/api/test_splits_api.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/splitio/api/commons.py b/splitio/api/commons.py index 9126c861..6d7c90b7 100644 --- a/splitio/api/commons.py +++ b/splitio/api/commons.py @@ -125,5 +125,5 @@ def build_fetch(change_number, fetch_options, metadata): if fetch_options.change_number is not None: query['till'] = fetch_options.change_number if fetch_options.sets is not None: - query['sets'] = ','.join(fetch_options.sets) + query['sets'] = ','.join(sorted(fetch_options.sets)) return query, extra_headers \ No newline at end of file diff --git a/tests/api/test_splits_api.py b/tests/api/test_splits_api.py index 8caa55ae..b5f2086b 100644 --- a/tests/api/test_splits_api.py +++ b/tests/api/test_splits_api.py @@ -19,7 +19,7 @@ def test_fetch_split_changes(self, mocker): httpclient.get.return_value = client.HttpResponse(200, '{"prop1": "value1"}') split_api = splits.SplitsAPI(httpclient, 'some_api_key', SdkMetadata('1.0', 'some', '1.2.3.4'), mocker.Mock()) - response = split_api.fetch_splits(123, FetchOptions(False, None, ['set1', 'set2'])) + response = split_api.fetch_splits(123, FetchOptions(False, None, ['set2', 'set1'])) assert response['prop1'] == 'value1' assert httpclient.get.mock_calls == [mocker.call('sdk', '/splitChanges', 'some_api_key', extra_headers={ From a4d8ee81783591f2774b0eb04217c211439a6c72 Mon Sep 17 00:00:00 2001 From: Bilal Al-Shahwany Date: Wed, 23 Aug 2023 09:47:59 -0700 Subject: [PATCH 4/5] polish --- splitio/api/commons.py | 2 +- tests/api/test_splits_api.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/splitio/api/commons.py b/splitio/api/commons.py index 6d7c90b7..0766ae49 100644 --- a/splitio/api/commons.py +++ b/splitio/api/commons.py @@ -125,5 +125,5 @@ def build_fetch(change_number, fetch_options, metadata): if fetch_options.change_number is not None: query['till'] = fetch_options.change_number if fetch_options.sets is not None: - query['sets'] = ','.join(sorted(fetch_options.sets)) + query['sets'] = fetch_options.sets return query, extra_headers \ No newline at end of file diff --git a/tests/api/test_splits_api.py b/tests/api/test_splits_api.py index b5f2086b..e8d1784e 100644 --- a/tests/api/test_splits_api.py +++ b/tests/api/test_splits_api.py @@ -19,7 +19,7 @@ def test_fetch_split_changes(self, mocker): httpclient.get.return_value = client.HttpResponse(200, '{"prop1": "value1"}') split_api = splits.SplitsAPI(httpclient, 'some_api_key', SdkMetadata('1.0', 'some', '1.2.3.4'), mocker.Mock()) - response = split_api.fetch_splits(123, FetchOptions(False, None, ['set2', 'set1'])) + response = split_api.fetch_splits(123, FetchOptions(False, None, 'set1,set2')) assert response['prop1'] == 'value1' assert httpclient.get.mock_calls == [mocker.call('sdk', '/splitChanges', 'some_api_key', extra_headers={ @@ -42,7 +42,7 @@ def test_fetch_split_changes(self, mocker): query={'since': 123})] httpclient.reset_mock() - response = split_api.fetch_splits(123, FetchOptions(True, 123, ['set3'])) + response = split_api.fetch_splits(123, FetchOptions(True, 123, 'set3')) assert response['prop1'] == 'value1' assert httpclient.get.mock_calls == [mocker.call('sdk', '/splitChanges', 'some_api_key', extra_headers={ From 3649ada36def9f0426a0258581f523efb86afe8b Mon Sep 17 00:00:00 2001 From: Bilal Al-Shahwany Date: Mon, 28 Aug 2023 13:41:48 -0700 Subject: [PATCH 5/5] polish --- splitio/api/splits.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/splitio/api/splits.py b/splitio/api/splits.py index 8cb23cfc..78e15ef2 100644 --- a/splitio/api/splits.py +++ b/splitio/api/splits.py @@ -56,12 +56,11 @@ def fetch_splits(self, change_number, fetch_options): query=query, ) record_telemetry(response.status_code, get_current_epoch_time_ms() - start, HTTPExceptionsAndLatencies.SPLIT, self._telemetry_runtime_producer) - if response.status_code == 414: - _LOGGER.error('Error fetching feature flags; the amount of flag sets provided are too big, causing uri length error.') - if 200 <= response.status_code < 300: return json.loads(response.body) else: + if response.status_code == 414: + _LOGGER.error('Error fetching feature flags; the amount of flag sets provided are too big, causing uri length error.') raise APIException(response.body, response.status_code) except HttpClientException as exc: _LOGGER.error('Error fetching feature flags because an exception was raised by the HTTPClient')