Skip to content

Commit 4d66ad9

Browse files
authored
Merge pull request #199 from splitio/feature/streaming
Feature/streaming
2 parents 1a8fde8 + bca16ac commit 4d66ad9

File tree

95 files changed

+7751
-1373
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

95 files changed

+7751
-1373
lines changed

splitio/api/auth.py

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
"""Auth API module."""
2+
3+
import logging
4+
import json
5+
6+
from future.utils import raise_from
7+
8+
from splitio.api import APIException, headers_from_metadata
9+
from splitio.api.client import HttpClientException
10+
from splitio.models.token import from_raw
11+
12+
13+
_LOGGER = logging.getLogger(__name__)
14+
15+
16+
class AuthAPI(object): # pylint: disable=too-few-public-methods
17+
"""Class that uses an httpClient to communicate with the SDK Auth Service API."""
18+
19+
def __init__(self, client, apikey, sdk_metadata):
20+
"""
21+
Class constructor.
22+
23+
:param client: HTTP Client responsble for issuing calls to the backend.
24+
:type client: HttpClient
25+
:param apikey: User apikey token.
26+
:type apikey: string
27+
:param sdk_metadata: SDK version & machine name & IP.
28+
:type sdk_metadata: splitio.client.util.SdkMetadata
29+
"""
30+
self._client = client
31+
self._apikey = apikey
32+
self._metadata = headers_from_metadata(sdk_metadata)
33+
34+
def authenticate(self):
35+
"""
36+
Perform authentication.
37+
38+
:return: Json representation of an authentication.
39+
:rtype: splitio.models.token.Token
40+
"""
41+
try:
42+
response = self._client.get(
43+
'auth',
44+
'/auth',
45+
self._apikey,
46+
extra_headers=self._metadata
47+
)
48+
if 200 <= response.status_code < 300:
49+
payload = json.loads(response.body)
50+
return from_raw(payload)
51+
else:
52+
raise APIException(response.body, response.status_code)
53+
except HttpClientException as exc:
54+
_LOGGER.error('Exception raised while authenticating')
55+
_LOGGER.debug('Exception information: ', exc_info=True)
56+
raise_from(APIException('Could not perform authentication.'), exc)

splitio/api/client.py

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,9 @@ class HttpClient(object):
2727

2828
SDK_URL = 'https://sdk.split.io/api'
2929
EVENTS_URL = 'https://events.split.io/api'
30+
AUTH_URL = 'https://auth.split.io/api'
3031

31-
def __init__(self, timeout=None, sdk_url=None, events_url=None):
32+
def __init__(self, timeout=None, sdk_url=None, events_url=None, auth_url=None):
3233
"""
3334
Class constructor.
3435
@@ -38,11 +39,14 @@ def __init__(self, timeout=None, sdk_url=None, events_url=None):
3839
:type sdk_url: str
3940
:param events_url: Optional alternative events URL.
4041
:type events_url: str
42+
:param auth_url: Optional alternative auth URL.
43+
:type auth_url: str
4144
"""
42-
self._timeout = timeout / 1000 if timeout else None # Convert ms to seconds.
45+
self._timeout = timeout/1000 if timeout else None # Convert ms to seconds.
4346
self._urls = {
4447
'sdk': sdk_url if sdk_url is not None else self.SDK_URL,
4548
'events': events_url if events_url is not None else self.EVENTS_URL,
49+
'auth': auth_url if auth_url is not None else self.AUTH_URL,
4650
}
4751

4852
def _build_url(self, server, path):
@@ -72,11 +76,11 @@ def _build_basic_headers(apikey):
7276
'Authorization': "Bearer %s" % apikey
7377
}
7478

75-
def get(self, server, path, apikey, query=None, extra_headers=None): #pylint: disable=too-many-arguments
79+
def get(self, server, path, apikey, query=None, extra_headers=None): # pylint: disable=too-many-arguments
7680
"""
7781
Issue a get request.
7882
79-
:param server: Whether the request is for SDK server or Events server.
83+
:param server: Whether the request is for SDK server, Events server or Auth server.
8084
:typee server: str
8185
:param path: path to append to the host url.
8286
:type path: str
@@ -91,7 +95,6 @@ def get(self, server, path, apikey, query=None, extra_headers=None): #pylint: d
9195
:rtype: HttpResponse
9296
"""
9397
headers = self._build_basic_headers(apikey)
94-
9598
if extra_headers is not None:
9699
headers.update(extra_headers)
97100

@@ -103,10 +106,10 @@ def get(self, server, path, apikey, query=None, extra_headers=None): #pylint: d
103106
timeout=self._timeout
104107
)
105108
return HttpResponse(response.status_code, response.text)
106-
except Exception as exc: #pylint: disable=broad-except
109+
except Exception as exc: # pylint: disable=broad-except
107110
raise_from(HttpClientException('requests library is throwing exceptions'), exc)
108111

