Skip to content

Commit

Permalink
Pagination now working, examples include pagination
Browse files Browse the repository at this point in the history
  • Loading branch information
tyler-mairose-sp committed Oct 25, 2023
1 parent f6f2ee6 commit ffbe49e
Show file tree
Hide file tree
Showing 3 changed files with 107 additions and 10 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -65,4 +65,5 @@ target/
#Ipython Notebook
.ipynb_checkpoints

config.json
config.json
api-specs/
41 changes: 32 additions & 9 deletions example.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
from sailpoint.cc.api_client import ApiClient
from sailpoint.cc.api.accounts_api import AccountsApi
from sailpoint.cc.api.connectors_api import ConnectorsApi
from sailpoint.paginator import Paginator
from sailpoint.v3.models.search import Search

configuration = Configuration()

Expand All @@ -16,6 +18,7 @@
# Create an instance of the API class
api_instance = sailpoint.v3.TransformsApi(api_client)

# List transforms
try:
# List transforms
api_response = api_instance.list_transforms()
Expand All @@ -25,14 +28,34 @@
except Exception as e:
print("Exception when calling TransformsApi->list_transforms: %s\n" % e)

# List Access Profiles
api_instance = sailpoint.v3.AccessProfilesApi(api_client)

# try:
# api_response = api_instance.list_access_profiles()
# print("The response of AccessProfilesApi->list_access_profiles:\n")
# for access_profile in api_response:
# pprint(access_profile.name)
# except Exception as e:
# print(
# "Exception when calling AccessProfilesApi->list_access_profiles: %s\n" % e
# )
try:
api_response = api_instance.list_access_profiles()
print("The response of AccessProfilesApi->list_access_profiles:\n")
for access_profile in api_response:
pprint(access_profile.name)
except Exception as e:
print(
"Exception when calling AccessProfilesApi->list_access_profiles: %s\n" % e
)

# Use the paginator with search

search = Search()
search.indices = ['identities']
search.query = { 'query': '*' }
search.sort = ['-name']

identities = Paginator.paginate_search(sailpoint.v3.SearchApi(api_client),search, 250, 1000)
for identity in identities:
print(identity['name'])



# Use the paginator to paginate 1000 accounts 100 at a time
accounts = Paginator.paginate(sailpoint.v3.AccountsApi(api_client).list_accounts, 1000, limit=100)
print(len(accounts))
for account in accounts:
print(account.name)
73 changes: 73 additions & 0 deletions sailpoint/paginator.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
from sailpoint.v3.api.search_api import SearchApi
from sailpoint.v3.models.search import Search
from typing import TypeVar

T = TypeVar('T')

class PaginationParams:
limit: int
offset: int
count: bool
filters: str
sorters: str
increment: int

def __init__(self, iterable=(), **kwargs):
self.__dict__.update(iterable, **kwargs)

class Paginator:

@staticmethod
def paginate(T, result_limit, **kwargs) -> T:

# If the total result limit is not provided, set a default of 1000 records to fetch.
result_limit = result_limit if result_limit else 1000
increment = kwargs['limit'] if hasattr(kwargs, 'limit') is not None else 250
kwargs['offset'] = kwargs['offset'] if hasattr(kwargs, 'offset') is not None else 0

modified = []
while True:
print(f'Paginating call, offset = {kwargs["offset"]}')

# Call endpoint and pass any arguments
results = T(**kwargs)

modified = modified + results

if len(results) < increment or (len(modified) >= result_limit and result_limit > 0):
# Return results, we have either received less results than the limit
# passed to the api or we've reached the limit specified by the user
return modified

kwargs['offset'] += increment

@staticmethod
def paginate_search(search_api: SearchApi, search: Search, increment: int, limit: int):
increment = increment if increment else 250
offset = 0
max_limit = limit if limit else 0

modified = []

if search.sort is None or len(search.sort) != 1:
raise Exception('search query must include exactly one sort parameter to paginate properly')

while True:
print(f'Paginating call, offset = {offset}')
results = search_api.search_post(search, None, increment)
modified = modified + results

print(f'Recieved {len(results)} results')

if len(results) < increment or (len(modified) >= max_limit and max_limit > 0):
results = modified
return results
else:
result = results[len(results) - 1]
if result[search.sort[0].strip('+-')] is not None:
next_search_after = result[str(search.sort[0]).strip('+-')]
search.search_after = [next_search_after]
else:
raise Exception('Search unexpectedly did not return a result we can search after!')

offset += increment

0 comments on commit ffbe49e

Please sign in to comment.