Skip to content

Commit

Permalink
Implement Cursor
Browse files Browse the repository at this point in the history
  • Loading branch information
pitbulk committed Oct 3, 2017
1 parent 149b191 commit 9c9e4c3
Show file tree
Hide file tree
Showing 3 changed files with 133 additions and 123 deletions.
41 changes: 34 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ client = OneLoginClient(
)

#Now you can make requests
client.get_users
client.get_rate_limits()
```

For all methods see Pydoc of this SDK published at:
Expand Down Expand Up @@ -80,6 +80,33 @@ token2 = client.regenerate_token()
token3 = client.get_access_token()
```

### Paging

All OneLogin API endpoints that support paging are returned as a Cursor object to save you keeping track of the paging cursor, you can retrieve the related objects by calling objects()

eg

```python
# List the first name of all users
for user in client.get_users().objects():
print user.firstname

# List the first name of all users starting with the 2nd user
for user in client.get_users().objects()[1:]:
print user.firstname

# List the first 5 users with the name of Joe
query_parameters = {'firstname': 'Joe'}
for user in client.get_users(query_parameters, max_results=5).objects():
print user.firstname

# Get 10 event ids
ids = [user.id for user in client.get_events(max_results=10).objects()]

# Get all roles
client.get_roles().objects()
```

### Available Methods

