This repository was archived by the owner on May 5, 2022. It is now read-only.
forked from launchdarkly/python-server-sdk
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathutil.py
More file actions
144 lines (112 loc) · 4.17 KB
/
Copy pathutil.py
File metadata and controls
144 lines (112 loc) · 4.17 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
from __future__ import division, with_statement, absolute_import
import hashlib
import logging
import sys
from ldclient.version import VERSION
log = logging.getLogger(sys.modules[__name__].__name__)
# noinspection PyBroadException
try:
import queue
except:
# noinspection PyUnresolvedReferences,PyPep8Naming
import Queue as queue
__LONG_SCALE__ = float(0xFFFFFFFFFFFFFFF)
__BUILTINS__ = ["key", "ip", "country", "email",
"firstName", "lastName", "avatar", "name", "anonymous"]
try:
# noinspection PyUnresolvedReferences
unicode
except NameError:
__BASE_TYPES__ = (str, float, int, bool)
else:
# noinspection PyUnresolvedReferences
__BASE_TYPES__ = (str, float, int, bool, unicode)
def _headers(api_key):
return {'Authorization': 'api_key ' + api_key, 'User-Agent': 'PythonClient/' + VERSION,
'Content-Type': "application/json"}
def _stream_headers(api_key, client="PythonClient"):
return {'Authorization': 'api_key ' + api_key,
'User-Agent': '{}/{}'.format(client, VERSION),
'Cache-Control': 'no-cache',
'Accept': "text/event-stream"}
def _param_for_user(feature, user):
if 'key' in user and user['key']:
id_hash = user['key']
else:
log.exception(
'User does not have a valid key set. Returning default value for flag.')
return None
if 'secondary' in user:
id_hash += "." + user['secondary']
hash_key = '%s.%s.%s' % (feature['key'], feature['salt'], id_hash)
hash_val = int(hashlib.sha1(hash_key.encode('utf-8')).hexdigest()[:15], 16)
result = hash_val / __LONG_SCALE__
return result
def _match_target(target, user):
attr = target['attribute']
if attr in __BUILTINS__:
if attr in user:
u_value = user[attr]
return u_value in target['values']
else:
return False
else: # custom attribute
if 'custom' not in user:
return False
if attr not in user['custom']:
return False
u_value = user['custom'][attr]
if isinstance(u_value, __BASE_TYPES__):
return u_value in target['values']
elif isinstance(u_value, (list, tuple)):
return len(set(u_value).intersection(target['values'])) > 0
return False
def _match_user(variation, user):
if 'userTarget' in variation:
return _match_target(variation['userTarget'], user)
return False
def _match_variation(variation, user):
for target in variation['targets']:
if 'userTarget' in variation and target['attribute'] == 'key':
continue
if _match_target(target, user):
return True
return False
def check_uwsgi():
if 'uwsgi' in sys.modules:
# noinspection PyPackageRequirements,PyUnresolvedReferences
import uwsgi
if not uwsgi.opt.get('enable-threads'):
log.warning('The LaunchDarkly client requires the enable-threads option '
'be passed to uWSGI. If enable-threads is not provided, no '
'threads will run and event data will not be sent to LaunchDarkly. '
'To learn more, see '
'http://docs.launchdarkly.com/v1.0/docs/python-sdk-reference#configuring-uwsgi')
def _evaluate(feature, user):
if feature is None:
return None
if not feature['on']:
return None
param = _param_for_user(feature, user)
if param is None:
return None
for variation in feature['variations']:
if _match_user(variation, user):
return variation['value']
for variation in feature['variations']:
if _match_variation(variation, user):
return variation['value']
total = 0.0
for variation in feature['variations']:
total += float(variation['weight']) / 100.0
if param < total:
return variation['value']
return None
class Event(object):
def __init__(self, data='', event='message', event_id=None, retry=None):
self.data = data
self.event = event
self.id = event_id
self.retry = retry
def __str__(self, *args, **kwargs):
return self.data