Skip to content

Commit 643454c

Browse files
authored
Merge pull request #1277 from python-gitlab/feat/override-user-agent
feat(api,cli): make user agent configurable
2 parents 071d699 + a69a214 commit 643454c

File tree

9 files changed

+88
-11
lines changed

9 files changed

+88
-11
lines changed

docs/api-usage.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@ To connect to a GitLab server, create a ``gitlab.Gitlab`` object:
2626
# anonymous gitlab instance, read-only for public resources
2727
gl = gitlab.Gitlab('http://10.0.0.1')
2828
29+
# Define your own custom user agent for requests
30+
gl = gitlab.Gitlab('http://10.0.0.1', user_agent='my-package/1.0.0')
31+
2932
# make an API request to create the gl.user object. This is mandatory if you
3033
# use the username/password authentication.
3134
gl.auth()

docs/cli-usage.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,9 @@ parameters. You can override the values in each GitLab server section.
7878
- Integer between 1 and 100
7979
- The number of items to return in listing queries. GitLab limits the
8080
value at 100.
81+
* - ``user_agent``
82+
- ``str``
83+
- A string defining a custom user agent to use when ``gitlab`` makes requests.
8184

8285
You must define the ``url`` in each GitLab server section.
8386

gitlab/__init__.py

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -24,19 +24,20 @@
2424
import requests.utils
2525

2626
import gitlab.config
27+
from gitlab.__version__ import (
28+
__author__,
29+
__copyright__,
30+
__email__,
31+
__license__,
32+
__title__,
33+
__version__,
34+
)
2735
from gitlab.const import * # noqa
2836
from gitlab.exceptions import * # noqa
2937
from gitlab import utils # noqa
3038
from requests_toolbelt.multipart.encoder import MultipartEncoder
3139

3240

33-
__title__ = "python-gitlab"
34-
__version__ = "2.6.0"
35-
__author__ = "Gauvain Pocentek"
36-
__email__ = "gauvainpocentek@gmail.com"
37-
__license__ = "LGPL3"
38-
__copyright__ = "Copyright 2013-2019 Gauvain Pocentek"
39-
4041
warnings.filterwarnings("default", category=DeprecationWarning, module="^gitlab")
4142

