splitio-client 10.0.1__tar.gz → 10.1.0rc2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {splitio_client-10.0.1 → splitio_client-10.1.0rc2}/PKG-INFO +3 -2
- {splitio_client-10.0.1 → splitio_client-10.1.0rc2}/setup.py +4 -2
- {splitio_client-10.0.1 → splitio_client-10.1.0rc2}/splitio/api/client.py +82 -44
- {splitio_client-10.0.1 → splitio_client-10.1.0rc2}/splitio/client/config.py +21 -1
- {splitio_client-10.0.1 → splitio_client-10.1.0rc2}/splitio/client/factory.py +9 -2
- {splitio_client-10.0.1 → splitio_client-10.1.0rc2}/splitio/optional/loaders.py +12 -0
- splitio_client-10.1.0rc2/splitio/version.py +1 -0
- {splitio_client-10.0.1 → splitio_client-10.1.0rc2}/splitio_client.egg-info/PKG-INFO +3 -2
- {splitio_client-10.0.1 → splitio_client-10.1.0rc2}/splitio_client.egg-info/requires.txt +4 -0
- splitio_client-10.0.1/splitio/version.py +0 -1
- {splitio_client-10.0.1 → splitio_client-10.1.0rc2}/README.md +0 -0
- {splitio_client-10.0.1 → splitio_client-10.1.0rc2}/setup.cfg +0 -0
- {splitio_client-10.0.1 → splitio_client-10.1.0rc2}/splitio/__init__.py +0 -0
- {splitio_client-10.0.1 → splitio_client-10.1.0rc2}/splitio/api/__init__.py +0 -0
- {splitio_client-10.0.1 → splitio_client-10.1.0rc2}/splitio/api/auth.py +0 -0
- {splitio_client-10.0.1 → splitio_client-10.1.0rc2}/splitio/api/commons.py +0 -0
- {splitio_client-10.0.1 → splitio_client-10.1.0rc2}/splitio/api/events.py +0 -0
- {splitio_client-10.0.1 → splitio_client-10.1.0rc2}/splitio/api/impressions.py +0 -0
- {splitio_client-10.0.1 → splitio_client-10.1.0rc2}/splitio/api/segments.py +0 -0
- {splitio_client-10.0.1 → splitio_client-10.1.0rc2}/splitio/api/splits.py +0 -0
- {splitio_client-10.0.1 → splitio_client-10.1.0rc2}/splitio/api/telemetry.py +0 -0
- {splitio_client-10.0.1 → splitio_client-10.1.0rc2}/splitio/client/__init__.py +0 -0
- {splitio_client-10.0.1 → splitio_client-10.1.0rc2}/splitio/client/client.py +0 -0
- {splitio_client-10.0.1 → splitio_client-10.1.0rc2}/splitio/client/input_validator.py +0 -0
- {splitio_client-10.0.1 → splitio_client-10.1.0rc2}/splitio/client/key.py +0 -0
- {splitio_client-10.0.1 → splitio_client-10.1.0rc2}/splitio/client/listener.py +0 -0
- {splitio_client-10.0.1 → splitio_client-10.1.0rc2}/splitio/client/localhost.py +0 -0
- {splitio_client-10.0.1 → splitio_client-10.1.0rc2}/splitio/client/manager.py +0 -0
- {splitio_client-10.0.1 → splitio_client-10.1.0rc2}/splitio/client/util.py +0 -0
- {splitio_client-10.0.1 → splitio_client-10.1.0rc2}/splitio/engine/__init__.py +0 -0
- {splitio_client-10.0.1 → splitio_client-10.1.0rc2}/splitio/engine/cache/__init__.py +0 -0
- {splitio_client-10.0.1 → splitio_client-10.1.0rc2}/splitio/engine/cache/lru.py +0 -0
- {splitio_client-10.0.1 → splitio_client-10.1.0rc2}/splitio/engine/evaluator.py +0 -0
- {splitio_client-10.0.1 → splitio_client-10.1.0rc2}/splitio/engine/filters.py +0 -0
- {splitio_client-10.0.1 → splitio_client-10.1.0rc2}/splitio/engine/hashfns/__init__.py +0 -0
- {splitio_client-10.0.1 → splitio_client-10.1.0rc2}/splitio/engine/hashfns/legacy.py +0 -0
- {splitio_client-10.0.1 → splitio_client-10.1.0rc2}/splitio/engine/hashfns/murmur3py.py +0 -0
- {splitio_client-10.0.1 → splitio_client-10.1.0rc2}/splitio/engine/impressions/__init__.py +0 -0
- {splitio_client-10.0.1 → splitio_client-10.1.0rc2}/splitio/engine/impressions/adapters.py +0 -0
- {splitio_client-10.0.1 → splitio_client-10.1.0rc2}/splitio/engine/impressions/impressions.py +0 -0
- {splitio_client-10.0.1 → splitio_client-10.1.0rc2}/splitio/engine/impressions/manager.py +0 -0
- {splitio_client-10.0.1 → splitio_client-10.1.0rc2}/splitio/engine/impressions/strategies.py +0 -0
- {splitio_client-10.0.1 → splitio_client-10.1.0rc2}/splitio/engine/impressions/unique_keys_tracker.py +0 -0
- {splitio_client-10.0.1 → splitio_client-10.1.0rc2}/splitio/engine/splitters.py +0 -0
- {splitio_client-10.0.1 → splitio_client-10.1.0rc2}/splitio/engine/telemetry.py +0 -0
- {splitio_client-10.0.1 → splitio_client-10.1.0rc2}/splitio/exceptions.py +0 -0
- {splitio_client-10.0.1 → splitio_client-10.1.0rc2}/splitio/factories.py +0 -0
- {splitio_client-10.0.1 → splitio_client-10.1.0rc2}/splitio/impressions.py +0 -0
- {splitio_client-10.0.1 → splitio_client-10.1.0rc2}/splitio/key.py +0 -0
- {splitio_client-10.0.1 → splitio_client-10.1.0rc2}/splitio/models/__init__.py +0 -0
- {splitio_client-10.0.1 → splitio_client-10.1.0rc2}/splitio/models/datatypes.py +0 -0
- {splitio_client-10.0.1 → splitio_client-10.1.0rc2}/splitio/models/events.py +0 -0
- {splitio_client-10.0.1 → splitio_client-10.1.0rc2}/splitio/models/grammar/__init__.py +0 -0
- {splitio_client-10.0.1 → splitio_client-10.1.0rc2}/splitio/models/grammar/condition.py +0 -0
- {splitio_client-10.0.1 → splitio_client-10.1.0rc2}/splitio/models/grammar/matchers/__init__.py +0 -0
- {splitio_client-10.0.1 → splitio_client-10.1.0rc2}/splitio/models/grammar/matchers/base.py +0 -0
- {splitio_client-10.0.1 → splitio_client-10.1.0rc2}/splitio/models/grammar/matchers/keys.py +0 -0
- {splitio_client-10.0.1 → splitio_client-10.1.0rc2}/splitio/models/grammar/matchers/misc.py +0 -0
- {splitio_client-10.0.1 → splitio_client-10.1.0rc2}/splitio/models/grammar/matchers/numeric.py +0 -0
- {splitio_client-10.0.1 → splitio_client-10.1.0rc2}/splitio/models/grammar/matchers/semver.py +0 -0
- {splitio_client-10.0.1 → splitio_client-10.1.0rc2}/splitio/models/grammar/matchers/sets.py +0 -0
- {splitio_client-10.0.1 → splitio_client-10.1.0rc2}/splitio/models/grammar/matchers/string.py +0 -0
- {splitio_client-10.0.1 → splitio_client-10.1.0rc2}/splitio/models/grammar/matchers/utils/__init__.py +0 -0
- {splitio_client-10.0.1 → splitio_client-10.1.0rc2}/splitio/models/grammar/matchers/utils/utils.py +0 -0
- {splitio_client-10.0.1 → splitio_client-10.1.0rc2}/splitio/models/grammar/partitions.py +0 -0
- {splitio_client-10.0.1 → splitio_client-10.1.0rc2}/splitio/models/impressions.py +0 -0
- {splitio_client-10.0.1 → splitio_client-10.1.0rc2}/splitio/models/notification.py +0 -0
- {splitio_client-10.0.1 → splitio_client-10.1.0rc2}/splitio/models/segments.py +0 -0
- {splitio_client-10.0.1 → splitio_client-10.1.0rc2}/splitio/models/splits.py +0 -0
- {splitio_client-10.0.1 → splitio_client-10.1.0rc2}/splitio/models/telemetry.py +0 -0
- {splitio_client-10.0.1 → splitio_client-10.1.0rc2}/splitio/models/token.py +0 -0
- {splitio_client-10.0.1 → splitio_client-10.1.0rc2}/splitio/optional/__init__.py +0 -0
- {splitio_client-10.0.1 → splitio_client-10.1.0rc2}/splitio/push/__init__.py +0 -0
- {splitio_client-10.0.1 → splitio_client-10.1.0rc2}/splitio/push/manager.py +0 -0
- {splitio_client-10.0.1 → splitio_client-10.1.0rc2}/splitio/push/parser.py +0 -0
- {splitio_client-10.0.1 → splitio_client-10.1.0rc2}/splitio/push/processor.py +0 -0
- {splitio_client-10.0.1 → splitio_client-10.1.0rc2}/splitio/push/splitsse.py +0 -0
- {splitio_client-10.0.1 → splitio_client-10.1.0rc2}/splitio/push/sse.py +0 -0
- {splitio_client-10.0.1 → splitio_client-10.1.0rc2}/splitio/push/status_tracker.py +0 -0
- {splitio_client-10.0.1 → splitio_client-10.1.0rc2}/splitio/push/workers.py +0 -0
- {splitio_client-10.0.1 → splitio_client-10.1.0rc2}/splitio/recorder/__init__.py +0 -0
- {splitio_client-10.0.1 → splitio_client-10.1.0rc2}/splitio/recorder/recorder.py +0 -0
- {splitio_client-10.0.1 → splitio_client-10.1.0rc2}/splitio/spec.py +0 -0
- {splitio_client-10.0.1 → splitio_client-10.1.0rc2}/splitio/storage/__init__.py +0 -0
- {splitio_client-10.0.1 → splitio_client-10.1.0rc2}/splitio/storage/adapters/__init__.py +0 -0
- {splitio_client-10.0.1 → splitio_client-10.1.0rc2}/splitio/storage/adapters/cache_trait.py +0 -0
- {splitio_client-10.0.1 → splitio_client-10.1.0rc2}/splitio/storage/adapters/redis.py +0 -0
- {splitio_client-10.0.1 → splitio_client-10.1.0rc2}/splitio/storage/adapters/util.py +0 -0
- {splitio_client-10.0.1 → splitio_client-10.1.0rc2}/splitio/storage/inmemmory.py +0 -0
- {splitio_client-10.0.1 → splitio_client-10.1.0rc2}/splitio/storage/pluggable.py +0 -0
- {splitio_client-10.0.1 → splitio_client-10.1.0rc2}/splitio/storage/redis.py +0 -0
- {splitio_client-10.0.1 → splitio_client-10.1.0rc2}/splitio/sync/__init__.py +0 -0
- {splitio_client-10.0.1 → splitio_client-10.1.0rc2}/splitio/sync/event.py +0 -0
- {splitio_client-10.0.1 → splitio_client-10.1.0rc2}/splitio/sync/impression.py +0 -0
- {splitio_client-10.0.1 → splitio_client-10.1.0rc2}/splitio/sync/manager.py +0 -0
- {splitio_client-10.0.1 → splitio_client-10.1.0rc2}/splitio/sync/segment.py +0 -0
- {splitio_client-10.0.1 → splitio_client-10.1.0rc2}/splitio/sync/split.py +0 -0
- {splitio_client-10.0.1 → splitio_client-10.1.0rc2}/splitio/sync/synchronizer.py +0 -0
- {splitio_client-10.0.1 → splitio_client-10.1.0rc2}/splitio/sync/telemetry.py +0 -0
- {splitio_client-10.0.1 → splitio_client-10.1.0rc2}/splitio/sync/unique_keys.py +0 -0
- {splitio_client-10.0.1 → splitio_client-10.1.0rc2}/splitio/sync/util.py +0 -0
- {splitio_client-10.0.1 → splitio_client-10.1.0rc2}/splitio/tasks/__init__.py +0 -0
- {splitio_client-10.0.1 → splitio_client-10.1.0rc2}/splitio/tasks/events_sync.py +0 -0
- {splitio_client-10.0.1 → splitio_client-10.1.0rc2}/splitio/tasks/impressions_sync.py +0 -0
- {splitio_client-10.0.1 → splitio_client-10.1.0rc2}/splitio/tasks/segment_sync.py +0 -0
- {splitio_client-10.0.1 → splitio_client-10.1.0rc2}/splitio/tasks/split_sync.py +0 -0
- {splitio_client-10.0.1 → splitio_client-10.1.0rc2}/splitio/tasks/telemetry_sync.py +0 -0
- {splitio_client-10.0.1 → splitio_client-10.1.0rc2}/splitio/tasks/unique_keys_sync.py +0 -0
- {splitio_client-10.0.1 → splitio_client-10.1.0rc2}/splitio/tasks/util/__init__.py +0 -0
- {splitio_client-10.0.1 → splitio_client-10.1.0rc2}/splitio/tasks/util/asynctask.py +0 -0
- {splitio_client-10.0.1 → splitio_client-10.1.0rc2}/splitio/tasks/util/workerpool.py +0 -0
- {splitio_client-10.0.1 → splitio_client-10.1.0rc2}/splitio/util/__init__.py +0 -0
- {splitio_client-10.0.1 → splitio_client-10.1.0rc2}/splitio/util/backoff.py +0 -0
- {splitio_client-10.0.1 → splitio_client-10.1.0rc2}/splitio/util/decorators.py +0 -0
- {splitio_client-10.0.1 → splitio_client-10.1.0rc2}/splitio/util/storage_helper.py +0 -0
- {splitio_client-10.0.1 → splitio_client-10.1.0rc2}/splitio/util/threadutil.py +0 -0
- {splitio_client-10.0.1 → splitio_client-10.1.0rc2}/splitio/util/time.py +0 -0
- {splitio_client-10.0.1 → splitio_client-10.1.0rc2}/splitio_client.egg-info/SOURCES.txt +0 -0
- {splitio_client-10.0.1 → splitio_client-10.1.0rc2}/splitio_client.egg-info/dependency_links.txt +0 -0
- {splitio_client-10.0.1 → splitio_client-10.1.0rc2}/splitio_client.egg-info/top_level.txt +0 -0
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: splitio_client
|
|
3
|
-
Version: 10.
|
|
3
|
+
Version: 10.1.0rc2
|
|
4
4
|
Summary: Split.io Python Client
|
|
5
5
|
Home-page: https://github.com/splitio/python-client
|
|
6
6
|
Author: Patricio Echague, Sebastian Arrubia
|
|
7
7
|
Author-email: pato@split.io, sebastian@split.io
|
|
8
8
|
License: Apache License 2.0
|
|
9
|
-
Download-URL: https://github.com/splitio/python-client/tarball/10.
|
|
9
|
+
Download-URL: https://github.com/splitio/python-client/tarball/10.1.0rc2
|
|
10
10
|
Description: # Split Python SDK
|
|
11
11
|