109-
def post(self, server, path, apikey, body, query=None, extra_headers=None): #pylint: disable=too-many-arguments
112+
def post(self, server, path, apikey, body, query=None, extra_headers=None): # pylint: disable=too-many-arguments
110113
"""
111114
Issue a POST request.
112115
@@ -140,5 +143,5 @@ def post(self, server, path, apikey, body, query=None, extra_headers=None): #py
140143
timeout=self._timeout
141144
)
142145
return HttpResponse(response.status_code, response.text)
143-
except Exception as exc: #pylint: disable=broad-except
146+
except Exception as exc: # pylint: disable=broad-except
144147
raise_from(HttpClientException('requests library is throwing exceptions'), exc)

splitio/api/events.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@
77
from splitio.api.client import HttpClientException
88

99

10+
_LOGGER = logging.getLogger(__name__)
11+
12+
1013
class EventsAPI(object): # pylint: disable=too-few-public-methods
1114
"""Class that uses an httpClient to communicate with the events API."""
1215

@@ -21,7 +24,6 @@ def __init__(self, http_client, apikey, sdk_metadata):
2124
:param sdk_metadata: SDK version & machine name & IP.
2225
:type sdk_metadata: splitio.client.util.SdkMetadata
2326
"""
24-
self._logger = logging.getLogger(self.__class__.__name__)
2527
self._client = http_client
2628
self._apikey = apikey
2729
self._metadata = headers_from_metadata(sdk_metadata)
@@ -71,6 +73,6 @@ def flush_events(self, events):
7173
if not 200 <= response.status_code < 300:
7274
raise APIException(response.body, response.status_code)
7375
except HttpClientException as exc:
74-
self._logger.error('Http client is throwing exceptions')
75-
self._logger.debug('Error: ', exc_info=True)
76+
_LOGGER.error('Error posting events because an exception was raised by the HTTPClient')
77+
_LOGGER.debug('Error: ', exc_info=True)
7678
raise_from(APIException('Events not flushed properly.'), exc)

splitio/api/impressions.py

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@
1010
from splitio.engine.impressions import ImpressionsMode
1111

1212

13+
_LOGGER = logging.getLogger(__name__)
14+
15+
1316
class ImpressionsAPI(object): # pylint: disable=too-few-public-methods
1417
"""Class that uses an httpClient to communicate with the impressions API."""
1518

@@ -22,7 +25,6 @@ def __init__(self, client, apikey, sdk_metadata, mode=ImpressionsMode.OPTIMIZED)
2225
:param apikey: User apikey token.
2326
:type apikey: string
2427
"""
25-
self._logger = logging.getLogger(self.__class__.__name__)
2628
self._client = client
2729
self._apikey = apikey
2830
self._metadata = headers_from_metadata(sdk_metadata)
@@ -101,8 +103,10 @@ def flush_impressions(self, impressions):
101103
if not 200 <= response.status_code < 300:
102104
raise APIException(response.body, response.status_code)
103105
except HttpClientException as exc:
104-
self._logger.error('Http client is throwing exceptions')
105-
self._logger.debug('Error: ', exc_info=True)
106+
_LOGGER.error(
107+
'Error posting impressions because an exception was raised by the HTTPClient'
108+
)
109+
_LOGGER.debug('Error: ', exc_info=True)
106110
raise_from(APIException('Impressions not flushed properly.'), exc)
107111

108112
def flush_counters(self, counters):
@@ -124,6 +128,9 @@ def flush_counters(self, counters):
124128
if not 200 <= response.status_code < 300:
125129
raise APIException(response.body, response.status_code)
126130
except HttpClientException as exc:
127-
self._logger.error('Http client is throwing exceptions')
128-
self._logger.debug('Error: ', exc_info=True)
131+
_LOGGER.error(
132+
'Error posting impressions counters because an exception was raised by the '
133+
'HTTPClient'
134+
)
135+
_LOGGER.debug('Error: ', exc_info=True)
129136
raise_from(APIException('Impressions not flushed properly.'), exc)

splitio/api/segments.py

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,10 @@
99
from splitio.api.client import HttpClientException
1010

1111

12-
class SegmentsAPI(object): #pylint: disable=too-few-public-methods
12+
_LOGGER = logging.getLogger(__name__)
13+
14+
15+
class SegmentsAPI(object): # pylint: disable=too-few-public-methods
1316
"""Class that uses an httpClient to communicate with the segments API."""
1417

1518
def __init__(self, http_client, apikey):
@@ -21,7 +24,6 @@ def __init__(self, http_client, apikey):
2124
:param apikey: User apikey token.
2225
:type apikey: string
2326
"""
24-
self._logger = logging.getLogger(self.__class__.__name__)
2527
self._client = http_client
2628
self._apikey = apikey
2729

