Skip to content

Commit f86ef3b

Browse files
committed
fix: use keyset pagination by default for /projects > 50000
Workaround for https://gitlab.com/gitlab-org/gitlab/-/issues/218504. Remove this in 13.1
1 parent ef6181b commit f86ef3b

File tree

1 file changed

+25
-5
lines changed

1 file changed

+25
-5
lines changed

gitlab/__init__.py

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,12 @@
1616
# along with this program. If not, see <http://www.gnu.org/licenses/>.
1717
"""Wrapper for the GitLab API."""
1818

19-
from __future__ import print_function
20-
from __future__ import absolute_import
2119
import importlib
2220
import time
2321
import warnings
2422

2523
import requests
24+
import requests.utils
2625

2726
import gitlab.config
2827
from gitlab.const import * # noqa
@@ -43,6 +42,8 @@
4342
"must update your GitLab URL to use https:// to avoid issues."
4443
)
4544

45+
ALLOWED_KEYSET_ENDPOINTS = ["/projects"]
46+
4647

4748
def _sanitize(value):
4849
if isinstance(value, dict):
@@ -618,7 +619,7 @@ def http_list(self, path, query_data=None, as_list=None, **kwargs):
618619
619620
Args:
620621
path (str): Path or full URL to query ('/projects' or
621-
'http://whatever/v4/api/projecs')
622+
'http://whatever/v4/api/projects')
622623
query_data (dict): Data to send as query parameters
623624
**kwargs: Extra options to send to the server (e.g. sudo, page,
624625
per_page)
@@ -642,10 +643,22 @@ def http_list(self, path, query_data=None, as_list=None, **kwargs):
642643
get_all = kwargs.pop("all", False)
643644
url = self._build_url(path)
644645

646+
order_by = kwargs.get("order_by")
647+
pagination = kwargs.get("pagination")
648+
page = kwargs.get("page")
649+
if (
650+
path in ALLOWED_KEYSET_ENDPOINTS
651+
and (not order_by or order_by == "id")
652+
and (not pagination or pagination == "keyset")
653+
and not page
654+
):
655+
kwargs["pagination"] = "keyset"
656+
kwargs["order_by"] = "id"
657+
645658
if get_all is True and as_list is True:
646659
return list(GitlabList(self, url, query_data, **kwargs))
647660

648-
if "page" in kwargs or as_list is True:
661+
if page or as_list is True:
649662
# pagination requested, we return a list
650663
return list(GitlabList(self, url, query_data, get_next=False, **kwargs))
651664

@@ -781,7 +794,14 @@ def _query(self, url, query_data=None, **kwargs):
781794
query_data = query_data or {}
782795
result = self._gl.http_request("get", url, query_data=query_data, **kwargs)
783796
try:
784-
self._next_url = result.links["next"]["url"]
797+
links = result.links
798+
if links:
799+
next_url = links["next"]["url"]
800+
else:
801+
next_url = requests.utils.parse_header_links(result.headers["links"])[
802+
0
803+
]["url"]
804+
self._next_url = next_url
785805
except KeyError:
786806
self._next_url = None
787807
self._current_page = result.headers.get("X-Page")

0 commit comments

Comments
 (0)