GeezerVison is showing github.com — feat!: default to gitlab.com if no URL given · python-gitlab/python-gitlab@7bc388c
File treeExpand file treeCollapse file tree Open diff view settings Expand file treeCollapse file tree Open diff view settings Collapse file Copy file name to clipboardExpand all lines: docs/api-usage.rst +23-20Lines changed: 23 additions & 20 deletions - Display the source diff
- Display the rich diff
| Original file line number | Diff line number | Diff line change |
|---|
| 2 | 2 | Getting started with the API | 3 | 3 | ############################ | 4 | 4 |
| 5 | | -python-gitlab only supports GitLab APIs v4. | | 5 | +python-gitlab only supports GitLab API v4. | 6 | 6 |
| 7 | 7 | ``gitlab.Gitlab`` class | 8 | 8 | ======================= | 9 | 9 |
| 10 | | -To connect to a GitLab server, create a ``gitlab.Gitlab`` object: | | 10 | +To connect to GitLab.com or another GitLab instance, create a ``gitlab.Gitlab`` object: | 11 | 11 |
| 12 | 12 | .. code-block:: python | 13 | 13 |
| 14 | 14 | import gitlab | 15 | 15 |
| 16 | | - # private token or personal token authentication | 17 | | - # Note that a 'url' that results in 301/302 redirects will cause an error | 18 | | - # (see below for more information). | | 16 | + # anonymous read-only access for public resources (GitLab.com) | | 17 | + gl = gitlab.Gitlab() | | 18 | +
| | 19 | + # anonymous read-only access for public resources (self-hosted GitLab instance) | | 20 | + gl = gitlab.Gitlab('https://gitlab.example.com') | | 21 | +
| | 22 | + # private token or personal token authentication (GitLab.com) | | 23 | + gl = gitlab.Gitlab(private_token='JVNSESs8EwWRx5yDxM5q') | | 24 | +
| | 25 | + # private token or personal token authentication (self-hosted GitLab instance) | 19 | 26 | gl = gitlab.Gitlab(url='https://gitlab.example.com', private_token='JVNSESs8EwWRx5yDxM5q') | 20 | 27 |
| 21 | 28 | # oauth token authentication | 22 | | - gl = gitlab.Gitlab('http://10.0.0.1', oauth_token='my_long_token_here') | | 29 | + gl = gitlab.Gitlab('https://gitlab.example.com', oauth_token='my_long_token_here') | 23 | 30 |
| 24 | 31 | # job token authentication (to be used in CI) | 25 | 32 | import os | 26 | | - gl = gitlab.Gitlab('http://10.0.0.1', job_token=os.environ['CI_JOB_TOKEN']) | 27 | | -
| 28 | | - # anonymous gitlab instance, read-only for public resources | 29 | | - gl = gitlab.Gitlab('http://10.0.0.1') | 30 | | -
| 31 | | - # Define your own custom user agent for requests | 32 | | - gl = gitlab.Gitlab('http://10.0.0.1', user_agent='my-package/1.0.0') | | 33 | + gl = gitlab.Gitlab('https://gitlab.example.com', job_token=os.environ['CI_JOB_TOKEN']) | 33 | 34 |
| 34 | 35 | # make an API request to create the gl.user object. This is mandatory if you | 35 | 36 | # use the username/password authentication. | @@ -46,15 +47,17 @@ configuration files. | 46 | 47 |
| 47 | 48 | .. warning:: | 48 | 49 |
| 49 | | - If the GitLab server you are using redirects requests from http to https, | 50 | | - make sure to use the ``https://`` protocol in the URL definition. | | 50 | + Note that a url that results in 301/302 redirects will raise an error, | | 51 | + so it is highly recommended to use the final destination in the ``url`` field. | | 52 | + For example, if the GitLab server you are using redirects requests from http | | 53 | + to https, make sure to use the ``https://`` protocol in the URL definition. | 51 | 54 |
| 52 | | -.. note:: | | 55 | + A URL that redirects using 301/302 (rather than 307/308) will most likely | | 56 | + `cause malformed POST and PUT requests <https://github.com/psf/requests/blob/c45a4dfe6bfc6017d4ea7e9f051d6cc30972b310/requests/sessions.py#L324-L332>`_. | 53 | 57 |
| 54 | | - It is highly recommended to use the final destination in the ``url`` field. | 55 | | - What this means is that you should not use a URL which redirects as it will | 56 | | - most likely cause errors. python-gitlab will raise a ``RedirectionError`` | 57 | | - when it encounters a redirect which it believes will cause an error. | | 58 | + python-gitlab will therefore raise a ``RedirectionError`` when it encounters | | 59 | + a redirect which it believes will cause such an error, to avoid confusion | | 60 | + between successful GET and failing POST/PUT requests on the same instance. | 58 | 61 |
| 59 | 62 | Note on password authentication | 60 | 63 | ------------------------------- | |
Collapse file Copy file name to clipboardExpand all lines: docs/cli-usage.rst +9-7Lines changed: 9 additions & 7 deletions - Display the source diff
- Display the rich diff
| Original file line number | Diff line number | Diff line change |
|---|
@@ -86,15 +86,17 @@ You must define the ``url`` in each GitLab server section. | 86 | 86 |
| 87 | 87 | .. warning:: | 88 | 88 |
| 89 | | - If the GitLab server you are using redirects requests from http to https, | 90 | | - make sure to use the ``https://`` protocol in the ``url`` definition. | | 89 | + Note that a url that results in 301/302 redirects will raise an error, | | 90 | + so it is highly recommended to use the final destination in the ``url`` field. | | 91 | + For example, if the GitLab server you are using redirects requests from http | | 92 | + to https, make sure to use the ``https://`` protocol in the URL definition. | 91 | 93 |
| 92 | | -.. note:: | | 94 | + A URL that redirects using 301/302 (rather than 307/308) will most likely | | 95 | + `cause malformed POST and PUT requests <https://github.com/psf/requests/blob/c45a4dfe6bfc6017d4ea7e9f051d6cc30972b310/requests/sessions.py#L324-L332>`_. | 93 | 96 |
| 94 | | - It is highly recommended to use the final destination in the ``url`` field. | 95 | | - What this means is that you should not use a URL which redirects as it will | 96 | | - most likely cause errors. python-gitlab will raise a ``RedirectionError`` | 97 | | - when it encounters a redirect which it believes will cause an error. | | 97 | + python-gitlab will therefore raise a ``RedirectionError`` when it encounters | | 98 | + a redirect which it believes will cause such an error, to avoid confusion | | 99 | + between successful GET and failing POST/PUT requests on the same instance. | 98 | 100 |
| 99 | 101 | Only one of ``private_token``, ``oauth_token`` or ``job_token`` should be | 100 | 102 | defined. If neither are defined an anonymous request will be sent to the Gitlab | |
Collapse file Copy file name to clipboardExpand all lines: gitlab/client.py +14-3Lines changed: 14 additions & 3 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -39,7 +39,7 @@ class Gitlab(object): | 39 | 39 | """Represents a GitLab server connection. | 40 | 40 |
| 41 | 41 | Args: | 42 | | - url (str): The URL of the GitLab server. | | 42 | + url (str): The URL of the GitLab server (defaults to https://gitlab.com). | 43 | 43 | private_token (str): The user private token | 44 | 44 | oauth_token (str): An oauth token | 45 | 45 | job_token (str): A CI job token | @@ -59,7 +59,7 @@ class Gitlab(object): | 59 | 59 |
| 60 | 60 | def __init__( | 61 | 61 | self, | 62 | | - url: str, | | 62 | + url: Optional[str] = None, | 63 | 63 | private_token: Optional[str] = None, | 64 | 64 | oauth_token: Optional[str] = None, | 65 | 65 | job_token: Optional[str] = None, | @@ -79,7 +79,7 @@ def __init__( | 79 | 79 | self._api_version = str(api_version) | 80 | 80 | self._server_version: Optional[str] = None | 81 | 81 | self._server_revision: Optional[str] = None | 82 | | - self._base_url = url.rstrip("/") | | 82 | + self._base_url = self._get_base_url(url) | 83 | 83 | self._url = "%s/api/v%s" % (self._base_url, api_version) | 84 | 84 | #: Timeout to use for requests to gitlab server | 85 | 85 | self.timeout = timeout | @@ -442,6 +442,17 @@ def _get_session_opts(self) -> Dict[str, Any]: | 442 | 442 | "verify": self.ssl_verify, | 443 | 443 | } | 444 | 444 |
| | 445 | + def _get_base_url(self, url: Optional[str] = None) -> str: | | 446 | + """Return the base URL with the trailing slash stripped. | | 447 | + If the URL is a Falsy value, return the default URL. | | 448 | + Returns: | | 449 | + str: The base URL | | 450 | + """ | | 451 | + if not url: | | 452 | + return gitlab.const.DEFAULT_URL | | 453 | + | | 454 | + return url.rstrip("/") | | 455 | + | 445 | 456 | def _build_url(self, path: str) -> str: | 446 | 457 | """Returns the full url from path. | 447 | 458 |
| |
Collapse file Copy file name to clipboardExpand all lines: gitlab/const.py +2Lines changed: 2 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
| 17 | 17 |
| 18 | 18 | from gitlab.__version__ import __title__, __version__ | 19 | 19 |
| | 20 | +DEFAULT_URL: str = "https://gitlab.com" | | 21 | + | 20 | 22 | NO_ACCESS: int = 0 | 21 | 23 | MINIMAL_ACCESS: int = 5 | 22 | 24 | GUEST_ACCESS: int = 10 | |
Collapse file Copy file name to clipboardExpand all lines: tests/unit/test_gitlab.py +44-1Lines changed: 44 additions & 1 deletion | Original file line number | Diff line number | Diff line change |
|---|
| 21 | 21 | import pytest | 22 | 22 | from httmock import HTTMock, response, urlmatch, with_httmock # noqa | 23 | 23 |
| 24 | | -from gitlab import Gitlab, GitlabList, USER_AGENT | | 24 | +from gitlab import DEFAULT_URL, Gitlab, GitlabList, USER_AGENT | 25 | 25 | from gitlab.v4.objects import CurrentUser | 26 | 26 |
| | 27 | +localhost = "http://localhost" | 27 | 28 | username = "username" | 28 | 29 | user_id = 1 | | 30 | +token = "abc123" | 29 | 31 |
| 30 | 32 |
| 31 | 33 | @urlmatch(scheme="http", netloc="localhost", path="/api/v4/user", method="get") | @@ -127,6 +129,47 @@ def test_gitlab_token_auth(gl, callback=None): | 127 | 129 | assert isinstance(gl.user, CurrentUser) | 128 | 130 |
| 129 | 131 |
| | 132 | +def test_gitlab_default_url(): | | 133 | + gl = Gitlab() | | 134 | + assert gl.url == DEFAULT_URL | | 135 | + | | 136 | + | | 137 | +@pytest.mark.parametrize( | | 138 | + "args, kwargs, expected_url, expected_private_token, expected_oauth_token", | | 139 | + [ | | 140 | + ([], {}, DEFAULT_URL, None, None), | | 141 | + ([None, token], {}, DEFAULT_URL, token, None), | | 142 | + ([localhost], {}, localhost, None, None), | | 143 | + ([localhost, token], {}, localhost, token, None), | | 144 | + ([localhost, None, token], {}, localhost, None, token), | | 145 | + ([], {"private_token": token}, DEFAULT_URL, token, None), | | 146 | + ([], {"oauth_token": token}, DEFAULT_URL, None, token), | | 147 | + ([], {"url": localhost}, localhost, None, None), | | 148 | + ([], {"url": localhost, "private_token": token}, localhost, token, None), | | 149 | + ([], {"url": localhost, "oauth_token": token}, localhost, None, token), | | 150 | + ], | | 151 | + ids=[ | | 152 | + "no_args", | | 153 | + "args_private_token", | | 154 | + "args_url", | | 155 | + "args_url_private_token", | | 156 | + "args_url_oauth_token", | | 157 | + "kwargs_private_token", | | 158 | + "kwargs_oauth_token", | | 159 | + "kwargs_url", | | 160 | + "kwargs_url_private_token", | | 161 | + "kwargs_url_oauth_token", | | 162 | + ], | | 163 | +) | | 164 | +def test_gitlab_args_kwargs( | | 165 | + args, kwargs, expected_url, expected_private_token, expected_oauth_token | | 166 | +): | | 167 | + gl = Gitlab(*args, **kwargs) | | 168 | + assert gl.url == expected_url | | 169 | + assert gl.private_token == expected_private_token | | 170 | + assert gl.oauth_token == expected_oauth_token | | 171 | + | | 172 | + | 130 | 173 | def test_gitlab_from_config(default_config): | 131 | 174 | config_path = default_config | 132 | 175 | Gitlab.from_config("one", [config_path]) | |
|