- Try to retain backwards compatibility
- Leave room for multithreading implementations
- Implement
__len__()
- Handle negative indices
- Fail gracefully when unsupported
- Support lists containing multiple CanvasObject types
- For example: Listing a user's activity stream
- Support "Compound Documents"
- Provide an option to avoid element caching
class PaginatedList:
def __init__(self,
requester,
endpoint,
method="GET",
extra_attributes=None,
per_page=100,
content_class=CanvasObject,
**kwargs
):
self.requester = requester
# Identify link headers
self.pages = {
0: self.get_first_page(),
}
self.last_link = self.pages[0].links.get("last")
self.pages[current] = [] # the data
def __len__(self):
if self.last_link:
return compute_length(first, data)
raise NotImplementedError("Cast this to list() first")
def compute_length(self):
"""
1. Grab the first page results
2. If the first page == last page, just return len of the first page.
3. Grab the last page and count the items on the last page
4. Calculate the number of items in between ((last_page_number - first_page_number) * per_page)
5. Return the sum of steps 3 and 4
"""
if self.get_page_number(self.first_link) == self.last_link:
return len(self.pages[self.first_link])
data = self.get_page(self.last_link)
self.pages[self.last_link] = data
pages = self.last_link - self.first_link
items = (pages - 1) * per_page
return items + len(self.pages[self.last_link])