diff --git a/README.md b/README.md index 48555ded..6bee92f3 100644 --- a/README.md +++ b/README.md @@ -123,7 +123,7 @@ Let’s look at how we can use the `PaginatedList` returned by our `get_courses( # Access the first element in our list. # # You'll notice the first call takes a moment, but the next N-1 -# elements (where N = the per_page argument supplied; the default is 10) +# elements (where N = the per_page argument supplied; the default in canvasapi is 100) # will be instantly accessible. >>> print(courses[0]) TST101 Test Course (1234567) diff --git a/canvasapi/account.py b/canvasapi/account.py index a1c39c12..b184fbbc 100644 --- a/canvasapi/account.py +++ b/canvasapi/account.py @@ -1168,7 +1168,7 @@ def get_grading_periods(self, **kwargs): "accounts/{}/grading_periods".format(self.id), {"account_id": self.id}, _root="grading_periods", - kwargs=combine_kwargs(**kwargs), + _kwargs=combine_kwargs(**kwargs), ) def get_grading_standards(self, **kwargs): diff --git a/canvasapi/blueprint.py b/canvasapi/blueprint.py index 8e3ff055..161c20c2 100644 --- a/canvasapi/blueprint.py +++ b/canvasapi/blueprint.py @@ -103,7 +103,7 @@ def get_unsynced_changes(self, **kwargs): "courses/{}/blueprint_templates/{}/unsynced_changes".format( self.course_id, self.id ), - kwargs=combine_kwargs(**kwargs), + _kwargs=combine_kwargs(**kwargs), ) def list_blueprint_migrations(self, **kwargs): @@ -126,7 +126,7 @@ def list_blueprint_migrations(self, **kwargs): self.course_id, self.id ), {"course_id": self.course_id}, - kwargs=combine_kwargs(**kwargs), + _kwargs=combine_kwargs(**kwargs), ) def show_blueprint_migration(self, migration, **kwargs): @@ -201,7 +201,7 @@ def get_details(self, **kwargs): "courses/{}/blueprint_templates/{}/migrations/{}/details".format( self.course_id, self.template_id, self.id ), - kwargs=combine_kwargs(**kwargs), + _kwargs=combine_kwargs(**kwargs), ) def get_import_details(self, **kwargs): @@ -224,7 +224,7 @@ def get_import_details(self, **kwargs): "courses/{}/blueprint_subscriptions/{}/migrations/{}/details".format( self.course_id, self.subscription_id, self.id ), - kwargs=combine_kwargs(**kwargs), + _kwargs=combine_kwargs(**kwargs), ) @@ -258,7 +258,7 @@ def list_blueprint_imports(self, **kwargs): self.course_id, self.id ), {"course_id": self.id}, - kwargs=combine_kwargs(**kwargs), + _kwargs=combine_kwargs(**kwargs), ) def show_blueprint_import(self, migration, **kwargs): diff --git a/canvasapi/canvas.py b/canvasapi/canvas.py index bc6501af..bc25d0d8 100644 --- a/canvasapi/canvas.py +++ b/canvasapi/canvas.py @@ -820,7 +820,7 @@ def get_epub_exports(self, **kwargs): "GET", "epub_exports", _root="courses", - kwargs=combine_kwargs(**kwargs), + _kwargs=combine_kwargs(**kwargs), ) def get_file(self, file, **kwargs): diff --git a/canvasapi/collaboration.py b/canvasapi/collaboration.py index e5cc6089..53b1ffd1 100644 --- a/canvasapi/collaboration.py +++ b/canvasapi/collaboration.py @@ -22,7 +22,7 @@ def get_collaborators(self, **kwargs): "GET", "collaborations/{}/members".format(self.id), _root="collaborators", - kwargs=combine_kwargs(**kwargs), + _kwargs=combine_kwargs(**kwargs), ) diff --git a/canvasapi/course.py b/canvasapi/course.py index 2b28f810..011b8ce5 100644 --- a/canvasapi/course.py +++ b/canvasapi/course.py @@ -978,7 +978,7 @@ def get_collaborations(self, **kwargs): "GET", "courses/{}/collaborations".format(self.id), _root="collaborations", - kwargs=combine_kwargs(**kwargs), + _kwargs=combine_kwargs(**kwargs), ) def get_content_export(self, content_export, **kwargs): @@ -1018,7 +1018,7 @@ def get_content_exports(self, **kwargs): self._requester, "GET", "courses/{}/content_exports".format(self.id), - kwargs=combine_kwargs(**kwargs), + _kwargs=combine_kwargs(**kwargs), ) def get_content_migration(self, content_migration, **kwargs): @@ -1535,7 +1535,7 @@ def get_gradebook_history_details(self, date, **kwargs): self._requester, "GET", "courses/{}/gradebook_history/{}".format(self.id, date), - kwargs=combine_kwargs(**kwargs), + _kwargs=combine_kwargs(**kwargs), ) def get_grading_period(self, grading_period, **kwargs): @@ -1579,7 +1579,7 @@ def get_grading_periods(self, **kwargs): "courses/{}/grading_periods".format(self.id), {"course_id": self.id}, _root="grading_periods", - kwargs=combine_kwargs(**kwargs), + _kwargs=combine_kwargs(**kwargs), ) def get_grading_standards(self, **kwargs): @@ -1719,7 +1719,7 @@ def get_lti_resource_links(self, **kwargs): self._requester, "GET", f"courses/{self.id}/lti_resource_links", - kwargs=combine_kwargs(**kwargs), + _kwargs=combine_kwargs(**kwargs), ) def get_migration_systems(self, **kwargs): @@ -2279,7 +2279,7 @@ def get_submission_history(self, date, grader_id, assignment_id, **kwargs): "courses/{}/gradebook_history/{}/graders/{}/assignments/{}/submissions".format( self.id, date, grader_id, assignment_id ), - kwargs=combine_kwargs(**kwargs), + _kwargs=combine_kwargs(**kwargs), ) def get_tabs(self, **kwargs): @@ -2341,7 +2341,7 @@ def get_uncollated_submissions(self, **kwargs): self._requester, "GET", "courses/{}/gradebook_history/feed".format(self.id), - kwargs=combine_kwargs(**kwargs), + _kwargs=combine_kwargs(**kwargs), ) def get_user(self, user, user_id_type=None, **kwargs): @@ -2511,7 +2511,7 @@ def list_blueprint_subscriptions(self, **kwargs): "GET", "courses/{}/blueprint_subscriptions".format(self.id), {"course_id": self.id}, - kwargs=combine_kwargs(**kwargs), + _kwargs=combine_kwargs(**kwargs), ) def preview_html(self, html, **kwargs): diff --git a/canvasapi/group.py b/canvasapi/group.py index b9aaad41..ce1d8adb 100644 --- a/canvasapi/group.py +++ b/canvasapi/group.py @@ -309,7 +309,7 @@ def get_collaborations(self, **kwargs): "GET", "groups/{}/collaborations".format(self.id), _root="collaborations", - kwargs=combine_kwargs(**kwargs), + _kwargs=combine_kwargs(**kwargs), ) def get_content_export(self, content_export, **kwargs): @@ -353,7 +353,7 @@ def get_content_exports(self, **kwargs): self._requester, "GET", "groups/{}/content_exports".format(self.id), - kwargs=combine_kwargs(**kwargs), + _kwargs=combine_kwargs(**kwargs), ) def get_content_migration(self, content_migration, **kwargs): diff --git a/canvasapi/paginated_list.py b/canvasapi/paginated_list.py index 96b91529..acbfee95 100644 --- a/canvasapi/paginated_list.py +++ b/canvasapi/paginated_list.py @@ -31,6 +31,7 @@ def __init__( extra_attribs=None, _root=None, _url_override=None, + _kwargs=None, **kwargs, ): """ @@ -50,14 +51,24 @@ def __init__( Other URLs may be specified for third-party requests. :type _url_override: str :rtype: :class:`canvasapi.paginated_list.PaginatedList` of type content_class + :param _kwargs: A list of 2-tuples representing processed + keyword arguments to be sent to Canvas as params or data. + :type _kwargs: list[tuple[str, Any]] """ self._elements = list() self._requester = requester self._content_class = content_class self._first_url = first_url - self._first_params = kwargs or {} - self._first_params["per_page"] = kwargs.get("per_page", 100) + _kwargs = _kwargs or [] + for key, value in _kwargs: + if key == "per_page": + break + else: + # change kwargs such that if per_page is given as a keyword argument, + # we don't override it. + kwargs.setdefault("per_page", 100) + self._first_params = {"_kwargs": _kwargs, **kwargs} self._next_url = first_url self._next_params = self._first_params self._extra_attribs = extra_attribs or {} diff --git a/canvasapi/user.py b/canvasapi/user.py index 6f9adabf..7264b6ff 100644 --- a/canvasapi/user.py +++ b/canvasapi/user.py @@ -371,7 +371,7 @@ def get_content_exports(self, **kwargs): self._requester, "GET", "users/{}/content_exports".format(self.id), - kwargs=combine_kwargs(**kwargs), + _kwargs=combine_kwargs(**kwargs), ) def get_content_migration(self, content_migration, **kwargs): diff --git a/docs/getting-started.rst b/docs/getting-started.rst index 78514ab1..d2c7c1ae 100644 --- a/docs/getting-started.rst +++ b/docs/getting-started.rst @@ -90,7 +90,7 @@ Let’s look at how we can use the :code:`PaginatedList` returned by our :code:` # Access the first element in our list. # # You'll notice the first call takes a moment, but the next N-1 - # elements (where N = the per_page argument supplied; the default is 10) + # elements (where N = the per_page argument supplied; the default in canvasapi is 100) # will be instantly accessible. >>> print(courses[0]) TST101 Test Course (1234567) diff --git a/tests/fixtures/paginated_list.json b/tests/fixtures/paginated_list.json index db7a3d47..a1176b29 100644 --- a/tests/fixtures/paginated_list.json +++ b/tests/fixtures/paginated_list.json @@ -33,7 +33,7 @@ }, "4_2_pages_p1": { "method": "ANY", - "endpoint": "four_objects_two_pages", + "endpoint": "four_objects_two_pages?per_page=2", "data": [ { "id": "1", @@ -66,7 +66,7 @@ }, "6_3_pages_p1": { "method": "ANY", - "endpoint": "six_objects_three_pages", + "endpoint": "six_objects_three_pages?per_page=2", "data": [ { "id": "1", @@ -117,7 +117,7 @@ }, "no_header_4_2_pages_p1": { "method": "ANY", - "endpoint": "no_header_four_objects_two_pages", + "endpoint": "no_header_four_objects_two_pages?per_page=2", "data": { "assessments": [ { @@ -131,7 +131,7 @@ ], "meta": { "pagination": { - "next": "https://example.com/api/v1/no_header_four_objects_two_pages?page=2" + "next": "https://example.com/api/v1/no_header_four_objects_two_pages?page=2&per_page=2" } } }, @@ -139,7 +139,7 @@ }, "no_header_4_2_pages_p2": { "method": "ANY", - "endpoint": "no_header_four_objects_two_pages?page=2", + "endpoint": "no_header_four_objects_two_pages?page=2&per_page=2", "data": { "assessments": [ { diff --git a/tests/test_paginated_list.py b/tests/test_paginated_list.py index 9783e314..47d74052 100644 --- a/tests/test_paginated_list.py +++ b/tests/test_paginated_list.py @@ -6,6 +6,7 @@ from canvasapi.enrollment_term import EnrollmentTerm from canvasapi.paginated_list import PaginatedList from canvasapi.user import User +from canvasapi.util import combine_kwargs from tests import settings from tests.util import register_uris @@ -43,7 +44,13 @@ def test_paginated_list_two_one_page(self, m): def test_paginated_list_four_two_pages(self, m): register_uris({"paginated_list": ["4_2_pages_p1", "4_2_pages_p2"]}, m) - pag_list = PaginatedList(User, self.requester, "GET", "four_objects_two_pages") + pag_list = PaginatedList( + User, + self.requester, + "GET", + "four_objects_two_pages", + per_page=2, + ) item_list = [item for item in pag_list] self.assertEqual(len(item_list), 4) self.assertIsInstance(item_list[0], User) @@ -52,7 +59,13 @@ def test_paginated_list_six_three_pages(self, m): requires = {"paginated_list": ["6_3_pages_p1", "6_3_pages_p2", "6_3_pages_p3"]} register_uris(requires, m) - pag_list = PaginatedList(User, self.requester, "GET", "six_objects_three_pages") + pag_list = PaginatedList( + User, + self.requester, + "GET", + "six_objects_three_pages", + _kwargs=combine_kwargs(per_page=2), + ) item_list = [item for item in pag_list] self.assertEqual(len(item_list), 6) self.assertIsInstance(item_list[0], User) @@ -62,7 +75,13 @@ def test_iterator(self, m): requires = {"paginated_list": ["6_3_pages_p1", "6_3_pages_p2", "6_3_pages_p3"]} register_uris(requires, m) - pag_list = PaginatedList(User, self.requester, "GET", "six_objects_three_pages") + pag_list = PaginatedList( + User, + self.requester, + "GET", + "six_objects_three_pages", + _kwargs=combine_kwargs(per_page=2), + ) list_1 = [item for item in pag_list] list_2 = [item for item in pag_list] self.assertEqual(list_1, list_2) @@ -72,7 +91,13 @@ def test_getitem_first(self, m): requires = {"paginated_list": ["6_3_pages_p1", "6_3_pages_p2", "6_3_pages_p3"]} register_uris(requires, m) - pag_list = PaginatedList(User, self.requester, "GET", "six_objects_three_pages") + pag_list = PaginatedList( + User, + self.requester, + "GET", + "six_objects_three_pages", + _kwargs=combine_kwargs(per_page=2), + ) first_item = pag_list[0] self.assertIsInstance(first_item, User) @@ -80,7 +105,13 @@ def test_getitem_second_page(self, m): requires = {"paginated_list": ["6_3_pages_p1", "6_3_pages_p2", "6_3_pages_p3"]} register_uris(requires, m) - pag_list = PaginatedList(User, self.requester, "GET", "six_objects_three_pages") + pag_list = PaginatedList( + User, + self.requester, + "GET", + "six_objects_three_pages", + _kwargs=combine_kwargs(per_page=2), + ) third_item = pag_list[2] self.assertIsInstance(third_item, User) @@ -89,7 +120,13 @@ def test_slice_beginning(self, m): requires = {"paginated_list": ["6_3_pages_p1", "6_3_pages_p2", "6_3_pages_p3"]} register_uris(requires, m) - pag_list = PaginatedList(User, self.requester, "GET", "six_objects_three_pages") + pag_list = PaginatedList( + User, + self.requester, + "GET", + "six_objects_three_pages", + _kwargs=combine_kwargs(per_page=2), + ) first_two_items = pag_list[:2] item_list = [item for item in first_two_items] self.assertEqual(len(item_list), 2) @@ -101,7 +138,13 @@ def test_slice_middle(self, m): requires = {"paginated_list": ["6_3_pages_p1", "6_3_pages_p2", "6_3_pages_p3"]} register_uris(requires, m) - pag_list = PaginatedList(User, self.requester, "GET", "six_objects_three_pages") + pag_list = PaginatedList( + User, + self.requester, + "GET", + "six_objects_three_pages", + _kwargs=combine_kwargs(per_page=2), + ) middle_two_items = pag_list[2:4] item_list = [item for item in middle_two_items] self.assertEqual(len(item_list), 2) @@ -113,7 +156,13 @@ def test_slice_end(self, m): requires = {"paginated_list": ["6_3_pages_p1", "6_3_pages_p2", "6_3_pages_p3"]} register_uris(requires, m) - pag_list = PaginatedList(User, self.requester, "GET", "six_objects_three_pages") + pag_list = PaginatedList( + User, + self.requester, + "GET", + "six_objects_three_pages", + _kwargs=combine_kwargs(per_page=2), + ) middle_two_items = pag_list[4:6] item_list = [item for item in middle_two_items] self.assertEqual(len(item_list), 2) @@ -125,7 +174,13 @@ def test_slice_oversize(self, m): requires = {"paginated_list": ["4_2_pages_p1", "4_2_pages_p2"]} register_uris(requires, m) - pag_list = PaginatedList(User, self.requester, "GET", "four_objects_two_pages") + pag_list = PaginatedList( + User, + self.requester, + "GET", + "four_objects_two_pages", + _kwargs=combine_kwargs(per_page=2), + ) oversized_slice = pag_list[0:10] item_list = [item for item in oversized_slice] self.assertEqual(len(item_list), 4) @@ -134,7 +189,13 @@ def test_slice_out_of_bounds(self, m): requires = {"paginated_list": ["4_2_pages_p1", "4_2_pages_p2"]} register_uris(requires, m) - pag_list = PaginatedList(User, self.requester, "GET", "four_objects_two_pages") + pag_list = PaginatedList( + User, + self.requester, + "GET", + "four_objects_two_pages", + _kwargs=combine_kwargs(per_page=2), + ) out_of_bounds = pag_list[4:5] item_list = [item for item in out_of_bounds] self.assertEqual(len(item_list), 0) @@ -144,7 +205,13 @@ def test_repr(self, m): requires = {"paginated_list": ["6_3_pages_p1", "6_3_pages_p2", "6_3_pages_p3"]} register_uris(requires, m) - pag_list = PaginatedList(User, self.requester, "GET", "six_objects_three_pages") + pag_list = PaginatedList( + User, + self.requester, + "GET", + "six_objects_three_pages", + _kwargs=combine_kwargs(per_page=2), + ) self.assertEqual(pag_list.__repr__(), "") def test_root_element_incorrect(self, m): @@ -178,7 +245,13 @@ def test_negative_index(self, m): # Ensure that we can't use negative indexing, even after loading a page register_uris({"paginated_list": ["4_2_pages_p1", "4_2_pages_p2"]}, m) - pag_list = PaginatedList(User, self.requester, "GET", "four_objects_two_pages") + pag_list = PaginatedList( + User, + self.requester, + "GET", + "four_objects_two_pages", + _kwargs=combine_kwargs(per_page=2), + ) pag_list[0] with self.assertRaises(IndexError): @@ -189,7 +262,13 @@ def test_negative_index_for_slice_start(self, m): # Ensure that we can't slice using a negative index as the start item register_uris({"paginated_list": ["4_2_pages_p1", "4_2_pages_p2"]}, m) - pag_list = PaginatedList(User, self.requester, "GET", "four_objects_two_pages") + pag_list = PaginatedList( + User, + self.requester, + "GET", + "four_objects_two_pages", + _kwargs=combine_kwargs(per_page=2), + ) pag_list[0] with self.assertRaises(IndexError): @@ -200,7 +279,13 @@ def test_negative_index_for_slice_end(self, m): # Ensure that we can't slice using a negative index as the end item register_uris({"paginated_list": ["4_2_pages_p1", "4_2_pages_p2"]}, m) - pag_list = PaginatedList(User, self.requester, "GET", "four_objects_two_pages") + pag_list = PaginatedList( + User, + self.requester, + "GET", + "four_objects_two_pages", + _kwargs=combine_kwargs(per_page=2), + ) pag_list[0] with self.assertRaises(IndexError): @@ -217,6 +302,7 @@ def test_paginated_list_no_header(self, m): "GET", "no_header_four_objects_two_pages", _root="assessments", + _kwargs=combine_kwargs(per_page=2), ) self.assertIsInstance(pag_list, PaginatedList)