Skip to content

Commit 9d4ea7d

Browse files
committed
added rule based segments
1 parent 4985365 commit 9d4ea7d

13 files changed

Lines changed: 1071 additions & 51 deletions

README.md

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,111 @@ definition= {"treatments":[ {"name":"on"},{"name":"off"}],
282282
splitDef.submit_change_request(definition, 'UPDATE', 'updating default rule', 'comment', ['user@email.com'], '')
283283
```
284284

285+
### Rule-Based Segments
286+
287+
Fetch all Rule-Based Segments:
288+
289+
```python
290+
ws = client.workspaces.find("Defaults")
291+
for segment in client.rule_based_segments.list(ws.id):
292+
print("\nRule-Based Segment: " + segment.name + ", " + segment.description)
293+
```
294+
295+
Add new Rule-Based Segment:
296+
297+
```python
298+
segment_data = {
299+
'name': 'advanced_users',
300+
'description': 'Users who match advanced criteria',
301+
'tags': [{'name': 'important'}]
302+
}
303+
rule_segment = ws.add_rule_based_segment(segment_data, "user")
304+
print(rule_segment.name)
305+
```
306+
307+
Add Rule-Based Segment to environment:
308+
309+
```python
310+
ws = client.workspaces.find("Defaults")
311+
segment = client.rule_based_segments.find("advanced_users", ws.id)
312+
env = client.environments.find("Production", ws.id)
313+
segdef = segment.add_to_environment(env.id)
314+
```
315+
316+
Update Rule-Based Segment definition with rules:
317+
318+
```python
319+
ws = client.workspaces.find("Defaults")
320+
env = client.environments.find("Production", ws.id)
321+
segdef = client.rule_based_segment_definitions.find("advanced_users", env.id, ws.id)
322+
323+
# Define rules that match users with age > 30 and have completed tutorials
324+
rules_data = {
325+
'rules': [
326+
{
327+
'condition': {
328+
'combiner': 'AND',
329+
'matchers': [
330+
{
331+
'type': 'GREATER_THAN_OR_EQUAL_TO',
332+
'attribute': 'age',
333+
'number': 30
334+
},
335+
{
336+
'type': 'EQUAL_TO',
337+
'attribute': 'completed_tutorials',
338+
'bool': True
339+
}
340+
]
341+
}
342+
}
343+
]
344+
}
345+
346+
# Update the segment definition with the rules
347+
updated_segdef = segdef.update(rules_data)
348+
```
349+
350+
Submit a Change request to update a Rule-Based Segment definition:
351+
352+
```python
353+
ws = client.workspaces.find("Defaults")
354+
env = client.environments.find("Production", ws.id)
355+
segdef = client.rule_based_segment_definitions.find("advanced_users", env.id, ws.id)
356+
357+
# New rules for the change request
358+
rules = [
359+
{
360+
'condition': {
361+
'combiner': 'AND',
362+
'matchers': [
363+
{
364+
'type': 'GREATER_THAN_OR_EQUAL_NUMBER',
365+
'attribute': 'age',
366+
'number': 25
367+
},
368+
{
369+
'type': 'BOOLEAN',
370+
'attribute': 'completed_tutorials',
371+
'bool': True
372+
}
373+
]
374+
}
375+
}
376+
]
377+
378+
# Submit change request
379+
segdef.submit_change_request(
380+
rules=rules,
381+
operation_type='UPDATE',
382+
title='Lower age threshold to 25',
383+
comment='Including more users in advanced segment',
384+
approvers=['user@email.com'],
385+
rollout_status_id=None,
386+
workspace_id=ws.id
387+
)
388+
```
389+
285390
List all change requests:
286391

287392
```python

splitapiclient/microclients/rule_based_segment_definition_microclient.py

Lines changed: 11 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ class RuleBasedSegmentDefinitionMicroClient:
1111
_endpoint = {
1212
'all_items': {
1313
'method': 'GET',
14-
'url_template': 'rule-based-segments/ws/{workspaceId}/environments/{environmentId}?limit=50&offset={offset}',
14+
'url_template': 'rule-based-segments/ws/{workspaceId}/environments/{environmentId}',
1515
'headers': [{
1616
'name': 'Authorization',
1717
'template': 'Bearer {value}',
@@ -46,29 +46,17 @@ def list(self, environment_id, workspace_id):
4646
:returns: list of RuleBasedSegment in environment objects
4747
:rtype: list(RuleBasedSegmentDefinition)
4848
'''
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
49+
response = self._http_client.make_request(
50+
self._endpoint['all_items'],
51+
workspaceId = workspace_id,
52+
environmentId = environment_id
53+
)
54+
6855
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))
56+
if isinstance(response, list):
57+
for item in response:
58+
item['environment'] = {'id':environment_id, 'name':''}
59+
segment_definition_list.append(RuleBasedSegmentDefinition(item, self._http_client))
7260
return segment_definition_list
7361

7462
def find(self, segment_name, environment_id, workspace_id):

splitapiclient/microclients/rule_based_segment_microclient.py

Lines changed: 12 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -80,25 +80,18 @@ def list(self, workspace_id):
8080
:returns: list of RuleBasedSegment objects
8181
:rtype: list(RuleBasedSegment)
8282
'''
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]
83+
response = self._http_client.make_request(
84+
self._endpoint['all_items'],
85+
workspaceId = workspace_id
86+
)
87+
88+
# Check if we have the response
89+
if isinstance(response, list):
90+
objects = response
91+
if not objects: # If the list is empty, we're done
92+
return []
93+
return [RuleBasedSegment(item, self._http_client) for item in objects]
94+
return []
10295

10396
def find(self, segment_name, workspace_id):
10497
'''

splitapiclient/resources/rule_based_segment_definition.py

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,9 @@ def __init__(self, data=None, client=None):
5555
self._environment = data.get('environment')
5656
self._trafficType = TrafficType(data.get('trafficType')) if 'trafficType' in data else {}
5757
self._creationTime = data.get('creationTime') if 'creationTime' in data else 0
58+
self._excludedKeys = data.get('excludedKeys', [])
59+
self._excludedSegments = data.get('excludedSegments', [])
60+
self._rules = data.get('rules', [])
5861

5962
@property
6063
def name(self):
@@ -75,29 +78,45 @@ def tags(self):
7578
@property
7679
def creation_time(self):
7780
return None if self._creationTime==0 else self._creationTime
81+
82+
@property
83+
def excluded_keys(self):
84+
return self._excludedKeys
85+
86+
@property
87+
def excluded_segments(self):
88+
return self._excludedSegments
89+
90+
@property
91+
def rules(self):
92+
return self._rules
7893

79-
def update(self, data):
94+
def update(self, data, apiclient=None):
8095
'''
8196
Update RuleBasedSegmentDefinition object.
8297
8398
:param data: dictionary of data to update
99+
:param apiclient: If this instance wasn't returned by the client,
100+
the ApiClient instance should be passed in order to perform the
101+
http call
84102
85103
:returns: RuleBasedSegmentDefinition object
86104
:rtype: RuleBasedSegmentDefinition
87105
'''
88-
imc = require_client('RuleBasedSegmentDefinition', self._client)
106+
imc = require_client('RuleBasedSegmentDefinition', self._client, apiclient)
89107
return imc.update(self._name, self._environment['id'], self._client._workspace_id, data)
90108

91-
def submit_change_request(self, rules, operation_type, title, comment, approvers, rollout_status_id, workspace_id, apiclient=None):
109+
def submit_change_request(self, rules, excluded_keys, excluded_segments, operation_type, title, comment, approvers, workspace_id, apiclient=None):
92110
'''
93111
submit a change request for rule-based segment definition
94112
95113
:param rules: dictionary of rules to update
114+
:param excluded_keys: list of excluded keys
115+
:param excluded_segments: list of excluded segments
96116
:param operation_type: operation type
97117
:param title: title of the change request
98118
:param comment: comment for the change request
99119
:param approvers: list of approvers
100-
:param rollout_status_id: rollout status id
101120
:param workspace_id: id of the workspace
102121
:param apiclient: If this instance wasn't returned by the client,
103122
the IdentifyClient instance should be passed in order to perform the
@@ -110,13 +129,14 @@ def submit_change_request(self, rules, operation_type, title, comment, approvers
110129
'ruleBasedSegment': {
111130
'name':self._name,
112131
'rules': rules,
132+
'excludedKeys': excluded_keys,
133+
'excludedSegments': excluded_segments
113134
},
114135
'operationType': operation_type,
115136
'title': title,
116137
'comment': comment,
117138
'approvers': approvers,
118139
}
119-
if rollout_status_id is not None:
120-
data['rolloutStatus'] = {'id': rollout_status_id}
140+
121141
imc = require_client('ChangeRequest', self._client, apiclient)
122142
return imc.submit_change_request(self._environment['id'], workspace_id, data)

0 commit comments

Comments
 (0)