Skip to content

Commit 6f189e1

Browse files
committed
added flag sets and the impressionsDisabled flag
1 parent 701fa51 commit 6f189e1

File tree

16 files changed

+451
-19
lines changed

16 files changed

+451
-19
lines changed

CHANGES.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,3 +37,5 @@
3737
- Added ability to retrieve API keys when creating an environment
3838
3.1.13 (Jan 31, 2024)
3939
- Updated keyId of an API KEY to be the actual ID and not the key itself
40+
3.2.0 (Jan 31, 2025)
41+
- Updated to support flag sets and the impressionsDisabled boolean value

pyproject.toml

Lines changed: 5 additions & 5 deletions
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.1.13"
7+
version = "3.2.0"
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",
@@ -16,13 +16,13 @@ classifiers = [
1616
"Topic :: Software Development :: Libraries",
1717
]
1818
authors = [
19-
{name = "Patricio Echague", email = "pato@split.io"},
19+
{name = "Patricio Echague", email = "patricio.echague@harness.io"},
2020
{name = "Sebastian Arrubia", email = "[email protected]"},
21-
{name = "Martin Redolatti", email = "martin@split.io"},
22-
{name = "Bilal Al-Shawany", email = "bilal@split.io"},
21+
{name = "Martin Redolatti", email = "martin.redolatti@harness.io"},
22+
{name = "Bilal Al-Shawany", email = "bilal.al-shahwany@harness.io"},
2323
]
2424
maintainers = [
25-
{name = "Josh Klein", email = "joshua.klein@split.io"}
25+
{name = "Josh Klein", email = "joshua.klein@harness.io"}
2626
]
2727
dependencies = [
2828
'argparse >= 1.1',

splitapiclient/http_clients/sync_client.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ def make_request(self, endpoint, body=None, **kwargs):
109109
else:
110110
break
111111

112-
if not (response.status_code == 200 or response.status_code == 204):
112+
if not (response.status_code == 200 or response.status_code == 204 or response.status_code == 201):
113113
LOGGER.warning('RESPONSE CODE: %s' % response.status_code)
114114
self._handle_invalid_response(response)
115115

splitapiclient/main/sync_apiclient.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,13 @@
1717
from splitapiclient.microclients import GroupMicroClient
1818
from splitapiclient.microclients import APIKeyMicroClient
1919
from splitapiclient.microclients import RestrictionMicroClient
20-
20+
from splitapiclient.microclients import FlagSetMicroClient
2121

2222
class SyncApiClient(BaseApiClient):
2323
'''
2424
Synchronous Split API client
2525
'''
26-
26+
BASE_PROD_URL_V3 = 'https://api.split.io/api/v3'
2727
BASE_PROD_URL = 'https://api.split.io/internal/api/v2'
2828
BASE_PROD_URL_OLD = 'https://api.split.io/internal/api/v1'
2929

@@ -41,6 +41,7 @@ def __init__(self, config):
4141
else:
4242
self._base_url = self.BASE_PROD_URL
4343
self._base_url_old = self.BASE_PROD_URL_OLD
44+
self._base_url_v3 = self.BASE_PROD_URL_V3
4445

4546
missing = [i for i in ['apikey'] if i not in config]
4647
if missing:
@@ -52,6 +53,8 @@ def __init__(self, config):
5253
self._apikey = config['apikey']
5354

5455
http_client = SyncHttpClient(self._base_url, self._apikey)
56+
http_clientv3 = SyncHttpClient(self._base_url_v3, self._apikey)
57+
5558
self._environment_client = EnvironmentMicroClient(http_client)
5659
self._split_client = SplitMicroClient(http_client)
5760
self._split_definition_client = SplitDefinitionMicroClient(http_client)
@@ -66,6 +69,7 @@ def __init__(self, config):
6669
self._group_client = GroupMicroClient(http_client)
6770
self._apikey_client = APIKeyMicroClient(http_client)
6871
self._restriction_client = RestrictionMicroClient(http_client)
72+
self._flag_set_client = FlagSetMicroClient(http_clientv3)
6973

7074
@property
7175
def traffic_types(self):
@@ -122,3 +126,7 @@ def apikeys(self):
122126
@property
123127
def restrictions(self):
124128
return self._restriction_client
129+
130+
@property
131+
def flag_sets(self):
132+
return self._flag_set_client

splitapiclient/microclients/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,4 @@
1212
from splitapiclient.microclients.group_microclient import GroupMicroClient
1313
from splitapiclient.microclients.apikey_microclient import APIKeyMicroClient
1414
from splitapiclient.microclients.restriction_microclient import RestrictionMicroClient
15+
from splitapiclient.microclients.flag_set_microclient import FlagSetMicroClient
Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
from splitapiclient.resources.flag_set import FlagSet
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+
8+
class FlagSetMicroClient:
9+
'''
10+
'''
11+
_endpoint = {
12+
'list_initial': {
13+
'method': 'GET',
14+
'url_template': 'flag-sets?workspace_id={workspace_id}&limit=50',
15+
'headers': [{
16+
'name': 'Authorization',
17+
'template': 'Bearer {value}',
18+
'required': True,
19+
}],
20+
'query_string': [],
21+
'response': True,
22+
},
23+
'list_next': {
24+
'method': 'GET',
25+
'url_template': 'flag-sets?workspace_id={workspace_id}&after={after}&limit=50',
26+
'headers': [{
27+
'name': 'Authorization',
28+
'template': 'Bearer {value}',
29+
'required': True,
30+
}],
31+
'query_string': [],
32+
'response': True,
33+
},
34+
'get': {
35+
'method': 'GET',
36+
'url_template': 'flag-sets/{flag_set_id}',
37+
'headers': [{
38+
'name': 'Authorization',
39+
'template': 'Bearer {value}',
40+
'required': True,
41+
}],
42+
'query_string': [],
43+
'response': True,
44+
},
45+
'create': {
46+
'method': 'POST',
47+
'url_template': 'flag-sets',
48+
'headers': [{
49+
'name': 'Authorization',
50+
'template': 'Bearer {value}',
51+
'required': True,
52+
}],
53+
'query_string': [],
54+
'response': True,
55+
},
56+
'delete': {
57+
'method': 'DELETE',
58+
'url_template': ('flag-sets/{flagSetId}'),
59+
'headers': [{
60+
'name': 'Authorization',
61+
'template': 'Bearer {value}',
62+
'required': True,
63+
}],
64+
'query_string': [],
65+
'response': True,
66+
},
67+
}
68+
69+
def __init__(self, http_client):
70+
'''
71+
Constructor
72+
'''
73+
self._http_client = http_client
74+
75+
def list(self, workspace_id):
76+
'''
77+
Returns a list of flag_sets objects.
78+
79+
:returns: list of flag_sets objects
80+
:rtype: list(flag_sets)
81+
'''
82+
final_list = []
83+
afterMarker = 0
84+
while True:
85+
if afterMarker==0:
86+
response = self._http_client.make_request(
87+
self._endpoint['list_initial'],
88+
workspace_id = workspace_id
89+
)
90+
else:
91+
response = self._http_client.make_request(
92+
self._endpoint['list_next'],
93+
workspace_id = workspace_id,
94+
after = afterMarker
95+
)
96+
for item in response['data']:
97+
final_list.append(as_dict(item))
98+
if response['nextMarker'] is None:
99+
break
100+
else:
101+
afterMarker = response['nextMarker']
102+
continue
103+
return [FlagSet(item, workspace_id, self._http_client) for item in final_list]
104+
105+
def find(self, flag_set_name=None, workspace_id=None):
106+
'''
107+
Search for flag_set in list of flag_sets objects.
108+
109+
:returns: flag_set object
110+
:rtype: flag_set
111+
'''
112+
113+
for item in self.list(workspace_id=workspace_id):
114+
if item.name==flag_set_name:
115+
return item
116+
LOGGER.error("flag_set Name does not exist")
117+
return None
118+
119+
def get(self, flag_set_id=None):
120+
'''
121+
get a flag_set
122+
123+
:param flag_set_id: flag_set id
124+
:returns: flag_set
125+
:rtype: flag_set
126+
'''
127+
128+
response = self._http_client.make_request(
129+
self._endpoint['get'],
130+
flag_set_id=flag_set_id
131+
)
132+
return FlagSet(data=response, client=self._http_client)
133+
134+
135+
136+
137+
def add(self, flag_set, workspace_id):
138+
'''
139+
add a flag_set
140+
141+
:param flag_set: flag_set instance
142+
:returns: newly created flag_set
143+
:rtype: flag_set
144+
'''
145+
data = as_dict(flag_set)
146+
data['workspace'] = {
147+
'id': workspace_id,
148+
'type': 'WORKSPACE'
149+
}
150+
response = self._http_client.make_request(
151+
self._endpoint['create'],
152+
body=data
153+
)
154+
return FlagSet(response, workspace_id, self._http_client)
155+
156+
157+
158+
def delete(self, flag_set_id ):
159+
'''
160+
delete a flag_set
161+
162+
:param flag_set id:
163+
164+
:returns:
165+
:rtype: True if successful
166+
'''
167+
response = self._http_client.make_request(
168+
self._endpoint['delete'],
169+
flagSetId =flag_set_id,
170+
)
171+
return response

splitapiclient/resources/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,4 @@
1313
from splitapiclient.resources.group import Group
1414
from splitapiclient.resources.apikey import APIKey
1515
from splitapiclient.resources.restriction import Restriction
16+
from splitapiclient.resources.flag_set import FlagSet
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
from __future__ import absolute_import, division, print_function, \
2+
unicode_literals
3+
from splitapiclient.resources.base_resource import BaseResource
4+
from splitapiclient.util.helpers import require_client, as_dict
5+
6+
7+
class FlagSet(BaseResource):
8+
'''
9+
'''
10+
_schema = {
11+
"id" : "string",
12+
"name": "string",
13+
"description": "string",
14+
"workspace": {
15+
"id": "string",
16+
"type": "string"
17+
},
18+
"createdAt": "string",
19+
"type": "string"
20+
}
21+
22+
def __init__(self, data=None, workspace_id=None, client=None):
23+
'''
24+
'''
25+
if not data:
26+
data = {}
27+
BaseResource.__init__(self, data.get('id'), client)
28+
self._id = data.get('id')
29+
self._name = data.get('name')
30+
self._description = data.get('desription')
31+
self._workspace_id = workspace_id or (data.get('workspace') and data.get('workspace').get('id'))
32+
self._createdAt = data.get('createdAt')
33+
self._client = client
34+
35+
@property
36+
def description(self):
37+
return self._description
38+
39+
@property
40+
def workspace_id(self):
41+
return self._workspace_id
42+
43+
@property
44+
def createdAt(self):
45+
return self._createdAt
46+
47+
@property
48+
def name(self):
49+
return self._name
50+
51+
@property
52+
def id(self):
53+
return self._id
54+
55+
56+
def list(self, workspaceId=None, apiclient=None):
57+
'''
58+
list flag sets in a workspace
59+
'''
60+
imc = require_client('FlagSet', self._client, apiclient)
61+
workspaceId = self._workspace_id or workspaceId
62+
return imc.list(workspaceId)
63+
64+
65+
def find(self, flagSetName, workspaceId=None, apiclient=None):
66+
'''
67+
get a flag set by id
68+
'''
69+
imc = require_client('FlagSet', self._client, apiclient)
70+
71+
return imc.find(flagSetName, workspaceId)
72+
73+
74+
75+
def get(self, flagSetId, apiclient=None):
76+
'''
77+
get a flag set by id
78+
'''
79+
imc = require_client('FlagSet', self._client, apiclient)
80+
flag_set_id = self._id or flagSetId
81+
82+
return imc.get(flag_set_id)
83+
84+
85+
86+
def add(self, apiclient=None):
87+
'''
88+
add a flag set
89+
'''
90+
imc = require_client('FlagSet', self._client, apiclient)
91+
flagsetId = self._id
92+
workspaceId = self._workspace_id
93+
return imc.add(flagsetId, workspaceId)
94+
95+
def delete(self, flagSetId=None, apiclient=None):
96+
'''
97+
delete current flagSet instance
98+
'''
99+
imc = require_client('FlagSet', self._client, apiclient)
100+
flagsetId = flagSetId or self._id
101+
return imc.delete(flagsetId)

0 commit comments

Comments
 (0)