Skip to content

Commit 4985365

Browse files
committed
added support for rules based segments
1 parent 8162397 commit 4985365

13 files changed

Lines changed: 583 additions & 6 deletions

CHANGES.txt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,4 +40,6 @@
4040
3.2.0 (Feb 2, 2025)
4141
- Updated to support flag sets, large segments and the impressionsDisabled boolean value
4242
3.5.0 (May 6, 2025)
43-
- Updated to support harness mode
43+
- Updated to support harness mode
44+
3.5.1 (May 8, 2025)
45+
- Updated to support rule based segments

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
44

55
[project]
66
name = "splitapiclient"
7-
version = "3.5.0"
7+
version = "3.5.1"
88
description = "This Python Library provide full support for Split REST Admin API, allow creating, deleting and editing Environments, Splits, Split Definitions, Segments, Segment Keys, Users, Groups, API Keys, Change Requests, Attributes and Identities"
99
classifiers = [
1010
"Programming Language :: Python :: 3",

splitapiclient/main/apiclient.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,14 @@ def segments(self):
3535
@abc.abstractproperty
3636
def segment_definitions(self):
3737
pass
38+
39+
@abc.abstractproperty
40+
def rule_based_segments(self):
41+
pass
42+
43+
@abc.abstractproperty
44+
def rule_based_segment_definitions(self):
45+
pass
3846

3947
@abc.abstractproperty
4048
def workspaces(self):

splitapiclient/main/sync_apiclient.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
from splitapiclient.microclients import SplitDefinitionMicroClient
1010
from splitapiclient.microclients import SegmentMicroClient
1111
from splitapiclient.microclients import SegmentDefinitionMicroClient
12+
from splitapiclient.microclients import RuleBasedSegmentMicroClient
13+
from splitapiclient.microclients import RuleBasedSegmentDefinitionMicroClient
1214
from splitapiclient.microclients import WorkspaceMicroClient
1315
from splitapiclient.microclients import IdentityMicroClient
1416
from splitapiclient.microclients import AttributeMicroClient
@@ -67,6 +69,8 @@ def __init__(self, config):
6769
self._split_definition_client = SplitDefinitionMicroClient(http_client)
6870
self._segment_client = SegmentMicroClient(http_client)
6971
self._segment_definition_client = SegmentDefinitionMicroClient(http_client)
72+
self._rule_based_segment_client = RuleBasedSegmentMicroClient(http_client)
73+
self._rule_based_segment_definition_client = RuleBasedSegmentDefinitionMicroClient(http_client)
7074
self._large_segment_client = LargeSegmentMicroClient(http_client)
7175
self._large_segment_definition_client = LargeSegmentDefinitionMicroClient(http_client)
7276
self._workspace_client = WorkspaceMicroClient(http_client)
@@ -103,6 +107,14 @@ def segments(self):
103107
@property
104108
def segment_definitions(self):
105109
return self._segment_definition_client
110+
111+
@property
112+
def rule_based_segments(self):
113+
return self._rule_based_segment_client
114+
115+
@property
116+
def rule_based_segment_definitions(self):
117+
return self._rule_based_segment_definition_client
106118

107119
@property
108120
def large_segments(self):

splitapiclient/microclients/__init__.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,6 @@
1414
from splitapiclient.microclients.restriction_microclient import RestrictionMicroClient
1515
from splitapiclient.microclients.flag_set_microclient import FlagSetMicroClient
1616
from splitapiclient.microclients.large_segment_microclient import LargeSegmentMicroClient
17-
from splitapiclient.microclients.large_segment_definition_microclient import LargeSegmentDefinitionMicroClient
17+
from splitapiclient.microclients.large_segment_definition_microclient import LargeSegmentDefinitionMicroClient
18+
from splitapiclient.microclients.rule_based_segment_microclient import RuleBasedSegmentMicroClient
19+
from splitapiclient.microclients.rule_based_segment_definition_microclient import RuleBasedSegmentDefinitionMicroClient
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
from splitapiclient.resources import RuleBasedSegmentDefinition
2+
from splitapiclient.util.exceptions import HTTPResponseError, \
3+
UnknownApiClientError
4+
from splitapiclient.util.logger import LOGGER
5+
from splitapiclient.util.helpers import as_dict
6+
7+
class RuleBasedSegmentDefinitionMicroClient:
8+
'''
9+
MicroClient for rule-based segment definitions
10+
'''
11+
_endpoint = {
12+
'all_items': {
13+
'method': 'GET',
14+
'url_template': 'rule-based-segments/ws/{workspaceId}/environments/{environmentId}?limit=50&offset={offset}',
15+
'headers': [{
16+
'name': 'Authorization',
17+
'template': 'Bearer {value}',
18+
'required': True,
19+
}],
20+
'query_string': [],
21+
'response': True,
22+
},
23+
'update': {
24+
'method': 'PUT',
25+
'url_template': 'rule-based-segments/ws/{workspaceId}/{segmentName}/environments/{environmentId}',
26+
'headers': [{
27+
'name': 'Authorization',
28+
'template': 'Bearer {value}',
29+
'required': True,
30+
}],
31+
'query_string': [],
32+
'response': True,
33+
}
34+
}
35+
36+
def __init__(self, http_client):
37+
'''
38+
Constructor
39+
'''
40+
self._http_client = http_client
41+
42+
def list(self, environment_id, workspace_id):
43+
'''
44+
Returns a list of RuleBasedSegment in environment objects.
45+
46+
:returns: list of RuleBasedSegment in environment objects
47+
:rtype: list(RuleBasedSegmentDefinition)
48+
'''
49+
offset_val = 0
50+
final_list = []
51+
while True:
52+
response = self._http_client.make_request(
53+
self._endpoint['all_items'],
54+
workspaceId = workspace_id,
55+
environmentId = environment_id,
56+
offset = offset_val
57+
)
58+
for item in response:
59+
final_list.append(as_dict(item))
60+
offset = int(response['offset'])
61+
totalCount = int(response['totalCount'])
62+
limit = int(response['limit'])
63+
if totalCount>(offset+limit):
64+
offset_val = offset_val + limit
65+
continue
66+
else:
67+
break
68+
segment_definition_list = []
69+
for item in final_list:
70+
item['environment'] = {'id':environment_id, 'name':''}
71+
segment_definition_list.append(RuleBasedSegmentDefinition(item, self._http_client))
72+
return segment_definition_list
73+
74+
def find(self, segment_name, environment_id, workspace_id):
75+
'''
76+
Find RuleBasedSegment in environment list objects.
77+
78+
:returns: RuleBasedSegmentDefinition object
79+
:rtype: RuleBasedSegmentDefinition
80+
'''
81+
for item in self.list(environment_id, workspace_id):
82+
if item.name == segment_name:
83+
return item
84+
LOGGER.error("RuleBasedSegment Definition Name does not exist")
85+
return None
86+
87+
def update(self, segment_name, environment_id, workspace_id, data):
88+
'''
89+
Update RuleBasedSegmentDefinition object.
90+
91+
:param segment_name: name of the rule-based segment
92+
:param environment_id: id of the environment
93+
:param workspace_id: id of the workspace
94+
:param data: dictionary of data to update
95+
96+
:returns: RuleBasedSegmentDefinition object
97+
:rtype: RuleBasedSegmentDefinition
98+
'''
99+
response = self._http_client.make_request(
100+
self._endpoint['update'],
101+
body=as_dict(data),
102+
workspaceId = workspace_id,
103+
environmentId = environment_id,
104+
segmentName = segment_name
105+
)
106+
return RuleBasedSegmentDefinition(as_dict(response), self._http_client)
107+
108+
Lines changed: 183 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
from splitapiclient.resources import RuleBasedSegment
2+
from splitapiclient.resources import RuleBasedSegmentDefinition
3+
from splitapiclient.util.exceptions import HTTPResponseError, \
4+
UnknownApiClientError
5+
from splitapiclient.util.logger import LOGGER
6+
from splitapiclient.util.helpers import as_dict
7+
8+
class RuleBasedSegmentMicroClient:
9+
'''
10+
MicroClient for rule-based segments
11+
'''
12+
_endpoint = {
13+
'create': {
14+
'method': 'POST',
15+
'url_template': ('rule-based-segments/ws/{workspaceId}/trafficTypes/{trafficTypeName}'),
16+
'headers': [{
17+
'name': 'Authorization',
18+
'template': 'Bearer {value}',
19+
'required': True,
20+
}],
21+
'query_string': [],
22+
'response': True,
23+
},
24+
'add_to_environment': {
25+
'method': 'POST',
26+
'url_template': ('rule-based-segments/{environmentId}/{segmentName}'),
27+
'headers': [{
28+
'name': 'Authorization',
29+
'template': 'Bearer {value}',
30+
'required': True,
31+
}],
32+
'query_string': [],
33+
'response': True,
34+
},
35+
'remove_from_environment': {
36+
'method': 'DELETE',
37+
'url_template': ('rule-based-segments/{environmentId}/{segmentName}'),
38+
'headers': [{
39+
'name': 'Authorization',
40+
'template': 'Bearer {value}',
41+
'required': True,
42+
}],
43+
'query_string': [],
44+
'response': True,
45+
},
46+
'delete': {
47+
'method': 'DELETE',
48+
'url_template': ('rule-based-segments/ws/{workspaceId}/{segmentName}'),
49+
'headers': [{
50+
'name': 'Authorization',
51+
'template': 'Bearer {value}',
52+
'required': True,
53+
}],
54+
'query_string': [],
55+
'response': True,
56+
},
57+
'all_items': {
58+
'method': 'GET',
59+
'url_template': 'rule-based-segments/ws/{workspaceId}?limit=50&offset={offset}',
60+
'headers': [{
61+
'name': 'Authorization',
62+
'template': 'Bearer {value}',
63+
'required': True,
64+
}],
65+
'query_string': [],
66+
'response': True,
67+
},
68+
}
69+
70+
def __init__(self, http_client):
71+
'''
72+
Constructor
73+
'''
74+
self._http_client = http_client
75+
76+
def list(self, workspace_id):
77+
'''
78+
Returns a list of RuleBasedSegment objects.
79+
80+
:returns: list of RuleBasedSegment objects
81+
:rtype: list(RuleBasedSegment)
82+
'''
83+
offset_val = 0
84+
final_list = []
85+
while True:
86+
response = self._http_client.make_request(
87+
self._endpoint['all_items'],
88+
workspaceId = workspace_id,
89+
offset = offset_val
90+
)
91+
for item in response:
92+
final_list.append(as_dict(item))
93+
offset = int(response['offset'])
94+
totalCount = int(response['totalCount'])
95+
limit = int(response['limit'])
96+
if totalCount>(offset+limit):
97+
offset_val = offset_val + limit
98+
continue
99+
else:
100+
break
101+
return [RuleBasedSegment(item, self._http_client) for item in final_list]
102+
103+
def find(self, segment_name, workspace_id):
104+
'''
105+
Find RuleBasedSegment in environment list objects.
106+
107+
:returns: RuleBasedSegment objects
108+
:rtype: RuleBasedSegment
109+
'''
110+
for item in self.list(workspace_id):
111+
if item.name == segment_name:
112+
return item
113+
LOGGER.error("RuleBasedSegment Name does not exist")
114+
return None
115+
116+
def add(self, segment, traffic_type_name, workspace_id):
117+
'''
118+
add a rule-based segment
119+
120+
:param segment: rule-based segment instance or dict
121+
122+
:returns: newly created rule-based segment
123+
:rtype: RuleBasedSegment
124+
'''
125+
data = as_dict(segment)
126+
response = self._http_client.make_request(
127+
self._endpoint['create'],
128+
body=data,
129+
workspaceId = workspace_id,
130+
trafficTypeName = traffic_type_name
131+
)
132+
response['workspaceId'] = workspace_id
133+
return RuleBasedSegment(response, self._http_client)
134+
135+
def delete(self, segment_name, workspace_id):
136+
'''
137+
delete a rule-based segment
138+
139+
:param segment: rule-based segment instance or dict
140+
141+
:returns:
142+
:rtype: RuleBasedSegment
143+
'''
144+
response = self._http_client.make_request(
145+
self._endpoint['delete'],
146+
workspaceId = workspace_id,
147+
segmentName = segment_name
148+
)
149+
return response
150+
151+
def add_to_environment(self, segment_name, environment_id):
152+
'''
153+
add a rule-based segment to environment
154+
155+
:param segment: rule-based segment name, environment id
156+
157+
:returns: newly created rule-based segment definition object
158+
:rtype: RuleBasedSegmentDefinition
159+
'''
160+
response = self._http_client.make_request(
161+
self._endpoint['add_to_environment'],
162+
body="",
163+
segmentName = segment_name,
164+
environmentId = environment_id
165+
)
166+
return RuleBasedSegmentDefinition(response, self._http_client)
167+
168+
def remove_from_environment(self, segment_name, environment_id):
169+
'''
170+
remove a rule-based segment from environment
171+
172+
:param segment: rule-based segment name, environment id
173+
174+
:returns: http response
175+
:rtype: boolean
176+
'''
177+
response = self._http_client.make_request(
178+
self._endpoint['remove_from_environment'],
179+
body="",
180+
segmentName = segment_name,
181+
environmentId = environment_id
182+
)
183+
return response

splitapiclient/resources/__init__.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,6 @@
1515
from splitapiclient.resources.restriction import Restriction
1616
from splitapiclient.resources.flag_set import FlagSet
1717
from splitapiclient.resources.large_segment import LargeSegment
18-
from splitapiclient.resources.large_segment_definition import LargeSegmentDefinition
18+
from splitapiclient.resources.large_segment_definition import LargeSegmentDefinition
19+
from splitapiclient.resources.rule_based_segment import RuleBasedSegment
20+
from splitapiclient.resources.rule_based_segment_definition import RuleBasedSegmentDefinition

0 commit comments

Comments
 (0)