python-gitlab 4.10.0__py3-none-any.whl → 4.11.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- gitlab/__init__.py +2 -1
- gitlab/_backends/graphql.py +24 -0
- gitlab/_version.py +1 -1
- gitlab/client.py +118 -47
- gitlab/utils.py +91 -2
- gitlab/v4/objects/members.py +4 -2
- {python_gitlab-4.10.0.dist-info → python_gitlab-4.11.1.dist-info}/METADATA +3 -1
- {python_gitlab-4.10.0.dist-info → python_gitlab-4.11.1.dist-info}/RECORD +13 -12
- {python_gitlab-4.10.0.dist-info → python_gitlab-4.11.1.dist-info}/WHEEL +1 -1
- {python_gitlab-4.10.0.dist-info → python_gitlab-4.11.1.dist-info}/AUTHORS +0 -0
- {python_gitlab-4.10.0.dist-info → python_gitlab-4.11.1.dist-info}/COPYING +0 -0
- {python_gitlab-4.10.0.dist-info → python_gitlab-4.11.1.dist-info}/entry_points.txt +0 -0
- {python_gitlab-4.10.0.dist-info → python_gitlab-4.11.1.dist-info}/top_level.txt +0 -0
gitlab/__init__.py
CHANGED
@@ -27,7 +27,7 @@ from gitlab._version import ( # noqa: F401
|
|
27
27
|
__title__,
|
28
28
|
__version__,
|
29
29
|
)
|
30
|
-
from gitlab.client import Gitlab, GitlabList # noqa: F401
|
30
|
+
from gitlab.client import Gitlab, GitlabList, GraphQL # noqa: F401
|
31
31
|
from gitlab.exceptions import * # noqa: F401,F403
|
32
32
|
|
33
33
|
warnings.filterwarnings("default", category=DeprecationWarning, module="^gitlab")
|
@@ -42,5 +42,6 @@ __all__ = [
|
|
42
42
|
"__version__",
|
43
43
|
"Gitlab",
|
44
44
|
"GitlabList",
|
45
|
+
"GraphQL",
|
45
46
|
]
|
46
47
|
__all__.extend(gitlab.exceptions.__all__)
|
@@ -0,0 +1,24 @@
|
|
1
|
+
from typing import Any
|
2
|
+
|
3
|
+
import httpx
|
4
|
+
from gql.transport.httpx import HTTPXTransport
|
5
|
+
|
6
|
+
|
7
|
+
class GitlabTransport(HTTPXTransport):
|
8
|
+
"""A gql httpx transport that reuses an existing httpx.Client.
|
9
|
+
By default, gql's transports do not have a keep-alive session
|
10
|
+
and do not enable providing your own session that's kept open.
|
11
|
+
This transport lets us provide and close our session on our own
|
12
|
+
and provide additional auth.
|
13
|
+
For details, see https://github.com/graphql-python/gql/issues/91.
|
14
|
+
"""
|
15
|
+
|
16
|
+
def __init__(self, *args: Any, client: httpx.Client, **kwargs: Any):
|
17
|
+
super().__init__(*args, **kwargs)
|
18
|
+
self.client = client
|
19
|
+
|
20
|
+
def connect(self) -> None:
|
21
|
+
pass
|
22
|
+
|
23
|
+
def close(self) -> None:
|
24
|
+
pass
|
gitlab/_version.py
CHANGED
gitlab/client.py
CHANGED
@@ -1,8 +1,9 @@
|
|
1
1
|
"""Wrapper for the GitLab API."""
|
2
2
|
|
3
|
+
from __future__ import annotations
|
4
|
+
|
3
5
|
import os
|
4
6
|
import re
|
5
|
-
import time
|
6
7
|
from typing import (
|
7
8
|
Any,
|
8
9
|
BinaryIO,
|
@@ -25,6 +26,19 @@ import gitlab.const
|
|
25
26
|
import gitlab.exceptions
|
26
27
|
from gitlab import _backends, utils
|
27
28
|
|
29
|
+
try:
|
30
|
+
import gql
|
31
|
+
import gql.transport.exceptions
|
32
|
+
import graphql
|
33
|
+
import httpx
|
34
|
+
|
35
|
+
from ._backends.graphql import GitlabTransport
|
36
|
+
|
37
|
+
_GQL_INSTALLED = True
|
38
|
+
except ImportError: # pragma: no cover
|
39
|
+
_GQL_INSTALLED = False
|
40
|
+
|
41
|
+
|
28
42
|
REDIRECT_MSG = (
|
29
43
|
"python-gitlab detected a {status_code} ({reason!r}) redirection. You must update "
|
30
44
|
"your GitLab URL to the correct URL to avoid issues. The redirection was from: "
|
@@ -89,7 +103,7 @@ class Gitlab:
|
|
89
103
|
self._api_version = str(api_version)
|
90
104
|
self._server_version: Optional[str] = None
|
91
105
|
self._server_revision: Optional[str] = None
|
92
|
-
self._base_url =
|
106
|
+
self._base_url = utils.get_base_url(url)
|
93
107
|
self._url = f"{self._base_url}/api/v{api_version}"
|
94
108
|
#: Timeout to use for requests to gitlab server
|
95
109
|
self.timeout = timeout
|
@@ -557,18 +571,6 @@ class Gitlab:
|
|
557
571
|
"verify": self.ssl_verify,
|
558
572
|
}
|
559
573
|
|
560
|
-
@staticmethod
|
561
|
-
def _get_base_url(url: Optional[str] = None) -> str:
|
562
|
-
"""Return the base URL with the trailing slash stripped.
|
563
|
-
If the URL is a Falsy value, return the default URL.
|
564
|
-
Returns:
|
565
|
-
The base URL
|
566
|
-
"""
|
567
|
-
if not url:
|
568
|
-
return gitlab.const.DEFAULT_URL
|
569
|
-
|
570
|
-
return url.rstrip("/")
|
571
|
-
|
572
574
|
def _build_url(self, path: str) -> str:
|
573
575
|
"""Returns the full url from path.
|
574
576
|
|
@@ -718,7 +720,12 @@ class Gitlab:
|
|
718
720
|
send_data = self._backend.prepare_send_data(files, post_data, raw)
|
719
721
|
opts["headers"]["Content-type"] = send_data.content_type
|
720
722
|
|
721
|
-
|
723
|
+
retry = utils.Retry(
|
724
|
+
max_retries=max_retries,
|
725
|
+
obey_rate_limit=obey_rate_limit,
|
726
|
+
retry_transient_errors=retry_transient_errors,
|
727
|
+
)
|
728
|
+
|
722
729
|
while True:
|
723
730
|
try:
|
724
731
|
result = self._backend.http_request(
|
@@ -733,14 +740,8 @@ class Gitlab:
|
|
733
740
|
**opts,
|
734
741
|
)
|
735
742
|
except (requests.ConnectionError, requests.exceptions.ChunkedEncodingError):
|
736
|
-
if
|
737
|
-
max_retries == -1 or cur_retries < max_retries
|
738
|
-
):
|
739
|
-
wait_time = 2**cur_retries * 0.1
|
740
|
-
cur_retries += 1
|
741
|
-
time.sleep(wait_time)
|
743
|
+
if retry.handle_retry():
|
742
744
|
continue
|
743
|
-
|
744
745
|
raise
|
745
746
|
|
746
747
|
self._check_redirects(result.response)
|
@@ -748,31 +749,10 @@ class Gitlab:
|
|
748
749
|
if 200 <= result.status_code < 300:
|
749
750
|
return result.response
|
750
751
|
|
751
|
-
|
752
|
-
|
753
|
-
|
754
|
-
|
755
|
-
if not retry_transient_errors:
|
756
|
-
return False
|
757
|
-
if result.status_code in gitlab.const.RETRYABLE_TRANSIENT_ERROR_CODES:
|
758
|
-
return True
|
759
|
-
if result.status_code == 409 and "Resource lock" in result.reason:
|
760
|
-
return True
|
761
|
-
|
762
|
-
return False
|
763
|
-
|
764
|
-
if should_retry():
|
765
|
-
# Response headers documentation:
|
766
|
-
# https://docs.gitlab.com/ee/user/admin_area/settings/user_and_ip_rate_limits.html#response-headers
|
767
|
-
if max_retries == -1 or cur_retries < max_retries:
|
768
|
-
wait_time = 2**cur_retries * 0.1
|
769
|
-
if "Retry-After" in result.headers:
|
770
|
-
wait_time = int(result.headers["Retry-After"])
|
771
|
-
elif "RateLimit-Reset" in result.headers:
|
772
|
-
wait_time = int(result.headers["RateLimit-Reset"]) - time.time()
|
773
|
-
cur_retries += 1
|
774
|
-
time.sleep(wait_time)
|
775
|
-
continue
|
752
|
+
if retry.handle_retry_on_status(
|
753
|
+
result.status_code, result.headers, result.reason
|
754
|
+
):
|
755
|
+
continue
|
776
756
|
|
777
757
|
error_message = result.content
|
778
758
|
try:
|
@@ -1296,3 +1276,94 @@ class GitlabList:
|
|
1296
1276
|
return self.next()
|
1297
1277
|
|
1298
1278
|
raise StopIteration
|
1279
|
+
|
1280
|
+
|
1281
|
+
class GraphQL:
|
1282
|
+
def __init__(
|
1283
|
+
self,
|
1284
|
+
url: Optional[str] = None,
|
1285
|
+
*,
|
1286
|
+
token: Optional[str] = None,
|
1287
|
+
ssl_verify: Union[bool, str] = True,
|
1288
|
+
client: Optional[httpx.Client] = None,
|
1289
|
+
timeout: Optional[float] = None,
|
1290
|
+
user_agent: str = gitlab.const.USER_AGENT,
|
1291
|
+
fetch_schema_from_transport: bool = False,
|
1292
|
+
max_retries: int = 10,
|
1293
|
+
obey_rate_limit: bool = True,
|
1294
|
+
retry_transient_errors: bool = False,
|
1295
|
+
) -> None:
|
1296
|
+
if not _GQL_INSTALLED:
|
1297
|
+
raise ImportError(
|
1298
|
+
"The GraphQL client could not be initialized because "
|
1299
|
+
"the gql dependencies are not installed. "
|
1300
|
+
"Install them with 'pip install python-gitlab[graphql]'"
|
1301
|
+
)
|
1302
|
+
self._base_url = utils.get_base_url(url)
|
1303
|
+
self._timeout = timeout
|
1304
|
+
self._token = token
|
1305
|
+
self._url = f"{self._base_url}/api/graphql"
|
1306
|
+
self._user_agent = user_agent
|
1307
|
+
self._ssl_verify = ssl_verify
|
1308
|
+
self._max_retries = max_retries
|
1309
|
+
self._obey_rate_limit = obey_rate_limit
|
1310
|
+
self._retry_transient_errors = retry_transient_errors
|
1311
|
+
|
1312
|
+
opts = self._get_client_opts()
|
1313
|
+
self._http_client = client or httpx.Client(**opts)
|
1314
|
+
self._transport = GitlabTransport(self._url, client=self._http_client)
|
1315
|
+
self._client = gql.Client(
|
1316
|
+
transport=self._transport,
|
1317
|
+
fetch_schema_from_transport=fetch_schema_from_transport,
|
1318
|
+
)
|
1319
|
+
self._gql = gql.gql
|
1320
|
+
|
1321
|
+
def __enter__(self) -> "GraphQL":
|
1322
|
+
return self
|
1323
|
+
|
1324
|
+
def __exit__(self, *args: Any) -> None:
|
1325
|
+
self._http_client.close()
|
1326
|
+
|
1327
|
+
def _get_client_opts(self) -> Dict[str, Any]:
|
1328
|
+
headers = {"User-Agent": self._user_agent}
|
1329
|
+
|
1330
|
+
if self._token:
|
1331
|
+
headers["Authorization"] = f"Bearer {self._token}"
|
1332
|
+
|
1333
|
+
return {
|
1334
|
+
"headers": headers,
|
1335
|
+
"timeout": self._timeout,
|
1336
|
+
"verify": self._ssl_verify,
|
1337
|
+
}
|
1338
|
+
|
1339
|
+
def execute(
|
1340
|
+
self, request: Union[str, graphql.Source], *args: Any, **kwargs: Any
|
1341
|
+
) -> Any:
|
1342
|
+
parsed_document = self._gql(request)
|
1343
|
+
retry = utils.Retry(
|
1344
|
+
max_retries=self._max_retries,
|
1345
|
+
obey_rate_limit=self._obey_rate_limit,
|
1346
|
+
retry_transient_errors=self._retry_transient_errors,
|
1347
|
+
)
|
1348
|
+
|
1349
|
+
while True:
|
1350
|
+
try:
|
1351
|
+
result = self._client.execute(parsed_document, *args, **kwargs)
|
1352
|
+
except gql.transport.exceptions.TransportServerError as e:
|
1353
|
+
if retry.handle_retry_on_status(
|
1354
|
+
status_code=e.code, headers=self._transport.response_headers
|
1355
|
+
):
|
1356
|
+
continue
|
1357
|
+
|
1358
|
+
if e.code == 401:
|
1359
|
+
raise gitlab.exceptions.GitlabAuthenticationError(
|
1360
|
+
response_code=e.code,
|
1361
|
+
error_message=str(e),
|
1362
|
+
)
|
1363
|
+
|
1364
|
+
raise gitlab.exceptions.GitlabHttpError(
|
1365
|
+
response_code=e.code,
|
1366
|
+
error_message=str(e),
|
1367
|
+
)
|
1368
|
+
|
1369
|
+
return result
|
gitlab/utils.py
CHANGED
@@ -2,14 +2,26 @@ import dataclasses
|
|
2
2
|
import email.message
|
3
3
|
import logging
|
4
4
|
import pathlib
|
5
|
+
import time
|
5
6
|
import traceback
|
6
7
|
import urllib.parse
|
7
8
|
import warnings
|
8
|
-
from typing import
|
9
|
+
from typing import (
|
10
|
+
Any,
|
11
|
+
Callable,
|
12
|
+
Dict,
|
13
|
+
Iterator,
|
14
|
+
Literal,
|
15
|
+
MutableMapping,
|
16
|
+
Optional,
|
17
|
+
Tuple,
|
18
|
+
Type,
|
19
|
+
Union,
|
20
|
+
)
|
9
21
|
|
10
22
|
import requests
|
11
23
|
|
12
|
-
from gitlab import types
|
24
|
+
from gitlab import const, types
|
13
25
|
|
14
26
|
|
15
27
|
class _StdoutStream:
|
@@ -17,6 +29,18 @@ class _StdoutStream:
|
|
17
29
|
print(chunk)
|
18
30
|
|
19
31
|
|
32
|
+
def get_base_url(url: Optional[str] = None) -> str:
|
33
|
+
"""Return the base URL with the trailing slash stripped.
|
34
|
+
If the URL is a Falsy value, return the default URL.
|
35
|
+
Returns:
|
36
|
+
The base URL
|
37
|
+
"""
|
38
|
+
if not url:
|
39
|
+
return const.DEFAULT_URL
|
40
|
+
|
41
|
+
return url.rstrip("/")
|
42
|
+
|
43
|
+
|
20
44
|
def get_content_type(content_type: Optional[str]) -> str:
|
21
45
|
message = email.message.Message()
|
22
46
|
if content_type is not None:
|
@@ -73,6 +97,71 @@ def response_content(
|
|
73
97
|
return None
|
74
98
|
|
75
99
|
|
100
|
+
class Retry:
|
101
|
+
def __init__(
|
102
|
+
self,
|
103
|
+
max_retries: int,
|
104
|
+
obey_rate_limit: Optional[bool] = True,
|
105
|
+
retry_transient_errors: Optional[bool] = False,
|
106
|
+
) -> None:
|
107
|
+
self.cur_retries = 0
|
108
|
+
self.max_retries = max_retries
|
109
|
+
self.obey_rate_limit = obey_rate_limit
|
110
|
+
self.retry_transient_errors = retry_transient_errors
|
111
|
+
|
112
|
+
def _retryable_status_code(
|
113
|
+
self, status_code: Optional[int], reason: str = ""
|
114
|
+
) -> bool:
|
115
|
+
if status_code == 429 and self.obey_rate_limit:
|
116
|
+
return True
|
117
|
+
|
118
|
+
if not self.retry_transient_errors:
|
119
|
+
return False
|
120
|
+
if status_code in const.RETRYABLE_TRANSIENT_ERROR_CODES:
|
121
|
+
return True
|
122
|
+
if status_code == 409 and "Resource lock" in reason:
|
123
|
+
return True
|
124
|
+
|
125
|
+
return False
|
126
|
+
|
127
|
+
def handle_retry_on_status(
|
128
|
+
self,
|
129
|
+
status_code: Optional[int],
|
130
|
+
headers: Optional[MutableMapping[str, str]] = None,
|
131
|
+
reason: str = "",
|
132
|
+
) -> bool:
|
133
|
+
if not self._retryable_status_code(status_code, reason):
|
134
|
+
return False
|
135
|
+
|
136
|
+
if headers is None:
|
137
|
+
headers = {}
|
138
|
+
|
139
|
+
# Response headers documentation:
|
140
|
+
# https://docs.gitlab.com/ee/user/admin_area/settings/user_and_ip_rate_limits.html#response-headers
|
141
|
+
if self.max_retries == -1 or self.cur_retries < self.max_retries:
|
142
|
+
wait_time = 2**self.cur_retries * 0.1
|
143
|
+
if "Retry-After" in headers:
|
144
|
+
wait_time = int(headers["Retry-After"])
|
145
|
+
elif "RateLimit-Reset" in headers:
|
146
|
+
wait_time = int(headers["RateLimit-Reset"]) - time.time()
|
147
|
+
self.cur_retries += 1
|
148
|
+
time.sleep(wait_time)
|
149
|
+
return True
|
150
|
+
|
151
|
+
return False
|
152
|
+
|
153
|
+
def handle_retry(self) -> bool:
|
154
|
+
if self.retry_transient_errors and (
|
155
|
+
self.max_retries == -1 or self.cur_retries < self.max_retries
|
156
|
+
):
|
157
|
+
wait_time = 2**self.cur_retries * 0.1
|
158
|
+
self.cur_retries += 1
|
159
|
+
time.sleep(wait_time)
|
160
|
+
return True
|
161
|
+
|
162
|
+
return False
|
163
|
+
|
164
|
+
|
76
165
|
def _transform_types(
|
77
166
|
data: Dict[str, Any],
|
78
167
|
custom_types: Dict[str, Any],
|
gitlab/v4/objects/members.py
CHANGED
@@ -37,8 +37,9 @@ class GroupMemberManager(CRUDMixin, RESTManager):
|
|
37
37
|
_obj_cls = GroupMember
|
38
38
|
_from_parent_attrs = {"group_id": "id"}
|
39
39
|
_create_attrs = RequiredOptional(
|
40
|
-
required=("access_level",
|
40
|
+
required=("access_level",),
|
41
41
|
optional=("expires_at", "tasks_to_be_done"),
|
42
|
+
exclusive=("username", "user_id"),
|
42
43
|
)
|
43
44
|
_update_attrs = RequiredOptional(
|
44
45
|
required=("access_level",), optional=("expires_at",)
|
@@ -101,8 +102,9 @@ class ProjectMemberManager(CRUDMixin, RESTManager):
|
|
101
102
|
_obj_cls = ProjectMember
|
102
103
|
_from_parent_attrs = {"project_id": "id"}
|
103
104
|
_create_attrs = RequiredOptional(
|
104
|
-
required=("access_level",
|
105
|
+
required=("access_level",),
|
105
106
|
optional=("expires_at", "tasks_to_be_done"),
|
107
|
+
exclusive=("username", "user_id"),
|
106
108
|
)
|
107
109
|
_update_attrs = RequiredOptional(
|
108
110
|
required=("access_level",), optional=("expires_at",)
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: python-gitlab
|
3
|
-
Version: 4.
|
3
|
+
Version: 4.11.1
|
4
4
|
Summary: A python wrapper for the GitLab API
|
5
5
|
Author-email: Gauvain Pocentek <gauvain@pocentek.net>
|
6
6
|
Maintainer-email: John Villalovos <john@sodarock.com>, Max Wittig <max.wittig@siemens.com>, Nejc Habjan <nejc.habjan@siemens.com>, Roger Meier <r.meier@siemens.com>
|
@@ -32,6 +32,8 @@ Requires-Dist: requests >=2.32.0
|
|
32
32
|
Requires-Dist: requests-toolbelt >=1.0.0
|
33
33
|
Provides-Extra: autocompletion
|
34
34
|
Requires-Dist: argcomplete <3,>=1.10.0 ; extra == 'autocompletion'
|
35
|
+
Provides-Extra: graphql
|
36
|
+
Requires-Dist: gql[httpx] <4,>=3.5.0 ; extra == 'graphql'
|
35
37
|
Provides-Extra: yaml
|
36
38
|
Requires-Dist: PyYaml >=6.0.1 ; extra == 'yaml'
|
37
39
|
|
@@ -1,17 +1,18 @@
|
|
1
|
-
gitlab/__init__.py,sha256=
|
1
|
+
gitlab/__init__.py,sha256=DlY_IEbIbeTJnMfkcl4866XbJ_50UiaE4yI0PwOq36E,1406
|
2
2
|
gitlab/__main__.py,sha256=HTesNl0UAU6mPb9EXWkTKMy6Q6pAUxGi3iPnDHTE2uE,68
|
3
|
-
gitlab/_version.py,sha256=
|
3
|
+
gitlab/_version.py,sha256=3A0MvnWrTCInQYk_lrq1rViL2qGa7xznDd8PugfxA9Y,250
|
4
4
|
gitlab/base.py,sha256=5cotawlHD01Vw88aN4o7wNIhDyk_bmcwubX4mbOpnVo,13780
|
5
5
|
gitlab/cli.py,sha256=d3-LtZuA1Fgon5wZWn4c3E70fTIu4mM4Juyhh3F8EBs,12416
|
6
|
-
gitlab/client.py,sha256=
|
6
|
+
gitlab/client.py,sha256=WK13AV69dJg-5dWIcYV51_ylExuZolrCGXSLHT1vDkU,51217
|
7
7
|
gitlab/config.py,sha256=T1DgUXD0-MN2qNszrv-SO5d4uy0FITnNN0vWJgOt2yo,9088
|
8
8
|
gitlab/const.py,sha256=rtPU-fxVSOvgpueoQVTvZGQp6iAZ-aa3nsY4RcSs_M4,5352
|
9
9
|
gitlab/exceptions.py,sha256=VOQftPzEq5mpVj6vke7z6Xe4S7Yf_rDTab0lNHqf3AY,8390
|
10
10
|
gitlab/mixins.py,sha256=7iPlzqGmd5Ew2RLzRzRWsJ4r8Bn6wteUj791BJrjtXc,36645
|
11
11
|
gitlab/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
12
12
|
gitlab/types.py,sha256=lepiiI_YOr94B4koqIHuY70tszZC_X3YW4lDvbadbI8,3312
|
13
|
-
gitlab/utils.py,sha256=
|
13
|
+
gitlab/utils.py,sha256=3OngV45Gb4UO2GR-6-kXax1Ghdw6bpyRdUC2cHpyCSw,9027
|
14
14
|
gitlab/_backends/__init__.py,sha256=WalQZRIDzw19FuNxraG7fvck6ddg4cdNd3bi53QKvZM,392
|
15
|
+
gitlab/_backends/graphql.py,sha256=SiGEfqqBqRey_EhozhF1pWFO81c_VVKdM50XvCQ4PZc,737
|
15
16
|
gitlab/_backends/protocol.py,sha256=m5qSz1o3i0H4XJCWnqx0wIFilOIU9cKxzFsYxLL6Big,842
|
16
17
|
gitlab/_backends/requests_backend.py,sha256=CrSDTfkvi17dT4kTU8R3qQFBNCPJqEfBJq4gJ2GXleA,5534
|
17
18
|
gitlab/v4/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -58,7 +59,7 @@ gitlab/v4/objects/jobs.py,sha256=g7l5dA6-99tyLDoohjJ_xZvGyMbeytn4L9T-h78NQaE,914
|
|
58
59
|
gitlab/v4/objects/keys.py,sha256=IclYGSzcVEZPIhDdIz-p16rvb68FnBTgAf1cWCXWjkY,882
|
59
60
|
gitlab/v4/objects/labels.py,sha256=JvOciJ6V76pF9HuJp5OT_Ykq8oqaa6ItxvpKf3hiEzs,4736
|
60
61
|
gitlab/v4/objects/ldap.py,sha256=adpkdfk7VBjshuh8SpCsc77Pax4QgqCx1N12CuzitDE,1662
|
61
|
-
gitlab/v4/objects/members.py,sha256=
|
62
|
+
gitlab/v4/objects/members.py,sha256=YJO9MaqlCSUnozHIlI7MfSlcWTju4xRmW8QIlEiBmok,3902
|
62
63
|
gitlab/v4/objects/merge_request_approvals.py,sha256=oPZFd4AUtrAVhBTa0iM4krNkk2UTNOTw_MWlEWo2HAQ,6400
|
63
64
|
gitlab/v4/objects/merge_requests.py,sha256=tpFCMmTVWyL9X7HtUoZuHJP4MVZUz1kk9-Bv-SbnwfU,17422
|
64
65
|
gitlab/v4/objects/merge_trains.py,sha256=e0Gp2Ri75elcG_r9w8qxdrcWW_YiebPRwUYIH5od8kc,422
|
@@ -94,10 +95,10 @@ gitlab/v4/objects/triggers.py,sha256=UAERq_C-QdPBbBQPHLh5IfhpkdDeIxdnVGPHfu9Qy5Y
|
|
94
95
|
gitlab/v4/objects/users.py,sha256=_gGrTwcE17jeoXIPgfFSv54jtF1_9C1R0Y0hhssTvXY,21381
|
95
96
|
gitlab/v4/objects/variables.py,sha256=S0Vz32jEpUbo4J2js8gMPPTVpcy1ge5FYVHLiPz9c-A,2627
|
96
97
|
gitlab/v4/objects/wikis.py,sha256=JtI1cQqZV1_PRfKVlQRMh4LZjdxEfi9T2VuFYv6PrV8,1775
|
97
|
-
python_gitlab-4.
|
98
|
-
python_gitlab-4.
|
99
|
-
python_gitlab-4.
|
100
|
-
python_gitlab-4.
|
101
|
-
python_gitlab-4.
|
102
|
-
python_gitlab-4.
|
103
|
-
python_gitlab-4.
|
98
|
+
python_gitlab-4.11.1.dist-info/AUTHORS,sha256=Z0P61GJSVnp7iFbRcMezhx3f4zMyPkVmG--TWaRo768,526
|
99
|
+
python_gitlab-4.11.1.dist-info/COPYING,sha256=2n6rt7r999OuXp8iOqW9we7ORaxWncIbOwN1ILRGR2g,7651
|
100
|
+
python_gitlab-4.11.1.dist-info/METADATA,sha256=wCr5WsVuHR7d3SeMIdAu3HuzRXXjniEYb8LoBJGxyoI,8311
|
101
|
+
python_gitlab-4.11.1.dist-info/WHEEL,sha256=cVxcB9AmuTcXqmwrtPhNK88dr7IR_b6qagTj0UvIEbY,91
|
102
|
+
python_gitlab-4.11.1.dist-info/entry_points.txt,sha256=nhpKLLP_uQPFByn8UtE9zsvQQwa402t52o_Cw9IFXMo,43
|
103
|
+
python_gitlab-4.11.1.dist-info/top_level.txt,sha256=MvIaP8p_Oaf4gO_hXmHkX-5y2deHLp1pe6tJR3ukQ6o,7
|
104
|
+
python_gitlab-4.11.1.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|