Skip to content

Commit 9db988a

Browse files
author
Liora Milbaum
committed
feat: Initial support for httpx
1 parent eec6c02 commit 9db988a

8 files changed

+74
-17
lines changed

.pre-commit-config.yaml

+3-1
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,10 @@ repos:
2323
rev: v2.15.4
2424
hooks:
2525
- id: pylint
26-
additional_dependencies:
26+
additional_dependencies:
2727
- argcomplete==2.0.0
2828
- pytest==7.1.3
29+
- httpx==0.23.0
2930
- requests==2.28.1
3031
- requests-toolbelt==0.9.1
3132
files: 'gitlab/'
@@ -35,6 +36,7 @@ repos:
3536
- id: mypy
3637
args: []
3738
additional_dependencies:
39+
- httpx==0.23.0
3840
- types-PyYAML==6.0.12
3941
- types-requests==2.28.11.2
4042
- types-setuptools==64.0.1

gitlab/client.py

+30-11
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,12 @@
22

33
import os
44
import re
5+
import sys
56
import time
67
from typing import Any, cast, Dict, List, Optional, Tuple, TYPE_CHECKING, Union
78
from urllib import parse
89

10+
import httpx
911
import requests
1012
import requests.utils
1113
from requests_toolbelt.multipart.encoder import MultipartEncoder # type: ignore
@@ -16,6 +18,14 @@
1618
import gitlab.exceptions
1719
from gitlab import utils
1820

21+
from .clients._httpxclient import _HttpxClient
22+
from .clients._requestsclient import _RequestsClient
23+
24+
if sys.version_info >= (3, 8):
25+
from typing import Literal
26+
else:
27+
from typing_extensions import Literal
28+
1929
REDIRECT_MSG = (
2030
"python-gitlab detected a {status_code} ({reason!r}) redirection. You must update "
2131
"your GitLab URL to the correct URL to avoid issues. The redirection was from: "
@@ -66,7 +76,9 @@ def __init__(
6676
http_password: Optional[str] = None,
6777
timeout: Optional[float] = None,
6878
api_version: str = "4",
79+
http: Optional[Literal["requests", "httpx"]] = "requests",
6980
session: Optional[requests.Session] = None,
81+
client: Optional[httpx.Client] = None,
7082
per_page: Optional[int] = None,
7183
pagination: Optional[str] = None,
7284
order_by: Optional[str] = None,
@@ -75,7 +87,21 @@ def __init__(
7587
keep_base_url: bool = False,
7688
) -> None:
7789

90+
# We only support v4 API at this time
91+
if api_version not in ("4",):
92+
raise ModuleNotFoundError(f"gitlab.v{api_version}.objects")
93+
# NOTE: We must delay import of gitlab.v4.objects until now or
94+
# otherwise it will cause circular import errors
95+
from gitlab.v4 import objects
96+
7897
self._api_version = str(api_version)
98+
99+
if http == "requests":
100+
self._requests_client = _RequestsClient(session=session)
101+
self.session = self._requests_client.get_session
102+
elif http == "httpx":
103+
self._httpx_client = _HttpxClient(client=client)
104+
79105
self._server_version: Optional[str] = None
80106
self._server_revision: Optional[str] = None
81107
self._base_url = self._get_base_url(url)
@@ -97,20 +123,10 @@ def __init__(
97123
self.job_token = job_token
98124
self._set_auth_info()
99125

100-
#: Create a session object for requests
101-
self.session = session or requests.Session()
102-
103126
self.per_page = per_page
104127
self.pagination = pagination
105128
self.order_by = order_by
106129

107-
# We only support v4 API at this time
108-
if self._api_version not in ("4",):
109-
raise ModuleNotFoundError(f"gitlab.v{self._api_version}.objects")
110-
# NOTE: We must delay import of gitlab.v4.objects until now or
111-
# otherwise it will cause circular import errors
112-
from gitlab.v4 import objects
113-
114130
self._objects = objects
115131
self.user: Optional[objects.CurrentUser] = None
116132

@@ -193,7 +209,10 @@ def __enter__(self) -> "Gitlab":
193209
return self
194210

195211
def __exit__(self, *args: Any) -> None:
196-
self.session.close()
212+
if self._requests_client:
213+
self._requests_client.close()
214+
elif self._httpx_client:
215+
self._httpx_client.close()
197216

198217
def __getstate__(self) -> Dict[str, Any]:
199218
state = self.__dict__.copy()

gitlab/clients/__init__.py

Whitespace-only changes.

gitlab/clients/_httpxclient.py

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
from typing import Optional
2+
3+
import httpx
4+
5+
6+
class _HttpxClient:
7+
def __init__(
8+
self,
9+
client: Optional[httpx.Client] = None,
10+
) -> None:
11+
self._client = client or httpx.Client()
12+
13+
def close(self) -> None:
14+
self._client.close()

gitlab/clients/_requestsclient.py

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
from typing import Optional
2+
3+
import requests
4+
5+
6+
class _RequestsClient:
7+
def __init__(
8+
self,
9+
session: Optional[requests.Session] = None,
10+
) -> None:
11+
self._session = session or requests.Session()
12+
13+
@property
14+
def get_session(self) -> requests.Session:
15+
return self._session
16+
17+
def close(self) -> None:
18+
self._session.close()

requirements.txt

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
1-
requests==2.28.1
1+
httpx==0.23.0
22
requests-toolbelt==0.10.0
3+
requests==2.28.1

setup.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ def get_version() -> str:
2828
license="LGPLv3",
2929
url="https://github.com/python-gitlab/python-gitlab",
3030
packages=find_packages(exclude=["docs*", "tests*"]),
31-
install_requires=["requests>=2.25.0", "requests-toolbelt>=0.9.1"],
31+
install_requires=["requests>=2.25.0", "requests-toolbelt>=0.9.1", "httpx==0.23.0"],
3232
package_data={
3333
"gitlab": ["py.typed"],
3434
},

tox.ini

+6-3
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,8 @@ commands =
4343
[testenv:mypy]
4444
basepython = python3
4545
envdir={toxworkdir}/lint
46-
deps = -r{toxinidir}/requirements-lint.txt
46+
deps = -r requirements.txt
47+
-r requirements-lint.txt
4748
commands =
4849
mypy {posargs}
4950

@@ -57,7 +58,8 @@ commands =
5758
[testenv:pylint]
5859
basepython = python3
5960
envdir={toxworkdir}/lint
60-
deps = -r{toxinidir}/requirements-lint.txt
61+
deps = -r requirements.txt
62+
-r requirements-lint.txt
6163
commands =
6264
pylint {posargs} gitlab/
6365

@@ -121,7 +123,8 @@ commands =
121123
pytest --cov --cov-report xml tests/functional/api {posargs}
122124

123125
[testenv:smoke]
124-
deps = -r{toxinidir}/requirements-test.txt
126+
deps = -r requirements.txt
127+
-r requirements-test.txt
125128
commands = pytest tests/smoke {posargs}
126129

127130
[testenv:pre-commit]

0 commit comments

Comments
 (0)