```python
Expand All @@ -90,24 +117,24 @@ rate_limits = client.get_rate_limits()
custom_global_attributes = client.get_custom_attributes()

# Get Users with no query parameters
users = client.get_users()
users = client.get_users().objects()

# Get Users with query parameters
query_parameters = {
"email": "user@example.com"
}
users_filtered = client.get_users(query_parameters)
users_filtered = client.get_users(query_parameters).objects()

query_parameters = {
"email": "usermfa@example.com"
}
users_filtered2 = client.get_users(query_parameters)
users_filtered2 = client.get_users(query_parameters).objects()

# Get Users with limit
query_parameters = {
"limit": 3
}
users_filtered_limited = client.get_users(query_parameters)
users_filtered_limited = client.get_users(query_parameters).objects()

# Get User by id
user = client.get_user(users_filtered[0].id)
Expand All @@ -121,7 +148,7 @@ user = client.update_user(user.id, update_user_params)
user = client.get_user(user.id)

# Get Global Roles
roles = client.get_roles();
roles = client.get_roles().objects();

# Get Role
role = client.get_role(roles[0].id)
Expand Down Expand Up @@ -229,7 +256,7 @@ query_events_params = array(
events = client.get_events(query_events_params);

# Get Groups
groups = client.get_groups()
groups = client.get_groups().objects()

# Get Group
group = client.get_group(groups[0].id)
Expand Down
150 changes: 34 additions & 116 deletions src/onelogin/api/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

from onelogin.api.util.urlbuilder import UrlBuilder
from onelogin.api.util.constants import Constants
from onelogin.api.util.cursor import Cursor
from onelogin.api.models.app import App
from onelogin.api.models.event import Event
from onelogin.api.models.embed_app import EmbedApp
Expand Down Expand Up @@ -84,20 +85,6 @@ def extract_error_message_from_response(self, response):
message = status['type']
return message

def get_after_cursor(self, response):
after_cursor = None
content = response.json()
if content and 'pagination' in content and 'after_cursor' in content['pagination']:
after_cursor = content['pagination']['after_cursor']
return after_cursor

def get_before_cursor(self, response):
before_cursor = None
content = response.json()
if content and 'pagination' in content and 'before_cursor' in content['pagination']:
before_cursor = content['pagination']['before_cursor']
return before_cursor

def handle_session_token_response(self, response):
session_token = None
content = response.json()
Expand Down Expand Up @@ -346,32 +333,15 @@ def get_users(self, query_parameters=None, max_results=None):

try:
url = self.get_url(Constants.GET_USERS_URL)
model = User
headers = self.get_authorized_headers()

users = []
response = None
after_cursor = None
while (not response) or (len(users) > max_results or after_cursor):
response = requests.get(url, headers=headers, params=query_parameters)
if response.status_code == 200:
json_data = response.json()
if json_data and json_data.get('data', None):
for user_data in json_data['data']:
if len(users) < max_results:
users.append(User(user_data))
else:
return users
after_cursor = self.get_after_cursor(response)
if after_cursor:
if not query_parameters:
query_parameters = {}
query_parameters['after_cursor'] = after_cursor
else:
self.error = str(response.status_code)
self.error_description = self.extract_error_message_from_response(response)
break

return users
cursor = Cursor(url, model, headers, query_parameters, max_results)
if cursor.error:
self.error = str(cursor.response.status_code)
self.error_description = self.extract_error_message_from_response(cursor.response)
else:
return cursor
except Exception as e:
self.error = 500
self.error_description = e.args[0]
Expand Down Expand Up @@ -1043,32 +1013,15 @@ def get_roles(self, query_parameters=None, max_results=None):

try:
url = self.get_url(Constants.GET_ROLES_URL)
model = Role
headers = self.get_authorized_headers()

roles = []
response = None
after_cursor = None
while (not response) or (len(roles) > max_results or after_cursor):
response = requests.get(url, headers=headers, params=query_parameters)
if response.status_code == 200:
json_data = response.json()
if json_data and json_data.get('data', None):
for role_data in json_data['data']:
if len(roles) < max_results:
roles.append(Role(role_data))
return roles

after_cursor = self.get_after_cursor(response)
if after_cursor:
if not query_parameters:
query_parameters = {}
query_parameters['after_cursor'] = after_cursor
else:
self.error = str(response.status_code)
self.error_description = self.extract_error_message_from_response(response)
break

return roles
cursor = Cursor(url, model, headers, query_parameters, max_results)
if cursor.error:
self.error = str(cursor.response.status_code)
self.error_description = self.extract_error_message_from_response(cursor.response)
else:
return cursor
except Exception as e:
self.error = 500
self.error_description = e.args[0]
Expand Down Expand Up @@ -1170,33 +1123,15 @@ def get_events(self, query_parameters=None, max_results=None):

try:
url = self.get_url(Constants.GET_EVENTS_URL)
model = Event
headers = self.get_authorized_headers()

events = []
response = None
after_cursor = None
while (not response) or (len(events) > max_results or after_cursor):
response = requests.get(url, headers=headers, params=query_parameters)
if response.status_code == 200:
json_data = response.json()
if json_data and json_data.get('data', None):
for event_data in json_data['data']:
if len(events) < max_results:
events.append(Event(event_data))
else:
return events

after_cursor = self.get_after_cursor(response)
if after_cursor:
if not query_parameters:
query_parameters = {}
query_parameters['after_cursor'] = after_cursor
else:
self.error = str(response.status_code)
self.error_description = self.extract_error_message_from_response(response)
break

return events
cursor = Cursor(url, model, headers, query_parameters, max_results)
if cursor.error:
self.error = str(cursor.response.status_code)
self.error_description = self.extract_error_message_from_response(cursor.response)
else:
return cursor
except Exception as e:
self.error = 500
self.error_description = e.args[0]
Expand Down Expand Up @@ -1274,20 +1209,20 @@ def create_event(self, event_params):
self.error_description = e.args[0]

# Group Methods
def get_groups(self, max_results=None):
def get_groups(self, query_parameters=None, max_results=None):
"""
Gets a list of Group resources (element of groups limited with the max_results parameter, or client attribute).
Gets a list of Group resources.
:param max_results: Limit the number of groups returned (optional)
:type max_results: int
:param query_parameters: Parameters to filter the result of the list
:type query_parameters: dict
Returns the list of groups
:return: group list
:rtype: array
See https://developers.onelogin.com/api-docs/1/groups/get-groups Get Groups documentation
"""
self.clean_error()
self.prepare_token()
Expand All @@ -1297,32 +1232,15 @@ def get_groups(self, max_results=None):

try:
url = self.get_url(Constants.GET_GROUPS_URL)
model = Group
headers = self.get_authorized_headers()

query_parameters = {}
groups = []
response = None
after_cursor = None
while (not response) or (len(groups) > max_results or after_cursor):
response = requests.get(url, headers=headers, params=query_parameters)
if response.status_code == 200:
json_data = response.json()
if json_data and json_data.get('data', None):
for group_data in json_data['data']:
if len(groups) < max_results:
groups.append(Group(group_data))
else:
return groups

after_cursor = self.get_after_cursor(response)
if after_cursor:
query_parameters['after_cursor'] = after_cursor
else:
self.error = str(response.status_code)
self.error_description = self.extract_error_message_from_response(response)
break

return groups
cursor = Cursor(url, model, headers, query_parameters, max_results)
if cursor.error:
self.error = str(cursor.response.status_code)
self.error_description = self.extract_error_message_from_response(cursor.response)
else:
return cursor
except Exception as e:
self.error = 500
self.error_description = e.args[0]
Expand Down
65 changes: 65 additions & 0 deletions src/onelogin/api/util/cursor.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
#!/usr/bin/python

import requests

class Cursor(object):
def __init__(self, url, model, headers, query_parameters, max_results):
self.url = url
self.model = model
self.headers = headers
self.query_parameters = {} if query_parameters is None else query_parameters
self.max_results = max_results
self.response = None
self.collection = []
self.after_cursor = None
self.error = False

self.fetch_next_page()
while (not self.is_last()):
self.fetch_next_page()

def fetch_next_page(self):
if self.response is None or self.after_cursor is not None:
if self.after_cursor is not None:
self.query_parameters['after_cursor'] = self.after_cursor

self.response = requests.get(self.url, headers=self.headers, params=self.query_parameters)

if self.response.status_code == 200:
json_data = self.response.json()
if json_data and json_data.get('data', None):
for object_data in json_data['data']:
if len(self.collection) < self.max_results:
self.collection.append(self.model(object_data))
else:
break

self.after_cursor = self.get_after_cursor()
else:
self.after_cursor = None

def get_after_cursor(self):
after_cursor = None
if self.response is not None:
content = self.response.json()
if content and 'pagination' in content and 'after_cursor' in content['pagination']:
after_cursor = content['pagination']['after_cursor']
return after_cursor

def get_before_cursor(self, response):
before_cursor = None
content = response.json()
if content and 'pagination' in content and 'before_cursor' in content['pagination']:
before_cursor = content['pagination']['before_cursor']
return before_cursor

def objects(self):
return self.collection

def is_fetch_completed(self):
if self.max_results is None:
return False
return len(self.collection) >= self.max_results

def is_last(self):
return (self.after_cursor is None) or self.is_fetch_completed()

0 comments on commit 9c9e4c3

Please sign in to comment.