4243
REDIRECT_MSG = (
@@ -64,6 +65,7 @@ class Gitlab(object):
6465
api_version (str): Gitlab API version to use (support for 4 only)
6566
pagination (str): Can be set to 'keyset' to use keyset pagination
6667
order_by (str): Set order_by globally
68+
user_agent (str): A custom user agent to use for making HTTP requests.
6769
"""
6870

6971
def __init__(
@@ -81,6 +83,7 @@ def __init__(
8183
per_page=None,
8284
pagination=None,
8385
order_by=None,
86+
user_agent=USER_AGENT,
8487
):
8588

8689
self._api_version = str(api_version)
@@ -90,7 +93,7 @@ def __init__(
9093
#: Timeout to use for requests to gitlab server
9194
self.timeout = timeout
9295
#: Headers that will be used in request to GitLab
93-
self.headers = {"User-Agent": "%s/%s" % (__title__, __version__)}
96+
self.headers = {"User-Agent": user_agent}
9497

9598
#: Whether SSL certificates should be validated
9699
self.ssl_verify = ssl_verify
@@ -204,6 +207,7 @@ def from_config(cls, gitlab_id=None, config_files=None):
204207
per_page=config.per_page,
205208
pagination=config.pagination,
206209
order_by=config.order_by,
210+
user_agent=config.user_agent,
207211
)
208212

209213
def auth(self):

gitlab/__version__.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
__author__ = "Gauvain Pocentek, python-gitlab team"
2+
__copyright__ = "Copyright 2013-2019 Gauvain Pocentek, 2019-2021 python-gitlab team"
3+
__email__ = "gauvainpocentek@gmail.com"
4+
__license__ = "LGPL3"
5+
__title__ = "python-gitlab"
6+
__version__ = "2.6.0"

gitlab/config.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
import os
1919
import configparser
2020

21+
from gitlab.const import USER_AGENT
22+
2123

2224
def _env_config():
2325
if "PYTHON_GITLAB_CFG" in os.environ:
@@ -177,3 +179,13 @@ def __init__(self, gitlab_id=None, config_files=None):
177179
self.order_by = self._config.get(self.gitlab_id, "order_by")
178180
except Exception:
179181
pass
182+
183+
self.user_agent = USER_AGENT
184+
try:
185+
self.user_agent = self._config.get("global", "user_agent")
186+
except Exception:
187+
pass
188+
try:
189+
self.user_agent = self._config.get(self.gitlab_id, "user_agent")
190+
except Exception:
191+
pass

gitlab/const.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@
1515
# You should have received a copy of the GNU Lesser General Public License
1616
# along with this program. If not, see <http://www.gnu.org/licenses/>.
1717

18+
from gitlab.__version__ import __title__, __version__
19+
20+
1821
NO_ACCESS = 0
1922
MINIMAL_ACCESS = 5
2023
GUEST_ACCESS = 10
@@ -51,3 +54,5 @@
5154

5255
# specific project scope
5356
SEARCH_SCOPE_PROJECT_NOTES = "notes"
57+
58+
USER_AGENT = "{}/{}".format(__title__, __version__)

gitlab/tests/test_config.py

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,12 @@
2121
import mock
2222
import io
2323

24-
from gitlab import config
24+
from gitlab import config, USER_AGENT
2525
import pytest
2626

2727

28+
custom_user_agent = "my-package/1.0.0"
29+
2830
valid_config = u"""[global]
2931
default = one
3032
ssl_verify = true
@@ -51,6 +53,17 @@
5153
oauth_token = STUV
5254
"""
5355

56+
custom_user_agent_config = """[global]
57+
default = one
58+
user_agent = {}
59+
60+
[one]
61+
url = http://one.url
62+
private_token = ABCDEF
63+
""".format(
64+
custom_user_agent
65+
)
66+
5467
no_default_config = u"""[global]
5568
[there]
5669
url = http://there.url
@@ -178,3 +191,21 @@ def test_valid_data(m_open, path_exists):
178191
assert "STUV" == cp.oauth_token
179192
assert 2 == cp.timeout
180193
assert True == cp.ssl_verify
194+
195+
196+
@mock.patch("os.path.exists")
197+
@mock.patch("builtins.open")
198+
@pytest.mark.parametrize(
199+
"config_string,expected_agent",
200+
[
201+
(valid_config, USER_AGENT),
202+
(custom_user_agent_config, custom_user_agent),
203+
],
204+
)
205+
def test_config_user_agent(m_open, path_exists, config_string, expected_agent):
206+
fd = io.StringIO(config_string)
207+
fd.close = mock.Mock(return_value=None)
208+
m_open.return_value = fd
209+
210+
cp = config.GitlabConfigParser()
211+
assert cp.user_agent == expected_agent

gitlab/tests/test_gitlab.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,10 @@
1818

1919
import pickle
2020

21+
import pytest
2122
from httmock import HTTMock, response, urlmatch, with_httmock # noqa
2223

23-
from gitlab import Gitlab, GitlabList
24+
from gitlab import Gitlab, GitlabList, USER_AGENT
2425
from gitlab.v4.objects import CurrentUser
2526

2627

@@ -139,3 +140,15 @@ class MyGitlab(Gitlab):
139140
config_path = default_config
140141
gl = MyGitlab.from_config("one", [config_path])
141142
assert isinstance(gl, MyGitlab)
143+
144+
145+
@pytest.mark.parametrize(
146+
"kwargs,expected_agent",
147+
[
148+
({}, USER_AGENT),
149+
({"user_agent": "my-package/1.0.0"}, "my-package/1.0.0"),
150+
],
151+
)
152+
def test_gitlab_user_agent(kwargs, expected_agent):
153+
gl = Gitlab("http://localhost", **kwargs)
154+
assert gl.headers["User-Agent"] == expected_agent

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77

88
def get_version():
9-
with open("gitlab/__init__.py") as f:
9+
with open("gitlab/__version__.py") as f:
1010
for line in f:
1111
if line.startswith("__version__"):
1212
return eval(line.split("=")[-1])

0 commit comments

Comments
 (0)