|
|
12
12
|
|
|
@@ -98,3 +98,4 @@ Provides-Extra: redis
|
|
|
98
98
|
Provides-Extra: uwsgi
|
|
99
99
|
Provides-Extra: cpphash
|
|
100
100
|
Provides-Extra: asyncio
|
|
101
|
+
Provides-Extra: kerberos
|
|
@@ -16,7 +16,8 @@ TESTS_REQUIRES = [
|
|
|
16
16
|
'attrs==22.1.0',
|
|
17
17
|
'pytest-asyncio==0.21.0',
|
|
18
18
|
'aiohttp>=3.8.4',
|
|
19
|
-
'aiofiles>=23.1.0'
|
|
19
|
+
'aiofiles>=23.1.0',
|
|
20
|
+
'requests-kerberos>=0.15.0'
|
|
20
21
|
]
|
|
21
22
|
|
|
22
23
|
INSTALL_REQUIRES = [
|
|
@@ -46,7 +47,8 @@ setup(
|
|
|
46
47
|
'redis': ['redis>=2.10.5'],
|
|
47
48
|
'uwsgi': ['uwsgi>=2.0.0'],
|
|
48
49
|
'cpphash': ['mmh3cffi==0.2.1'],
|
|
49
|
-
'asyncio': ['aiohttp>=3.8.4', 'aiofiles>=23.1.0']
|
|
50
|
+
'asyncio': ['aiohttp>=3.8.4', 'aiofiles>=23.1.0'],
|
|
51
|
+
'kerberos': ['requests-kerberos>=0.15.0']
|
|
50
52
|
},
|
|
51
53
|
setup_requires=['pytest-runner', 'pluggy==1.0.0;python_version<"3.8"'],
|
|
52
54
|
classifiers=[
|
|
@@ -5,7 +5,11 @@ import urllib
|
|
|
5
5
|
import abc
|
|
6
6
|
import logging
|
|
7
7
|
import json
|
|
8
|
+
import threading
|
|
9
|
+
from urllib3.util import parse_url
|
|
8
10
|
|
|
11
|
+
from splitio.optional.loaders import HTTPKerberosAuth, OPTIONAL
|
|
12
|
+
from splitio.client.config import AuthenticateScheme
|
|
9
13
|
from splitio.optional.loaders import aiohttp
|
|
10
14
|
from splitio.util.time import get_current_epoch_time_ms
|
|
11
15
|
|
|
@@ -67,6 +71,24 @@ class HttpClientException(Exception):
|
|
|
67
71
|
"""
|
|
68
72
|
Exception.__init__(self, message)
|
|
69
73
|
|
|
74
|
+
class HTTPAdapterWithProxyKerberosAuth(requests.adapters.HTTPAdapter):
|
|
75
|
+
"""HTTPAdapter override for Kerberos Proxy auth"""
|
|
76
|
+
|
|
77
|
+
def __init__(self, principal=None, password=None):
|
|
78
|
+
requests.adapters.HTTPAdapter.__init__(self)
|
|
79
|
+
self._principal = principal
|
|
80
|
+
self._password = password
|
|
81
|
+
|
|
82
|
+
def proxy_headers(self, proxy):
|
|
83
|
+
headers = {}
|
|
84
|
+
if self._principal is not None:
|
|
85
|
+
auth = HTTPKerberosAuth(principal=self._principal, password=self._password)
|
|
86
|
+
else:
|
|
87
|
+
auth = HTTPKerberosAuth()
|
|
88
|
+
negotiate_details = auth.generate_request_header(None, parse_url(proxy).host, is_preemptive=True)
|
|
89
|
+
headers['Proxy-Authorization'] = negotiate_details
|
|
90
|
+
return headers
|
|
91
|
+
|
|
70
92
|
class HttpClientBase(object, metaclass=abc.ABCMeta):
|
|
71
93
|
"""HttpClient wrapper template."""
|
|
72
94
|
|
|
@@ -91,11 +113,16 @@ class HttpClientBase(object, metaclass=abc.ABCMeta):
|
|
|
91
113
|
self._telemetry_runtime_producer = telemetry_runtime_producer
|
|
92
114
|
self._metric_name = metric_name
|
|
93
115
|
|
|
116
|
+
def _get_headers(self, extra_headers, sdk_key):
|
|
117
|
+
headers = _build_basic_headers(sdk_key)
|
|
118
|
+
if extra_headers is not None:
|
|
119
|
+
headers.update(extra_headers)
|
|
120
|
+
return headers
|
|
94
121
|
|
|
95
122
|
class HttpClient(HttpClientBase):
|
|
96
123
|
"""HttpClient wrapper."""
|
|
97
124
|
|
|
98
|
-
def __init__(self, timeout=None, sdk_url=None, events_url=None, auth_url=None, telemetry_url=None):
|
|
125
|
+
def __init__(self, timeout=None, sdk_url=None, events_url=None, auth_url=None, telemetry_url=None, authentication_scheme=None, authentication_params=None):
|
|
99
126
|
"""
|
|
100
127
|
Class constructor.
|
|
101
128
|
|
|
@@ -110,8 +137,12 @@ class HttpClient(HttpClientBase):
|
|
|
110
137
|
:param telemetry_url: Optional alternative telemetry URL.
|
|
111
138
|
:type telemetry_url: str
|
|
112
139
|
"""
|
|
140
|
+
_LOGGER.debug("Initializing httpclient")
|
|
113
141
|
self._timeout = timeout/1000 if timeout else None # Convert ms to seconds.
|
|
114
142
|
self._urls = _construct_urls(sdk_url, events_url, auth_url, telemetry_url)
|
|
143
|
+
self._authentication_scheme = authentication_scheme
|
|
144
|
+
self._authentication_params = authentication_params
|
|
145
|
+
self._lock = threading.RLock()
|
|
115
146
|
|
|
116
147
|
def get(self, server, path, sdk_key, query=None, extra_headers=None): # pylint: disable=too-many-arguments
|
|
117
148
|
"""
|
|
@@ -131,23 +162,22 @@ class HttpClient(HttpClientBase):
|
|
|
131
162
|
:return: Tuple of status_code & response text
|
|
132
163
|
:rtype: HttpResponse
|
|
133
164
|
"""
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
raise HttpClientException('requests library is throwing exceptions') from exc
|
|
165
|
+
with self._lock:
|
|
166
|
+
start = get_current_epoch_time_ms()
|
|
167
|
+
with requests.Session() as session:
|
|
168
|
+
self._set_authentication(session)
|
|
169
|
+
try:
|
|
170
|
+
response = session.get(
|
|
171
|
+
_build_url(server, path, self._urls),
|
|
172
|
+
params=query,
|
|
173
|
+
headers=self._get_headers(extra_headers, sdk_key),
|
|
174
|
+
timeout=self._timeout
|
|
175
|
+
)
|
|
176
|
+
self._record_telemetry(response.status_code, get_current_epoch_time_ms() - start)
|
|
177
|
+
return HttpResponse(response.status_code, response.text, response.headers)
|
|
178
|
+
|
|
179
|
+
except Exception as exc: # pylint: disable=broad-except
|
|
180
|
+
raise HttpClientException('requests library is throwing exceptions') from exc
|
|
151
181
|
|
|
152
182
|
def post(self, server, path, sdk_key, body, query=None, extra_headers=None): # pylint: disable=too-many-arguments
|
|
153
183
|
"""
|
|
@@ -169,25 +199,37 @@ class HttpClient(HttpClientBase):
|
|
|
169
199
|
:return: Tuple of status_code & response text
|
|
170
200
|
:rtype: HttpResponse
|
|
171
201
|
"""
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
202
|
+
with self._lock:
|
|
203
|
+
start = get_current_epoch_time_ms()
|
|
204
|
+
with requests.Session() as session:
|
|
205
|
+
self._set_authentication(session)
|
|
206
|
+
try:
|
|
207
|
+
response = session.post(
|
|
208
|
+
_build_url(server, path, self._urls),
|
|
209
|
+
json=body,
|
|
210
|
+
params=query,
|
|
211
|
+
headers=self._get_headers(extra_headers, sdk_key),
|
|
212
|
+
timeout=self._timeout,
|
|
213
|
+
)
|
|
214
|
+
self._record_telemetry(response.status_code, get_current_epoch_time_ms() - start)
|
|
215
|
+
return HttpResponse(response.status_code, response.text, response.headers)
|
|
216
|
+
except Exception as exc: # pylint: disable=broad-except
|
|
217
|
+
raise HttpClientException('requests library is throwing exceptions') from exc
|
|
218
|
+
|
|
219
|
+
def _set_authentication(self, session):
|
|
220
|
+
if self._authentication_scheme == AuthenticateScheme.KERBEROS_SPNEGO:
|
|
221
|
+
_LOGGER.debug("Using Kerberos Spnego Authentication")
|
|
222
|
+
if self._authentication_params != [None, None]:
|
|
223
|
+
session.auth = HTTPKerberosAuth(principal=self._authentication_params[0], password=self._authentication_params[1], mutual_authentication=OPTIONAL)
|
|
224
|
+
else:
|
|
225
|
+
session.auth = HTTPKerberosAuth(mutual_authentication=OPTIONAL)
|
|
226
|
+
elif self._authentication_scheme == AuthenticateScheme.KERBEROS_PROXY:
|
|
227
|
+
_LOGGER.debug("Using Kerberos Proxy Authentication")
|
|
228
|
+
if self._authentication_params != [None, None]:
|
|
229
|
+
session.mount('https://', HTTPAdapterWithProxyKerberosAuth(principal=self._authentication_params[0], password=self._authentication_params[1]))
|
|
230
|
+
else:
|
|
231
|
+
session.mount('https://', HTTPAdapterWithProxyKerberosAuth())
|
|
188
232
|
|
|
189
|
-
except Exception as exc: # pylint: disable=broad-except
|
|
190
|
-
raise HttpClientException('requests library is throwing exceptions') from exc
|
|
191
233
|
|
|
192
234
|
def _record_telemetry(self, status_code, elapsed):
|
|
193
235
|
"""
|
|
@@ -203,8 +245,8 @@ class HttpClient(HttpClientBase):
|
|
|
203
245
|
if 200 <= status_code < 300:
|
|
204
246
|
self._telemetry_runtime_producer.record_successful_sync(self._metric_name, get_current_epoch_time_ms())
|
|
205
247
|
return
|
|
206
|
-
self._telemetry_runtime_producer.record_sync_error(self._metric_name, status_code)
|
|
207
248
|
|
|
249
|
+
self._telemetry_runtime_producer.record_sync_error(self._metric_name, status_code)
|
|
208
250
|
|
|
209
251
|
class HttpClientAsync(HttpClientBase):
|
|
210
252
|
"""HttpClientAsync wrapper."""
|
|
@@ -243,10 +285,8 @@ class HttpClientAsync(HttpClientBase):
|
|
|
243
285
|
:return: Tuple of status_code & response text
|
|
244
286
|
:rtype: HttpResponse
|
|
245
287
|
"""
|
|
246
|
-
headers = _build_basic_headers(apikey)
|
|
247
|
-
if extra_headers is not None:
|
|
248
|
-
headers.update(extra_headers)
|
|
249
288
|
start = get_current_epoch_time_ms()
|
|
289
|
+
headers = self._get_headers(extra_headers, apikey)
|
|
250
290
|
try:
|
|
251
291
|
url = _build_url(server, path, self._urls)
|
|
252
292
|
_LOGGER.debug("GET request: %s", url)
|
|
@@ -286,9 +326,7 @@ class HttpClientAsync(HttpClientBase):
|
|
|
286
326
|
:return: Tuple of status_code & response text
|
|
287
327
|
:rtype: HttpResponse
|
|
288
328
|
"""
|
|
289
|
-
headers =
|
|
290
|
-
if extra_headers is not None:
|
|
291
|
-
headers.update(extra_headers)
|
|
329
|
+
headers = self._get_headers(extra_headers, apikey)
|
|
292
330
|
start = get_current_epoch_time_ms()
|
|
293
331
|
try:
|
|
294
332
|
headers['Accept-Encoding'] = 'gzip'
|
|
@@ -333,4 +371,4 @@ class HttpClientAsync(HttpClientBase):
|
|
|
333
371
|
|
|
334
372
|
async def close_session(self):
|
|
335
373
|
if not self._session.closed:
|
|
336
|
-
await self._session.close()
|
|
374
|
+
await self._session.close()
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"""Default settings for the Split.IO SDK Python client."""
|
|
2
2
|
import os.path
|
|
3
3
|
import logging
|
|
4
|
+
from enum import Enum
|
|
4
5
|
|
|
5
6
|
from splitio.engine.impressions import ImpressionsMode
|
|
6
7
|
from splitio.client.input_validator import validate_flag_sets
|
|
@@ -8,6 +9,12 @@ from splitio.client.input_validator import validate_flag_sets
|
|
|
8
9
|
_LOGGER = logging.getLogger(__name__)
|
|
9
10
|
DEFAULT_DATA_SAMPLING = 1
|
|
10
11
|
|
|
12
|
+
class AuthenticateScheme(Enum):
|
|
13
|
+
"""Authentication Scheme."""
|
|
14
|
+
NONE = 'NONE'
|
|
15
|
+
KERBEROS_SPNEGO = 'KERBEROS_SPNEGO'
|
|
16
|
+
KERBEROS_PROXY = 'KERBEROS_PROXY'
|
|
17
|
+
|
|
11
18
|
DEFAULT_CONFIG = {
|
|
12
19
|
'operationMode': 'standalone',
|
|
13
20
|
'connectionTimeout': 1500,
|
|
@@ -59,7 +66,10 @@ DEFAULT_CONFIG = {
|
|
|
59
66
|
'storageWrapper': None,
|
|
60
67
|
'storagePrefix': None,
|
|
61
68
|
'storageType': None,
|
|
62
|
-
'flagSetsFilter': None
|
|
69
|
+
'flagSetsFilter': None,
|
|
70
|
+
'httpAuthenticateScheme': AuthenticateScheme.NONE,
|
|
71
|
+
'kerberosPrincipalUser': None,
|
|
72
|
+
'kerberosPrincipalPassword': None
|
|
63
73
|
}
|
|
64
74
|
|
|
65
75
|
def _parse_operation_mode(sdk_key, config):
|
|
@@ -148,4 +158,14 @@ def sanitize(sdk_key, config):
|
|
|
148
158
|
else:
|
|
149
159
|
processed['flagSetsFilter'] = sorted(validate_flag_sets(processed['flagSetsFilter'], 'SDK Config')) if processed['flagSetsFilter'] is not None else None
|
|
150
160
|
|
|
161
|
+
if config.get('httpAuthenticateScheme') is not None:
|
|
162
|
+
try:
|
|
163
|
+
authenticate_scheme = AuthenticateScheme(config['httpAuthenticateScheme'].upper())
|
|
164
|
+
except (ValueError, AttributeError):
|
|
165
|
+
authenticate_scheme = AuthenticateScheme.NONE
|
|
166
|
+
_LOGGER.warning('You passed an invalid HttpAuthenticationScheme, HttpAuthenticationScheme should be ' \
|
|
167
|
+
'one of the following values: `none`, `kerberos_proxy` or `kerberos_spnego`. '
|
|
168
|
+
' Defaulting to `none` mode.')
|
|
169
|
+
processed["httpAuthenticateScheme"] = authenticate_scheme
|
|
170
|
+
|
|
151
171
|
return processed
|
|
@@ -7,8 +7,8 @@ from enum import Enum
|
|
|
7
7
|
from splitio.optional.loaders import asyncio
|
|
8
8
|
from splitio.client.client import Client, ClientAsync
|
|
9
9
|
from splitio.client import input_validator
|
|
10
|
+
from splitio.client.config import sanitize as sanitize_config, DEFAULT_DATA_SAMPLING, AuthenticateScheme
|
|
10
11
|
from splitio.client.manager import SplitManager, SplitManagerAsync
|
|
11
|
-
from splitio.client.config import sanitize as sanitize_config, DEFAULT_DATA_SAMPLING
|
|
12
12
|
from splitio.client import util
|
|
13
13
|
from splitio.client.listener import ImpressionListenerWrapper, ImpressionListenerWrapperAsync
|
|
14
14
|
from splitio.engine.impressions.impressions import Manager as ImpressionsManager
|
|
@@ -508,12 +508,19 @@ def _build_in_memory_factory(api_key, cfg, sdk_url=None, events_url=None, # pyl
|
|
|
508
508
|
telemetry_evaluation_producer = telemetry_producer.get_telemetry_evaluation_producer()
|
|
509
509
|
telemetry_init_producer = telemetry_producer.get_telemetry_init_producer()
|
|
510
510
|
|
|
511
|
+
authentication_params = None
|
|
512
|
+
if cfg.get("httpAuthenticateScheme") in [AuthenticateScheme.KERBEROS_SPNEGO, AuthenticateScheme.KERBEROS_PROXY]:
|
|
513
|
+
authentication_params = [cfg.get("kerberosPrincipalUser"),
|
|
514
|
+
cfg.get("kerberosPrincipalPassword")]
|
|
515
|
+
|
|
511
516
|
http_client = HttpClient(
|
|
512
517
|
sdk_url=sdk_url,
|
|
513
518
|
events_url=events_url,
|
|
514
519
|
auth_url=auth_api_base_url,
|
|
515
520
|
telemetry_url=telemetry_api_base_url,
|
|
516
|
-
timeout=cfg.get('connectionTimeout')
|
|
521
|
+
timeout=cfg.get('connectionTimeout'),
|
|
522
|
+
authentication_scheme = cfg.get("httpAuthenticateScheme"),
|
|
523
|
+
authentication_params = authentication_params
|
|
517
524
|
)
|
|
518
525
|
|
|
519
526
|
sdk_metadata = util.get_metadata(cfg)
|
|
@@ -14,5 +14,17 @@ except ImportError:
|
|
|
14
14
|
asyncio = missing_asyncio_dependencies
|
|
15
15
|
aiofiles = missing_asyncio_dependencies
|
|
16
16
|
|
|
17
|
+
try:
|
|
18
|
+
from requests_kerberos import HTTPKerberosAuth, OPTIONAL
|
|
19
|
+
except ImportError:
|
|
20
|
+
def missing_auth_dependencies(*_, **__):
|
|
21
|
+
"""Fail if missing dependencies are used."""
|
|
22
|
+
raise NotImplementedError(
|
|
23
|
+
'Missing kerberos auth dependency. '
|
|
24
|
+
'Please use `pip install splitio_client[kerberos]` to install the sdk with kerberos auth support'
|
|
25
|
+
)
|
|
26
|
+
HTTPKerberosAuth = missing_auth_dependencies
|
|
27
|
+
OPTIONAL = missing_auth_dependencies
|
|
28
|
+
|
|
17
29
|
async def _anext(it):
|
|
18
30
|
return await it.__anext__()
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = '10.1.0rc2'
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: splitio-client
|
|
3
|
-
Version: 10.
|
|
3
|
+
Version: 10.1.0rc2
|
|
4
4
|
Summary: Split.io Python Client
|
|
5
5
|
Home-page: https://github.com/splitio/python-client
|
|
6
6
|
Author: Patricio Echague, Sebastian Arrubia
|
|
7
7
|
Author-email: pato@split.io, sebastian@split.io
|
|
8
8
|
License: Apache License 2.0
|
|
9
|
-
Download-URL: https://github.com/splitio/python-client/tarball/10.
|
|
9
|
+
Download-URL: https://github.com/splitio/python-client/tarball/10.1.0rc2
|
|
10
10
|
Description: # Split Python SDK
|
|
11
11
|

|
|
12
12
|
|
|
@@ -98,3 +98,4 @@ Provides-Extra: redis
|
|
|
98
98
|
Provides-Extra: uwsgi
|
|
99
99
|
Provides-Extra: cpphash
|
|
100
100
|
Provides-Extra: asyncio
|
|
101
|
+
Provides-Extra: kerberos
|
|
@@ -13,6 +13,9 @@ aiofiles>=23.1.0
|
|
|
13
13
|
[cpphash]
|
|
14
14
|
mmh3cffi==0.2.1
|
|
15
15
|
|
|
16
|
+
[kerberos]
|
|
17
|
+
requests-kerberos>=0.15.0
|
|
18
|
+
|
|
16
19
|
[redis]
|
|
17
20
|
redis>=2.10.5
|
|
18
21
|
|
|
@@ -29,6 +32,7 @@ attrs==22.1.0
|
|
|
29
32
|
pytest-asyncio==0.21.0
|
|
30
33
|
aiohttp>=3.8.4
|
|
31
34
|
aiofiles>=23.1.0
|
|
35
|
+
requests-kerberos>=0.15.0
|
|
32
36
|
|
|
33
37
|
[uwsgi]
|
|
34
38
|
uwsgi>=2.0.0
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = '10.0.1'
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{splitio_client-10.0.1 → splitio_client-10.1.0rc2}/splitio/engine/impressions/impressions.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{splitio_client-10.0.1 → splitio_client-10.1.0rc2}/splitio/engine/impressions/unique_keys_tracker.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{splitio_client-10.0.1 → splitio_client-10.1.0rc2}/splitio/models/grammar/matchers/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{splitio_client-10.0.1 → splitio_client-10.1.0rc2}/splitio/models/grammar/matchers/numeric.py
RENAMED
|
File without changes
|
{splitio_client-10.0.1 → splitio_client-10.1.0rc2}/splitio/models/grammar/matchers/semver.py
RENAMED
|
File without changes
|
|
File without changes
|
{splitio_client-10.0.1 → splitio_client-10.1.0rc2}/splitio/models/grammar/matchers/string.py
RENAMED
|
File without changes
|
{splitio_client-10.0.1 → splitio_client-10.1.0rc2}/splitio/models/grammar/matchers/utils/__init__.py
RENAMED
|
File without changes
|
{splitio_client-10.0.1 → splitio_client-10.1.0rc2}/splitio/models/grammar/matchers/utils/utils.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{splitio_client-10.0.1 → splitio_client-10.1.0rc2}/splitio_client.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|