Skip to content

Commit 1523f9c

Browse files
committed
updated readme
1 parent bed7907 commit 1523f9c

File tree

1 file changed

+398
-0
lines changed

1 file changed

+398
-0
lines changed

README.md

Lines changed: 398 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,398 @@
1+
# Split Python API
2+
3+
This API wrapper is designed to work with [Split](https://www.split.io), the platform for controlled rollouts, serving features to your users via the Split feature flag to manage your complete customer experience.
4+
5+
For specific instructions on how to use Split Admin REST API refer to our [official API documentation](https://docs.split.io/reference).
6+
7+
Full documentation on this Python wrapper is available in [this link](https://help.split.io/hc/en-us/articles/4412331052685-Python-PyPi-library-for-Split-REST-Admin-API).
8+
9+
## Using in Harness Mode
10+
11+
Starting with version 3.5.0, the Split API client supports operating in "harness mode" to interact with both Split and Harness Feature Flags APIs. This is required for usage in environments that have been migrated to Harness and want to use the new features. Existing API keys will continue to work with the non-deprecated endpoints after migration, but new Harness Tokens will be required for Harness mode.
12+
13+
For detailed information about Harness API endpoints, please refer to the [official Harness API documentation](https://apidocs.harness.io/).
14+
15+
### Authentication in Harness Mode
16+
17+
The client supports multiple authentication scenarios:
18+
19+
1. Harness-specific endpoints always use the 'x-api-key' header format
20+
2. Split endpoints will use the 'x-api-key' header when using the harness_token
21+
3. Split endpoints will use the normal 'Authorization' header when using the apikey
22+
4. If both harness_token and apikey are provided, the client will use the harness_token for Harness endpoints and the apikey for Split endpoints
23+
24+
### Base URLs and Endpoints
25+
26+
- Existing, non-deprecated Split endpoints continue to use the Split base URLs
27+
- New Harness-specific endpoints use the Harness base URL (https://app.harness.io/)
28+
29+
### Deprecated Endpoints
30+
31+
The following Split endpoints are deprecated and cannot be used in harness mode:
32+
- `/workspaces`: POST, PATCH, DELETE, PUT verbs are deprecated
33+
- `/apiKeys`: POST verb for apiKeyType == 'admin' is deprecated
34+
- `/users`: all verbs are deprecated
35+
- `/groups`: all verbs are deprecated
36+
- `/restrictions`: all verbs are deprecated
37+
38+
Non-deprecated endpoints will continue to function as they did before the migration.
39+
40+
### Basic Usage
41+
42+
To use the client in harness mode:
43+
44+
```python
45+
from splitapiclient.main import get_client
46+
47+
# Option 1: Use harness_token for Harness endpoints and apikey for Split endpoints
48+
client = get_client({
49+
'harness_mode': True,
50+
'harness_token': 'YOUR_HARNESS_TOKEN', # Used for Harness-specific endpoints
51+
'apikey': 'YOUR_SPLIT_API_KEY', # Used for existing Split endpoints
52+
'account_identifier': 'YOUR_HARNESS_ACCOUNT_ID' # Required for Harness operations
53+
})
54+
55+
# Option 2: Use harness_token for all operations (if apikey is not provided)
56+
client = get_client({
57+
'harness_mode': True,
58+
'harness_token': 'YOUR_HARNESS_TOKEN', # Used for both Harness and Split endpoints
59+
'account_identifier': 'YOUR_HARNESS_ACCOUNT_ID'
60+
})
61+
```
62+
63+
### Working with Split Resources in Harness Mode
64+
65+
You can still access standard Split resources with some restrictions:
66+
67+
```python
68+
# List workspaces (read-only in harness mode)
69+
for ws in client.workspaces.list():
70+
print(f"Workspace: {ws.name}, Id: {ws.id}")
71+
72+
# Find a specific workspace
73+
ws = client.workspaces.find("Default")
74+
75+
# List environments in a workspace
76+
for env in client.environments.list(ws.id):
77+
print(f"Environment: {env.name}, Id: {env.id}")
78+
```
79+
80+
### Working with Harness-specific Resources
81+
82+
Harness mode provides access to several Harness-specific resources through dedicated microclients:
83+
84+
- token
85+
- harness_apikey
86+
- service_account
87+
- harness_user
88+
- harness_group
89+
- role
90+
- resource_group
91+
- role_assignment
92+
- harness_project
93+
94+
Basic example:
95+
96+
```python
97+
# Account identifier is required for all Harness operations
98+
account_id = 'YOUR_ACCOUNT_IDENTIFIER'
99+
100+
# List all tokens
101+
tokens = client.token.list(account_id)
102+
for token in tokens:
103+
print(f"Token: {token.name}, ID: {token.id}")
104+
105+
# List service accounts
106+
service_accounts = client.service_account.list(account_id)
107+
for sa in service_accounts:
108+
print(f"Service Account: {sa.name}, ID: {sa.id}")
109+
```
110+
111+
For most creation, update, and delete endpoints for harness specific resources, you will need to pass through the JSON body directly.
112+
113+
Example:
114+
```python
115+
# Create a new service account
116+
sa_data = {
117+
'name': sa_name,
118+
'identifier': sa_identifier,
119+
'email': "[email protected]",
120+
'accountIdentifier': account_id,
121+
'description': 'Service account for test',
122+
'tags': {'test': 'test tag'}
123+
}
124+
125+
new_sa = client.service_account.create(sa_data, account_id)
126+
```
127+
128+
```python
129+
# Add a user to a group
130+
client.harness_user.add_user_to_groups(user.id, [group.id], account_id)
131+
```
132+
133+
134+
For detailed examples and API specifications for each resource, please refer to the [Harness API documentation](https://apidocs.harness.io/).
135+
136+
### Setting Default Account Identifier
137+
138+
To avoid specifying the account identifier with every request:
139+
140+
```python
141+
# Set default account identifier when creating the client
142+
client = get_client({
143+
'harness_mode': True,
144+
'harness_token': 'YOUR_HARNESS_TOKEN',
145+
'account_identifier': 'YOUR_ACCOUNT_IDENTIFIER'
146+
})
147+
148+
# Now you can make calls without specifying account_identifier in each request
149+
tokens = client.token.list() # account_identifier is automatically included
150+
projects = client.harness_project.list() # account_identifier is automatically included
151+
```
152+
153+
## Quick Setup
154+
155+
Install the splitapiclient:
156+
```
157+
pip install splitapiclient
158+
```
159+
160+
Import the client object and initialize connection using an Admin API Key:
161+
162+
```python
163+
from splitapiclient.main import get_client
164+
client = get_client({'apikey': 'ADMIN API KEY'})
165+
```
166+
167+
Enable optional logging:
168+
169+
```python
170+
import logging
171+
logging.basicConfig(level=logging.DEBUG)
172+
```
173+
174+
## Standard Split API Usage
175+
176+
### Workspaces
177+
178+
Fetch all workspaces:
179+
180+
```python
181+
for ws in client.workspaces.list():
182+
print("\nWorkspace:" + ws.name + ", Id: " + ws.id)
183+
```
184+
185+
Find a specific workspace:
186+
187+
```python
188+
ws = client.workspaces.find("Defaults")
189+
print("\nWorkspace:" + ws.name + ", Id: " + ws.id)
190+
```
191+
192+
### Environments
193+
194+
Fetch all Environments:
195+
196+
```python
197+
ws = client.workspaces.find("Defaults")
198+
for env in client.environments.list(ws.id):
199+
print("\nEnvironment: " + env.name + ", Id: " + env.id)
200+
```
201+
202+
Add new environment:
203+
204+
```python
205+
ws = client.workspaces.find("Defaults")
206+
env = ws.add_environment({'name': 'new_environment', 'production': False})
207+
```
208+
209+
### Splits
210+
Fetch all Splits:
211+
212+
```python
213+
ws = client.workspaces.find("Defaults")
214+
for split in client.splits.list(ws.id):
215+
print("\nSplit: " + split.name + ", " + split._workspace_id)
216+
```
217+
218+
Add new Split:
219+
220+
```python
221+
split = ws.add_split({'name': 'split_name', 'description': 'new UI feature'}, "user")
222+
print(split.name)
223+
```
224+
225+
Add tags:
226+
227+
```python
228+
split.associate_tags(['my_new_tag', 'another_new_tag'])
229+
```
230+
231+
Add Split to environment:
232+
233+
```python
234+
ws = client.workspaces.find("Defaults")
235+
split = client.splits.find("new_feature", ws.id)
236+
env = client.environments.find("Production", ws.id)
237+
tr1 = treatment.Treatment({"name":"on","configurations":""})
238+
tr2 = treatment.Treatment({"name":"off","configurations":""})
239+
bk1 = bucket.Bucket({"treatment":"on","size":50})
240+
bk2 = bucket.Bucket({"treatment":"off","size":50})
241+
match = matcher.Matcher({"attribute":"group","type":"IN_LIST_STRING","strings":["employees"]})
242+
cond = condition.Condition({'matchers':[match.export_dict()]})
243+
rl = rule.Rule({'condition':cond.export_dict(), 'buckets':[bk1.export_dict(), bk2.export_dict()]})
244+
defrl = default_rule.DefaultRule({"treatment":"off","size":100})
245+
data={"treatments":[tr1.export_dict() ,tr2.export_dict()],"defaultTreatment":"off", "baselineTreatment": "off","rules":[rl.export_dict()],"defaultRule":[defrl.export_dict()], "comment": "adding split to production"}
246+
splitdef = split.add_to_environment(env.id, data)
247+
```
248+
249+
Kill Split:
250+
251+
```python
252+
ws = client.workspaces.find("Defaults")
253+
env = client.environments.find("Production", ws.id)
254+
splitDef = client.split_definitions.find("new_feature", env.id, ws.id)
255+
splitDef.kill()
256+
```
257+
258+
Restore Split:
259+
260+
```python
261+
splitDef.restore()
262+
```
263+
264+
Fetch all Splits in an Environment:
265+
266+
```python
267+
ws = client.workspaces.find("Defaults")
268+
env = client.environments.find("Production", ws.id)
269+
for spDef in client.split_definitions.list(env.id, ws.id):
270+
print(spDef.name + str(spDef._default_rule))
271+
```
272+
273+
Submit a Change request to update a Split definition:
274+
275+
```python
276+
splitDef = client.split_definitions.find("new_feature", env.id, ws.id)
277+
definition= {"treatments":[ {"name":"on"},{"name":"off"}],
278+
"defaultTreatment":"off", "baselineTreatment": "off",
279+
"rules": [],
280+
"defaultRule":[{"treatment":"off","size":100}],"comment": "updating default rule"
281+
}
282+
splitDef.submit_change_request(definition, 'UPDATE', 'updating default rule', 'comment', ['[email protected]'], '')
283+
```
284+
285+
List all change requests:
286+
287+
```python
288+
for cr in client.change_requests.list():
289+
if cr._split is not None:
290+
print(cr._id + ", " + cr._split['name'] + ", " + cr._title + ", " + str(cr._split['environment']['id']))
291+
if cr._segment is not None:
292+
print(cr._id + ", " + cr._segment['name'] + ", " + cr._title)
293+
```
294+
295+
Approve specific change request:
296+
297+
```python
298+
for cr in client.change_requests.list():
299+
if cr._split['name'] == 'new_feature':
300+
cr.update_status("APPROVED", "done")
301+
```
302+
303+
### Users and Groups
304+
305+
Fetch all Active users:
306+
307+
```python
308+
for user in client.users.list('ACTIVE'):
309+
print(user.email + ", " + user._id)
310+
```
311+
312+
Invite new user:
313+
314+
```python
315+
group = client.groups.find('Administrators')
316+
userData = {'email': '[email protected]', 'groups': [{'id': '', 'type': 'group'}]}
317+
userData['groups'][0]['id'] = group._id
318+
client.users.invite_user(userData)
319+
```
320+
321+
Delete a pending invite:
322+
323+
```python
324+
for user in client.users.list('PENDING'):
325+
print(user.email + ", " + user._id + ", " + user._status)
326+
if user.email == '[email protected]':
327+
client.users.delete(user._id)
328+
```
329+
330+
Update user info:
331+
332+
```python
333+
data = {'name': 'new_name', 'email': '[email protected]', '2fa': False, 'status': 'ACTIVE'}
334+
user = client.users.find('[email protected]')
335+
user.update_user(user._id, data)
336+
```
337+
338+
Fetch all Groups:
339+
340+
```python
341+
for group in client.groups.list():
342+
print(group._id + ", " + group._name)
343+
```
344+
345+
Create Group:
346+
347+
```python
348+
client.groups.create_group({'name': 'new_group', 'description': ''})
349+
```
350+
351+
Delete Group:
352+
353+
```python
354+
group = client.groups.find('new_group')
355+
client.groups.delete_group(group._id)
356+
```
357+
358+
Replace existing user group:
359+
360+
```python
361+
user = client.users.find('[email protected]')
362+
group = client.groups.find('Administrators')
363+
data = [{'op': 'replace', 'path': '/groups/0', 'value': {'id': '<groupId>', 'type': 'group'}}]
364+
data[0]['value']['id'] = group._id
365+
user.update_user_group(data)
366+
```
367+
368+
Add user to new group
369+
370+
```python
371+
user = client.users.find('[email protected]')
372+
group = client.groups.find('Administrators')
373+
data = [{'op': 'add', 'path': '/groups/-', 'value': {'id': '<groupId>', 'type': 'group'}}]
374+
data[0]['value']['id'] = group._id
375+
user.update_user_group(data)
376+
```
377+
378+
## About Split
379+
380+
### Commitment to Quality:
381+
382+
Split's APIs are in active development and are constantly tested for quality. Unit tests are developed for each wrapper based on the unique needs of that language, and integration tests, load and performance tests, and behavior consistency tests are running 24/7 via automated bots. In addition, monitoring instrumentation ensures that these wrappers behave under the expected parameters of memory, CPU, and I/O.
383+
384+
### About Split:
385+
386+
Split is the leading platform for intelligent software delivery, helping businesses of all sizes deliver exceptional user experiences, and mitigate risk, by providing an easy, secure way to target features to customers. Companies like WePay, LendingTree and thredUP rely on Split to safely launch and test new features and derive insights on their use. Founded in 2015, Split's team comes from some of the most innovative enterprises in Silicon Valley, including Google, LinkedIn, Salesforce and Splunk. Split is based in Redwood City, California and backed by Accel Partners and Lightspeed Venture Partners. To learn more about Split, contact [email protected], or start a 14-day free trial at www.split.io/trial.
387+
388+
**Try Split for Free:**
389+
390+
Split is available as a 14-day free trial. To create an account, visit [split.io/trial](https://www.split.io/trial).
391+
392+
**Learn more about Split:**
393+
394+
Visit [split.io/product](https://www.split.io/product) for an overview of Split, or visit our documentation at [docs.split.io](http://docs.split.io) for more detailed information.
395+
396+
**System Status:**
397+
398+
We use a status page to monitor the availability of Split's various services. You can check the current status at [status.split.io](http://status.split.io).

0 commit comments

Comments
 (0)