Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commite2ea8b8

Browse files
authored
fix: optionally keep user-provided base URL for pagination (#2149)
1 parent1136b17 commite2ea8b8

File tree

2 files changed

+84
-0
lines changed

2 files changed

+84
-0
lines changed

‎gitlab/client.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
"""Wrapper for the GitLab API."""
1818

1919
importos
20+
importre
2021
importtime
2122
fromtypingimportAny,cast,Dict,List,Optional,Tuple,TYPE_CHECKING,Union
2223

@@ -65,6 +66,8 @@ class Gitlab:
6566
user_agent: A custom user agent to use for making HTTP requests.
6667
retry_transient_errors: Whether to retry after 500, 502, 503, 504
6768
or 52x responses. Defaults to False.
69+
keep_base_url: keep user-provided base URL for pagination if it
70+
differs from response headers
6871
"""
6972

7073
def__init__(
@@ -84,6 +87,7 @@ def __init__(
8487
order_by:Optional[str]=None,
8588
user_agent:str=gitlab.const.USER_AGENT,
8689
retry_transient_errors:bool=False,
90+
keep_base_url:bool=False,
8791
)->None:
8892

8993
self._api_version=str(api_version)
@@ -94,6 +98,7 @@ def __init__(
9498
#: Timeout to use for requests to gitlab server
9599
self.timeout=timeout
96100
self.retry_transient_errors=retry_transient_errors
101+
self.keep_base_url=keep_base_url
97102
#: Headers that will be used in request to GitLab
98103
self.headers= {"User-Agent":user_agent}
99104

@@ -1132,6 +1137,30 @@ def _query(
11321137
next_url=requests.utils.parse_header_links(result.headers["links"])[
11331138
0
11341139
]["url"]
1140+
# if the next url is different with user provided server URL
1141+
# then give a warning it may because of misconfiguration
1142+
# but if the option to fix provided then just reconstruct it
1143+
ifnotnext_url.startswith(self._gl.url):
1144+
search_api_url=re.search(r"(^.*?/api)",next_url)
1145+
ifsearch_api_url:
1146+
next_api_url=search_api_url.group(1)
1147+
ifself._gl.keep_base_url:
1148+
next_url=next_url.replace(
1149+
next_api_url,f"{self._gl._base_url}/api"
1150+
)
1151+
else:
1152+
utils.warn(
1153+
message=(
1154+
f"The base URL in the server response"
1155+
f"differs from the user-provided base URL "
1156+
f"({self._gl.url}/api/ ->{next_api_url}/). "
1157+
f"This may lead to unexpected behavior and "
1158+
f"broken pagination. Use `keep_base_url=True` "
1159+
f"when initializing the Gitlab instance "
1160+
f"to follow the user-provided base URL."
1161+
),
1162+
category=UserWarning,
1163+
)
11351164
self._next_url=next_url
11361165
exceptKeyError:
11371166
self._next_url=None

‎tests/unit/test_gitlab.py

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -353,3 +353,58 @@ def test_gitlab_plain_const_does_not_warn(recwarn):
353353

354354
assertnotrecwarn
355355
assertno_access==0
356+
357+
358+
@responses.activate
359+
@pytest.mark.parametrize(
360+
"kwargs,link_header,expected_next_url,show_warning",
361+
[
362+
(
363+
{},
364+
"<http://localhost/api/v4/tests?per_page=1&page=2>;"' rel="next"',
365+
"http://localhost/api/v4/tests?per_page=1&page=2",
366+
False,
367+
),
368+
(
369+
{},
370+
"<http://orig_host/api/v4/tests?per_page=1&page=2>;"' rel="next"',
371+
"http://orig_host/api/v4/tests?per_page=1&page=2",
372+
True,
373+
),
374+
(
375+
{"keep_base_url":True},
376+
"<http://orig_host/api/v4/tests?per_page=1&page=2>;"' rel="next"',
377+
"http://localhost/api/v4/tests?per_page=1&page=2",
378+
False,
379+
),
380+
],
381+
ids=["url-match-does-not-warn","url-mismatch-warns","url-mismatch-keeps-url"],
382+
)
383+
deftest_gitlab_keep_base_url(kwargs,link_header,expected_next_url,show_warning):
384+
responses.add(
385+
**{
386+
"method":responses.GET,
387+
"url":"http://localhost/api/v4/tests",
388+
"json": [{"a":"b"}],
389+
"headers": {
390+
"X-Page":"1",
391+
"X-Next-Page":"2",
392+
"X-Per-Page":"1",
393+
"X-Total-Pages":"2",
394+
"X-Total":"2",
395+
"Link": (link_header),
396+
},
397+
"content_type":"application/json",
398+
"status":200,
399+
"match":helpers.MATCH_EMPTY_QUERY_PARAMS,
400+
}
401+
)
402+
403+
gl=gitlab.Gitlab(url="http://localhost",**kwargs)
404+
ifshow_warning:
405+
withpytest.warns(UserWarning)aswarn_record:
406+
obj=gl.http_list("/tests",iterator=True)
407+
assertlen(warn_record)==1
408+
else:
409+
obj=gl.http_list("/tests",iterator=True)
410+
assertobj._next_url==expected_next_url

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp