1717"""Wrapper for the GitLab API."""
1818
1919import os
20+ import re
2021import time
2122from typing import Any , 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+ if not next_url .startswith (self ._gl .url ):
1144+ search_api_url = re .search (r"(^.*?/api)" , next_url )
1145+ if search_api_url :
1146+ next_api_url = search_api_url .group (1 )
1147+ if self ._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 except KeyError :
11371166 self ._next_url = None
0 commit comments