@@ -50,6 +52,9 @@ def fetch_segment(self, segment_name, change_number):
5052
else:
5153
raise APIException(response.body, response.status_code)
5254
except HttpClientException as exc:
53-
self._logger.error('Http client is throwing exceptions')
54-
self._logger.debug('Error: ', exc_info=True)
55+
_LOGGER.error(
56+
'Error fetching %s because an exception was raised by the HTTPClient',
57+
segment_name
58+
)
59+
_LOGGER.debug('Error: ', exc_info=True)
5560
raise_from(APIException('Segments not fetched properly.'), exc)

splitio/api/splits.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,10 @@
99
from splitio.api.client import HttpClientException
1010

1111

12-
class SplitsAPI(object): #pylint: disable=too-few-public-methods
12+
_LOGGER = logging.getLogger(__name__)
13+
14+
15+
class SplitsAPI(object): # pylint: disable=too-few-public-methods
1316
"""Class that uses an httpClient to communicate with the splits API."""
1417

1518
def __init__(self, client, apikey):
@@ -21,7 +24,6 @@ def __init__(self, client, apikey):
2124
:param apikey: User apikey token.
2225
:type apikey: string
2326
"""
24-
self._logger = logging.getLogger(self.__class__.__name__)
2527
self._client = client
2628
self._apikey = apikey
2729

@@ -47,6 +49,6 @@ def fetch_splits(self, change_number):
4749
else:
4850
raise APIException(response.body, response.status_code)
4951
except HttpClientException as exc:
50-
self._logger.error('Http client is throwing exceptions')
51-
self._logger.debug('Error: ', exc_info=True)
52+
_LOGGER.error('Error fetching splits because an exception was raised by the HTTPClient')
53+
_LOGGER.debug('Error: ', exc_info=True)
5254
raise_from(APIException('Splits not fetched correctly.'), exc)

splitio/api/telemetry.py

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@
88
from splitio.api.client import HttpClientException
99

1010

11+
_LOGGER = logging.getLogger(__name__)
12+
13+
1114
class TelemetryAPI(object):
1215
"""Class to handle telemetry submission to the backend."""
1316

@@ -22,10 +25,10 @@ def __init__(self, client, apikey, sdk_metadata):
2225
:param sdk_metadata: SDK Version, IP & Machine name
2326
:type sdk_metadata: splitio.client.util.SdkMetadata
2427
"""
25-
self._logger = logging.getLogger(self.__class__.__name__)
2628
self._client = client
2729
self._apikey = apikey
2830
self._metadata = headers_from_metadata(sdk_metadata)
31+
2932
@staticmethod
3033
def _build_latencies(latencies):
3134
"""
@@ -58,8 +61,10 @@ def flush_latencies(self, latencies):
5861
if not 200 <= response.status_code < 300:
5962
raise APIException(response.body, response.status_code)
6063
except HttpClientException as exc:
61-
self._logger.error('Http client is throwing exceptions')
62-
self._logger.debug('Error: ', exc_info=True)
64+
_LOGGER.error(
65+
'Error posting latencies because an exception was raised by the HTTPClient'
66+
)
67+
_LOGGER.debug('Error: ', exc_info=True)
6368
raise_from(APIException('Latencies not flushed correctly.'), exc)
6469

6570
@staticmethod
@@ -94,8 +99,10 @@ def flush_gauges(self, gauges):
9499
if not 200 <= response.status_code < 300:
95100
raise APIException(response.body, response.status_code)
96101
except HttpClientException as exc:
97-
self._logger.error('Http client is throwing exceptions')
98-
self._logger.debug('Error: ', exc_info=True)
102+
_LOGGER.error(
103+
'Error posting gauges because an exception was raised by the HTTPClient'
104+
)
105+
_LOGGER.debug('Error: ', exc_info=True)
99106
raise_from(APIException('Gauges not flushed correctly.'), exc)
100107

101108
@staticmethod
@@ -130,6 +137,8 @@ def flush_counters(self, counters):
130137
if not 200 <= response.status_code < 300:
131138
raise APIException(response.body, response.status_code)
132139
except HttpClientException as exc:
133-
self._logger.error('Http client is throwing exceptions')
134-
self._logger.debug('Error: ', exc_info=True)
140+
_LOGGER.error(
141+
'Error posting counters because an exception was raised by the HTTPClient'
142+
)
143+
_LOGGER.debug('Error: ', exc_info=True)
135144
raise_from(APIException('Counters not flushed correctly.'), exc)

0 commit comments

Comments
 (0)