Skip to content

Add statistics from response headers for query_multiple #75

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Oct 28, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 20 additions & 21 deletions tests/test_queries.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ def test_query_multiple_user_success():
conn = Connection(**mock_connection_params)
assert conn.query_multiple("user") == ([{"name": "n1", "type": "user"},
{"name": "n2", "type": "user"}],
False)
False, 0, 0, 1, 0)


def test_query_multiple_user_empty():
Expand All @@ -97,7 +97,7 @@ def test_query_multiple_user_empty():
"lastPage": True,
"users": []})
conn = Connection(**mock_connection_params)
assert conn.query_multiple("user") == ([], True)
assert conn.query_multiple("user") == ([], True, 0, 0, 1, 0)


def test_query_multiple_user_not_found():
Expand All @@ -120,10 +120,10 @@ def test_query_multiple_user_paged():
conn = Connection(**mock_connection_params)
assert conn.query_multiple("user", 0) == ([{"name": "n1", "type": "user"},
{"name": "n2", "type": "user"}],
False)
False, 0, 0, 1, 0)
assert conn.query_multiple("user", 1) == ([{"name": "n3", "type": "user"},
{"name": "n4", "type": "user"}],
True)
True, 0, 0, 1, 0)


def test_qm_user_iterate_complete():
Expand Down Expand Up @@ -199,7 +199,6 @@ def test_qm_user_reload():
{"name": "n7", "type": "user"},
{"name": "n8", "type": "user"}]


def test_query_multiple_usergroup_success():
with mock.patch("umapi_client.connection.requests.Session.get") as mock_get:
mock_get.return_value = MockResponse(200,
Expand All @@ -208,11 +207,11 @@ def test_query_multiple_usergroup_success():
{"X-Total-Count": "4",
"X-Page-Count": "2",
"X-Current-Page": "1",
"X-Page-Size:": "2"})
"X-Page-Size": "2"})
conn = Connection(**mock_connection_params)
assert conn.query_multiple("user-group") == ([{"name": "n1", "type": "user-group"},
{"name": "n2", "type": "user-group"}],
False)
False, 4, 2, 1, 2)


def test_query_multiple_usergroup_empty():
Expand All @@ -222,9 +221,9 @@ def test_query_multiple_usergroup_empty():
{"X-Total-Count": "0",
"X-Page-Count": "1",
"X-Current-Page": "1",
"X-Page-Size:": "0"})
"X-Page-Size": "0"})
conn = Connection(**mock_connection_params)
assert conn.query_multiple("user-group") == ([], True)
assert conn.query_multiple("user-group") == ([], True, 0, 1, 1, 0)


def test_query_multiple_usergroup_not_found():
Expand All @@ -242,21 +241,21 @@ def test_query_multiple_usergroup_paged():
{"X-Total-Count": "4",
"X-Page-Count": "2",
"X-Current-Page": "1",
"X-Page-Size:": "2"}),
"X-Page-Size": "2"}),
MockResponse(200,
[{"name": "n3", "type": "user-group"},
{"name": "n4", "type": "user-group"}],
{"X-Total-Count": "4",
"X-Page-Count": "2",
"X-Current-Page": "2",
"X-Page-Size:": "2"})]
"X-Page-Size": "2"})]
conn = Connection(**mock_connection_params)
assert conn.query_multiple("user-group", 0) == ([{"name": "n1", "type": "user-group"},
{"name": "n2", "type": "user-group"}],
False)
False, 4, 2, 1, 2)
assert conn.query_multiple("user-group", 1) == ([{"name": "n3", "type": "user-group"},
{"name": "n4", "type": "user-group"}],
True)
True, 4, 2, 2, 2)


