summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNejc Habjan <hab.nejc@gmail.com>2021-01-31 19:17:14 +0100
committerJohn Villalovos <john@sodarock.com>2021-09-08 13:45:27 -0700
commit823628153ec813c4490e749e502a47716425c0f1 (patch)
tree86285c732aa5a75c8fd6611535dbf40bcb65b0c7
parent37424050a00d9b4f46aea9e35d9897478452506d (diff)
downloadgitlab-823628153ec813c4490e749e502a47716425c0f1.tar.gz
feat: default to gitlab.com if no URL given
BREAKING CHANGE: python-gitlab will now default to gitlab.com if no URL is given
-rw-r--r--docs/api-usage.rst42
-rw-r--r--docs/cli-usage.rst16
-rw-r--r--gitlab/client.py17
-rw-r--r--gitlab/const.py2
-rw-r--r--tests/unit/test_gitlab.py45
5 files changed, 93 insertions, 29 deletions
diff --git a/docs/api-usage.rst b/docs/api-usage.rst
index d4a4106..e9fcd8f 100644
--- a/docs/api-usage.rst
+++ b/docs/api-usage.rst
@@ -2,34 +2,38 @@
Getting started with the API
############################
-python-gitlab only supports GitLab APIs v4.
+python-gitlab only supports GitLab API v4.
``gitlab.Gitlab`` class
=======================
-To connect to a GitLab server, create a ``gitlab.Gitlab`` object:
+To connect to GitLab.com or another GitLab instance, create a ``gitlab.Gitlab`` object:
.. code-block:: python
import gitlab
- # private token or personal token authentication
- # Note that a 'url' that results in 301/302 redirects will cause an error
- # (see below for more information).
+ # anonymous read-only access for public resources (GitLab.com)
+ gl = gitlab.Gitlab()
+
+ # anonymous read-only access for public resources (self-hosted GitLab instance)
+ gl = gitlab.Gitlab('https://gitlab.example.com')
+
+ # private token or personal token authentication (GitLab.com)
+ gl = gitlab.Gitlab(private_token='JVNSESs8EwWRx5yDxM5q')
+
+ # private token or personal token authentication (self-hosted GitLab instance)
gl = gitlab.Gitlab(url='https://gitlab.example.com', private_token='JVNSESs8EwWRx5yDxM5q')
# oauth token authentication
- gl = gitlab.Gitlab('http://10.0.0.1', oauth_token='my_long_token_here')
+ gl = gitlab.Gitlab('https://gitlab.example.com', oauth_token='my_long_token_here')
# job token authentication (to be used in CI)
import os
- gl = gitlab.Gitlab('http://10.0.0.1', job_token=os.environ['CI_JOB_TOKEN'])
-
- # anonymous gitlab instance, read-only for public resources
- gl = gitlab.Gitlab('http://10.0.0.1')
+ gl = gitlab.Gitlab('https://gitlab.example.com', job_token=os.environ['CI_JOB_TOKEN'])
# Define your own custom user agent for requests
- gl = gitlab.Gitlab('http://10.0.0.1', user_agent='my-package/1.0.0')
+ gl = gitlab.Gitlab('https://gitlab.example.com', user_agent='my-package/1.0.0')
# make an API request to create the gl.user object. This is mandatory if you
# use the username/password authentication.
@@ -46,15 +50,17 @@ configuration files.
.. warning::
- If the GitLab server you are using redirects requests from http to https,
- make sure to use the ``https://`` protocol in the URL definition.
+ Note that a url that results in 301/302 redirects will raise an error,
+ so it is highly recommended to use the final destination in the ``url`` field.
+ For example, if the GitLab server you are using redirects requests from http
+ to https, make sure to use the ``https://`` protocol in the URL definition.
-.. note::
+ A URL that redirects using 301/302 (rather than 307/308) will most likely
+ `cause malformed POST and PUT requests <https://github.com/psf/requests/blob/c45a4dfe6bfc6017d4ea7e9f051d6cc30972b310/requests/sessions.py#L324-L332>`_.
- It is highly recommended to use the final destination in the ``url`` field.
- What this means is that you should not use a URL which redirects as it will
- most likely cause errors. python-gitlab will raise a ``RedirectionError``
- when it encounters a redirect which it believes will cause an error.
+ python-gitlab will therefore raise a ``RedirectionError`` when it encounters
+ a redirect which it believes will cause such an error, to avoid confusion
+ between successful GET and failing POST/PUT requests on the same instance.
Note on password authentication
-------------------------------
diff --git a/docs/cli-usage.rst b/docs/cli-usage.rst
index e263ef2..ea10f93 100644
--- a/docs/cli-usage.rst
+++ b/docs/cli-usage.rst
@@ -86,15 +86,17 @@ You must define the ``url`` in each GitLab server section.
.. warning::
- If the GitLab server you are using redirects requests from http to https,
- make sure to use the ``https://`` protocol in the ``url`` definition.
+ Note that a url that results in 301/302 redirects will raise an error,
+ so it is highly recommended to use the final destination in the ``url`` field.
+ For example, if the GitLab server you are using redirects requests from http
+ to https, make sure to use the ``https://`` protocol in the URL definition.
-.. note::
+ A URL that redirects using 301/302 (rather than 307/308) will most likely
+ `cause malformed POST and PUT requests <https://github.com/psf/requests/blob/c45a4dfe6bfc6017d4ea7e9f051d6cc30972b310/requests/sessions.py#L324-L332>`_.
- It is highly recommended to use the final destination in the ``url`` field.
- What this means is that you should not use a URL which redirects as it will
- most likely cause errors. python-gitlab will raise a ``RedirectionError``
- when it encounters a redirect which it believes will cause an error.
+ python-gitlab will therefore raise a ``RedirectionError`` when it encounters
+ a redirect which it believes will cause such an error, to avoid confusion
+ between successful GET and failing POST/PUT requests on the same instance.
Only one of ``private_token``, ``oauth_token`` or ``job_token`` should be
defined. If neither are defined an anonymous request will be sent to the Gitlab
diff --git a/gitlab/client.py b/gitlab/client.py
index 9db3a0e..6a1ed28 100644
--- a/gitlab/client.py
+++ b/gitlab/client.py
@@ -39,7 +39,7 @@ class Gitlab(object):
"""Represents a GitLab server connection.
Args:
- url (str): The URL of the GitLab server.
+ url (str): The URL of the GitLab server (defaults to https://gitlab.com).
private_token (str): The user private token
oauth_token (str): An oauth token
job_token (str): A CI job token
@@ -59,7 +59,7 @@ class Gitlab(object):
def __init__(
self,
- url: str,
+ url: Optional[str] = None,
private_token: Optional[str] = None,
oauth_token: Optional[str] = None,
job_token: Optional[str] = None,
@@ -79,7 +79,7 @@ class Gitlab(object):
self._api_version = str(api_version)
self._server_version: Optional[str] = None
self._server_revision: Optional[str] = None
- self._base_url = url.rstrip("/")
+ self._base_url = self._get_base_url(url)
self._url = "%s/api/v%s" % (self._base_url, api_version)
#: Timeout to use for requests to gitlab server
self.timeout = timeout
@@ -442,6 +442,17 @@ class Gitlab(object):
"verify": self.ssl_verify,
}
+ def _get_base_url(self, url: Optional[str] = None) -> str:
+ """Return the base URL with the trailing slash stripped.
+ If the URL is a Falsy value, return the default URL.
+ Returns:
+ str: The base URL
+ """
+ if not url:
+ return gitlab.const.DEFAULT_URL
+
+ return url.rstrip("/")
+
def _build_url(self, path: str) -> str:
"""Returns the full url from path.
diff --git a/gitlab/const.py b/gitlab/const.py
index 33687c1..095b43d 100644
--- a/gitlab/const.py
+++ b/gitlab/const.py
@@ -17,6 +17,8 @@
from gitlab.__version__ import __title__, __version__
+DEFAULT_URL: str = "https://gitlab.com"
+
NO_ACCESS: int = 0
MINIMAL_ACCESS: int = 5
GUEST_ACCESS: int = 10
diff --git a/tests/unit/test_gitlab.py b/tests/unit/test_gitlab.py
index acb8752..2bd7d4d 100644
--- a/tests/unit/test_gitlab.py
+++ b/tests/unit/test_gitlab.py
@@ -21,11 +21,13 @@ import pickle
import pytest
from httmock import HTTMock, response, urlmatch, with_httmock # noqa
-from gitlab import Gitlab, GitlabList, USER_AGENT
+from gitlab import DEFAULT_URL, Gitlab, GitlabList, USER_AGENT
from gitlab.v4.objects import CurrentUser
+localhost = "http://localhost"
username = "username"
user_id = 1
+token = "abc123"
@urlmatch(scheme="http", netloc="localhost", path="/api/v4/user", method="get")
@@ -127,6 +129,47 @@ def test_gitlab_token_auth(gl, callback=None):
assert isinstance(gl.user, CurrentUser)
+def test_gitlab_default_url():
+ gl = Gitlab()
+ assert gl.url == DEFAULT_URL
+
+
+@pytest.mark.parametrize(
+ "args, kwargs, expected_url, expected_private_token, expected_oauth_token",
+ [
+ ([], {}, DEFAULT_URL, None, None),
+ ([None, token], {}, DEFAULT_URL, token, None),
+ ([localhost], {}, localhost, None, None),
+ ([localhost, token], {}, localhost, token, None),
+ ([localhost, None, token], {}, localhost, None, token),
+ ([], {"private_token": token}, DEFAULT_URL, token, None),
+ ([], {"oauth_token": token}, DEFAULT_URL, None, token),
+ ([], {"url": localhost}, localhost, None, None),
+ ([], {"url": localhost, "private_token": token}, localhost, token, None),
+ ([], {"url": localhost, "oauth_token": token}, localhost, None, token),
+ ],
+ ids=[
+ "no_args",
+ "args_private_token",
+ "args_url",
+ "args_url_private_token",
+ "args_url_oauth_token",
+ "kwargs_private_token",
+ "kwargs_oauth_token",
+ "kwargs_url",
+ "kwargs_url_private_token",
+ "kwargs_url_oauth_token",
+ ],
+)
+def test_gitlab_args_kwargs(
+ args, kwargs, expected_url, expected_private_token, expected_oauth_token
+):
+ gl = Gitlab(*args, **kwargs)
+ assert gl.url == expected_url
+ assert gl.private_token == expected_private_token
+ assert gl.oauth_token == expected_oauth_token
+
+
def test_gitlab_from_config(default_config):
config_path = default_config
Gitlab.from_config("one", [config_path])