Skip to content

Commit a6b6441

Browse files
committed
Update version to 3.5.8rc2 and enhance HarnessGroupMicroClient to support an optional filterType parameter in API requests, modifying the URL template accordingly.
1 parent fe0b4b7 commit a6b6441

File tree

6 files changed

+200
-6
lines changed

6 files changed

+200
-6
lines changed

CHANGES.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ CHANGELOG
33

44
This file tracks the version history and changes made to the Split/Harness FME Python API Client library.
55

6-
3.5.8 (December 4, 2025)
6+
3.5.8 (December 5, 2025)
77
-------------------------
88
Features:
99
- Added optional org_identifier and project_identifier support for Harness microclients
@@ -12,6 +12,7 @@ Features:
1212
- When not provided, they are completely omitted from URLs rather than being passed as empty strings
1313
- Applies to all Harness microclients: harness_project, harness_user, harness_group,
1414
harness_apikey, service_account, token, role, resource_group, and role_assignment
15+
Added filterType support to the group endpoint
1516

1617
3.5.7 (November 26, 2025)
1718
-------------------------

README.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,28 @@ new_sa = client.service_account.create(sa_data, account_id)
154154
client.harness_user.add_user_to_groups(user.id, [group.id], account_id)
155155
```
156156

157+
### Harness Groups
158+
159+
The `harness_group.list()` method supports an optional `filterType` parameter to filter groups:
160+
161+
```python
162+
# List all groups (default behavior)
163+
all_groups = client.harness_group.list()
164+
165+
# List groups with filterType to exclude inherited groups
166+
groups = client.harness_group.list(filterType='EXCLUDE_INHERITED_GROUPS')
167+
168+
# List groups with filterType and other optional parameters
169+
groups = client.harness_group.list(
170+
account_identifier='YOUR_ACCOUNT_ID',
171+
org_identifier='YOUR_ORG_ID',
172+
project_identifier='YOUR_PROJECT_ID',
173+
filterType='INCLUDE_INHERITED_GROUPS'
174+
)
175+
```
176+
177+
**Note:** The `filterType` parameter is optional. When not provided (or set to `None`), it will be omitted from the API request. Valid values depend on the Harness API specification.
178+
157179

158180
For detailed examples and API specifications for each resource, please refer to the [Harness API documentation](https://apidocs.harness.io/).
159181

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.8rc1"
7+
version = "3.5.8rc2"
88
license = "Apache-2.0"
99
description = "This Python Library provides 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"
1010
classifiers = [

splitapiclient/microclients/harness/harness_group_microclient.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ class HarnessGroupMicroClient:
1414
_endpoint = {
1515
'all_items': {
1616
'method': 'GET',
17-
'url_template': '/ng/api/user-groups?accountIdentifier={accountIdentifier}&orgIdentifier={orgIdentifier}&projectIdentifier={projectIdentifier}&pageIndex={pageIndex}&pageSize=100',
17+
'url_template': '/ng/api/user-groups?accountIdentifier={accountIdentifier}&orgIdentifier={orgIdentifier}&projectIdentifier={projectIdentifier}&pageIndex={pageIndex}&pageSize=100&filterType={filterType}',
1818
'headers': [{
1919
'name': 'x-api-key',
2020
'template': '{value}',
@@ -83,13 +83,14 @@ def __init__(self, http_client, account_identifier=None, org_identifier=None, pr
8383
self._org_identifier = org_identifier
8484
self._project_identifier = project_identifier
8585

86-
def list(self, account_identifier=None, org_identifier=None, project_identifier=None):
86+
def list(self, account_identifier=None, org_identifier=None, project_identifier=None, filterType=None):
8787
'''
8888
Returns a list of HarnessGroup objects.
8989
9090
:param account_identifier: Account identifier to use for this request, overrides the default
9191
:param org_identifier: Organization identifier to use for this request, overrides the default
9292
:param project_identifier: Project identifier to use for this request, overrides the default
93+
:param filterType: Filter type to use for filtering groups
9394
:returns: list of HarnessGroup objects
9495
:rtype: list(HarnessGroup)
9596
'''
@@ -109,6 +110,8 @@ def list(self, account_identifier=None, org_identifier=None, project_identifier=
109110
endpoint['url_template'] = endpoint['url_template'].replace('&orgIdentifier={orgIdentifier}', '')
110111
if project_id is None:
111112
endpoint['url_template'] = endpoint['url_template'].replace('&projectIdentifier={projectIdentifier}', '')
113+
if filterType is None:
114+
endpoint['url_template'] = endpoint['url_template'].replace('&filterType={filterType}', '')
112115

113116
request_kwargs = {
114117
'pageIndex': page_index,
@@ -118,6 +121,8 @@ def list(self, account_identifier=None, org_identifier=None, project_identifier=
118121
request_kwargs['orgIdentifier'] = org_id
119122
if project_id is not None:
120123
request_kwargs['projectIdentifier'] = project_id
124+
if filterType is not None:
125+
request_kwargs['filterType'] = filterType
121126

122127
response = self._http_client.make_request(
123128
endpoint,

splitapiclient/tests/microclients/harness/harness_group_microclient_test.py

Lines changed: 167 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ def test_list(self, mocker):
5252
# Verify the make_request calls
5353
assert SyncHttpClient.make_request.call_count == 2
5454

55-
# Create expected endpoint with modified URL template (orgIdentifier and projectIdentifier removed)
55+
# Create expected endpoint with modified URL template (orgIdentifier, projectIdentifier, and filterType removed)
5656
expected_endpoint = HarnessGroupMicroClient._endpoint['all_items'].copy()
5757
expected_endpoint['url_template'] = '/ng/api/user-groups?accountIdentifier={accountIdentifier}&pageIndex={pageIndex}&pageSize=100'
5858

@@ -245,3 +245,169 @@ def test_delete(self, mocker):
245245

246246
# Verify the result
247247
assert result is True
248+
249+
def test_list_with_filter_type(self, mocker):
250+
'''
251+
Test listing groups with filterType parameter
252+
'''
253+
mocker.patch('splitapiclient.http_clients.sync_client.SyncHttpClient.make_request')
254+
sc = SyncHttpClient('abc', 'abc')
255+
gmc = HarnessGroupMicroClient(sc, 'test_account')
256+
257+
# Mock the API response for the first page
258+
first_page_data = {
259+
'data': {
260+
'content': [
261+
{
262+
'identifier': 'group1',
263+
'name': 'Group 1',
264+
'accountIdentifier': 'test_account',
265+
'users': []
266+
}
267+
]
268+
}
269+
}
270+
271+
# Mock the API response for the second page (empty to end pagination)
272+
second_page_data = {
273+
'data': {
274+
'content': []
275+
}
276+
}
277+
278+
# Set up the mock to return different responses for different calls
279+
SyncHttpClient.make_request.side_effect = [first_page_data, second_page_data]
280+
281+
# Call the method being tested with filterType
282+
result = gmc.list(filterType='EXCLUDE_INHERITED_GROUPS')
283+
284+
# Verify the make_request calls
285+
assert SyncHttpClient.make_request.call_count == 2
286+
287+
# Create expected endpoint with filterType included, but orgIdentifier and projectIdentifier removed
288+
expected_endpoint = HarnessGroupMicroClient._endpoint['all_items'].copy()
289+
expected_endpoint['url_template'] = '/ng/api/user-groups?accountIdentifier={accountIdentifier}&pageIndex={pageIndex}&pageSize=100&filterType={filterType}'
290+
291+
SyncHttpClient.make_request.assert_any_call(
292+
expected_endpoint,
293+
pageIndex=0,
294+
accountIdentifier='test_account',
295+
filterType='EXCLUDE_INHERITED_GROUPS'
296+
)
297+
SyncHttpClient.make_request.assert_any_call(
298+
expected_endpoint,
299+
pageIndex=1,
300+
accountIdentifier='test_account',
301+
filterType='EXCLUDE_INHERITED_GROUPS'
302+
)
303+
304+
# Verify the result
305+
assert len(result) == 1
306+
assert isinstance(result[0], HarnessGroup)
307+
assert result[0]._identifier == 'group1'
308+
309+
def test_list_with_filter_type_and_org_identifier(self, mocker):
310+
'''
311+
Test listing groups with filterType and org_identifier parameters
312+
'''
313+
mocker.patch('splitapiclient.http_clients.sync_client.SyncHttpClient.make_request')
314+
sc = SyncHttpClient('abc', 'abc')
315+
gmc = HarnessGroupMicroClient(sc, 'test_account', org_identifier='test_org')
316+
317+
# Mock the API response for the first page
318+
first_page_data = {
319+
'data': {
320+
'content': [
321+
{
322+
'identifier': 'group1',
323+
'name': 'Group 1',
324+
'accountIdentifier': 'test_account',
325+
'users': []
326+
}
327+
]
328+
}
329+
}
330+
331+
# Mock the API response for the second page (empty to end pagination)
332+
second_page_data = {
333+
'data': {
334+
'content': []
335+
}
336+
}
337+
338+
# Set up the mock to return different responses for different calls
339+
SyncHttpClient.make_request.side_effect = [first_page_data, second_page_data]
340+
341+
# Call the method being tested with filterType
342+
result = gmc.list(filterType='INCLUDE_INHERITED_GROUPS')
343+
344+
# Verify the make_request calls
345+
assert SyncHttpClient.make_request.call_count == 2
346+
347+
# Create expected endpoint with filterType and orgIdentifier included, but projectIdentifier removed
348+
expected_endpoint = HarnessGroupMicroClient._endpoint['all_items'].copy()
349+
expected_endpoint['url_template'] = '/ng/api/user-groups?accountIdentifier={accountIdentifier}&orgIdentifier={orgIdentifier}&pageIndex={pageIndex}&pageSize=100&filterType={filterType}'
350+
351+
SyncHttpClient.make_request.assert_any_call(
352+
expected_endpoint,
353+
pageIndex=0,
354+
accountIdentifier='test_account',
355+
orgIdentifier='test_org',
356+
filterType='INCLUDE_INHERITED_GROUPS'
357+
)
358+
359+
# Verify the result
360+
assert len(result) == 1
361+
assert isinstance(result[0], HarnessGroup)
362+
363+
def test_list_with_filter_type_none(self, mocker):
364+
'''
365+
Test listing groups with filterType=None (should be omitted from URL)
366+
'''
367+
mocker.patch('splitapiclient.http_clients.sync_client.SyncHttpClient.make_request')
368+
sc = SyncHttpClient('abc', 'abc')
369+
gmc = HarnessGroupMicroClient(sc, 'test_account')
370+
371+
# Mock the API response for the first page
372+
first_page_data = {
373+
'data': {
374+
'content': [
375+
{
376+
'identifier': 'group1',
377+
'name': 'Group 1',
378+
'accountIdentifier': 'test_account',
379+
'users': []
380+
}
381+
]
382+
}
383+
}
384+
385+
# Mock the API response for the second page (empty to end pagination)
386+
second_page_data = {
387+
'data': {
388+
'content': []
389+
}
390+
}
391+
392+
# Set up the mock to return different responses for different calls
393+
SyncHttpClient.make_request.side_effect = [first_page_data, second_page_data]
394+
395+
# Call the method being tested with filterType=None (explicit)
396+
result = gmc.list(filterType=None)
397+
398+
# Verify the make_request calls
399+
assert SyncHttpClient.make_request.call_count == 2
400+
401+
# Create expected endpoint with filterType removed (since it's None)
402+
expected_endpoint = HarnessGroupMicroClient._endpoint['all_items'].copy()
403+
expected_endpoint['url_template'] = '/ng/api/user-groups?accountIdentifier={accountIdentifier}&pageIndex={pageIndex}&pageSize=100'
404+
405+
SyncHttpClient.make_request.assert_any_call(
406+
expected_endpoint,
407+
pageIndex=0,
408+
accountIdentifier='test_account'
409+
)
410+
411+
# Verify the result
412+
assert len(result) == 1
413+
assert isinstance(result[0], HarnessGroup)

splitapiclient/version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = '3.5.8rc1'
1+
__version__ = '3.5.8rc2'

0 commit comments

Comments
 (0)