def test_qm_usergroup_iterate_complete():
Expand All @@ -267,14 +266,14 @@ def test_qm_usergroup_iterate_complete():
{"X-Total-Count": "4",
"X-Page-Count": "2",
"X-Current-Page": "1",
"X-Page-Size:": "2"}),
"X-Page-Size": "2"}),
MockResponse(200,
[{"name": "n3", "type": "user-group"},
{"name": "n4", "type": "user-group"}],
{"X-Total-Count": "4",
"X-Page-Count": "2",
"X-Current-Page": "2",
"X-Page-Size:": "2"})]
"X-Page-Size": "2"})]
conn = Connection(**mock_connection_params)
qm = QueryMultiple(conn, "user-group")
for obj in qm:
Expand All @@ -294,14 +293,14 @@ def test_qm_usergroup_iterate_partial():
{"X-Total-Count": "6",
"X-Page-Count": "3",
"X-Current-Page": "1",
"X-Page-Size:": "2"}),
"X-Page-Size": "2"}),
MockResponse(200,
[{"name": "n1", "type": "user-group"},
{"name": "n2", "type": "user-group"}],
{"X-Total-Count": "6",
"X-Page-Count": "3",
"X-Current-Page": "2",
"X-Page-Size:": "2"}),
"X-Page-Size": "2"}),
MockResponse(400, text="400 bad request")]
conn = Connection(**mock_connection_params)
qm = QueryMultiple(conn, "user-group")
Expand All @@ -322,28 +321,28 @@ def test_qm_usergroup_reload():
{"X-Total-Count": "4",
"X-Page-Count": "2",
"X-Current-Page": "1",
"X-Page-Size:": "2"}),
"X-Page-Size": "2"}),
MockResponse(200,
[{"name": "n3", "type": "user-group"},
{"name": "n4", "type": "user-group"}],
{"X-Total-Count": "4",
"X-Page-Count": "2",
"X-Current-Page": "2",
"X-Page-Size:": "2"}),
"X-Page-Size": "2"}),
MockResponse(200,
[{"name": "n5", "type": "user-group"},
{"name": "n6", "type": "user-group"}],
{"X-Total-Count": "4",
"X-Page-Count": "2",
"X-Current-Page": "1",
"X-Page-Size:": "2"}),
"X-Page-Size": "2"}),
MockResponse(200,
[{"name": "n7", "type": "user-group"},
{"name": "n8", "type": "user-group"}],
{"X-Total-Count": "4",
"X-Page-Count": "2",
"X-Current-Page": "2",
"X-Page-Size:": "2"})]
"X-Page-Size": "2"})]
conn = Connection(**mock_connection_params)
qm = QueryMultiple(conn, "user-group")
assert list(qm) == [{"name": "n1", "type": "user-group"},
Expand Down
15 changes: 13 additions & 2 deletions umapi_client/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,10 @@ def __init__(self, connection, object_type, url_params=None, query_params=None):
self._results = []
self._next_item_index = 0
self._next_page_index = 0
self._total_count = 0
self._page_size = 1
self._page_count = 0
self._page_number = 1
self._last_page_seen = False

def reload(self):
Expand All @@ -193,6 +197,10 @@ def reload(self):
self._results = []
self._next_item_index = 0
self._next_page_index = 0
self._total_count = 0
self._page_count = 0
self._page_size = 0
self._page_number = 1
self._last_page_seen = False

def _next_page(self):
Expand All @@ -201,8 +209,8 @@ def _next_page(self):
"""
if self._last_page_seen:
raise StopIteration
new, self._last_page_seen = self.conn.query_multiple(self.object_type, self._next_page_index,
self.url_params, self.query_params)
new, self._last_page_seen, self._total_count, self._page_count, self._page_number, self._page_size = \
self.conn.query_multiple(self.object_type, self._next_page_index, self.url_params, self.query_params)
self._next_page_index += 1
if len(new) == 0:
self._last_page_seen = True # don't bother with next page if nothing was returned
Expand Down Expand Up @@ -250,6 +258,9 @@ def all_results(self):
self._next_item_index = len(self._results)
return list(self._results)

def stats(self):
return self._total_count, self._page_count, self._page_size, self._page_number


class QuerySingle:
"""
Expand Down
15 changes: 11 additions & 4 deletions umapi_client/connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -273,21 +273,28 @@ def query_multiple(self, object_type, page=0, url_params=None, query_params=None
return [], True
else:
raise re

headers = {k.lower(): v for k, v in result.headers.items()}
total_count = headers.get("x-total-count", "0")
page_count = headers.get("x-page-count", "0")
page_number = headers.get("x-current-page", "1")
page_size = headers.get("x-page-size", "0")

if object_type in ("user", "group"):
if body.get("result") == "success":
values = body.get(object_type + "s", [])
last_page = body.get("lastPage", False)

if self.logger: self.logger.debug("Ran multi-%s query: %s %s (page %d: %d found)",
object_type, url_params, query_params, page, len(values))
return values, last_page
return values, last_page, int(total_count), int(page_count), int(page_number), int(page_size)
else:
raise ClientError("OK status but no 'success' result", result)
elif object_type == "user-group":
page_number = result.headers.get("X-Current-Page", "1")
page_count = result.headers.get("X-Page-Count", "1")
if self.logger: self.logger.debug("Ran multi-group query: %s %s (page %d: %d found)",
url_params, query_params, page, len(body))
return body, int(page_number) >= int(page_count)
return body, int(page_number) >= int(page_count), int(total_count), int(page_count), \
int(page_number), int(page_size)
else:
# this would actually be caught above, but we use a parallel construction in both places
# to make it easy to add query object types
Expand Down