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
7073def __init__ (
@@ -84,6 +87,7 @@ def __init__(
8487order_by :Optional [str ]= None ,
8588user_agent :str = gitlab .const .USER_AGENT ,
8689retry_transient_errors :bool = False ,
90+ keep_base_url :bool = False ,
8791 )-> None :
8892
8993self ._api_version = str (api_version )
@@ -94,6 +98,7 @@ def __init__(
9498#: Timeout to use for requests to gitlab server
9599self .timeout = timeout
96100self .retry_transient_errors = retry_transient_errors
101+ self .keep_base_url = keep_base_url
97102#: Headers that will be used in request to GitLab
98103self .headers = {"User-Agent" :user_agent }
99104
@@ -1132,6 +1137,30 @@ def _query(
11321137next_url = requests .utils .parse_header_links (result .headers ["links" ])[
113311380
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+ )
11351164self ._next_url = next_url
11361165except KeyError :
11371166self ._next_url = None