Skip to content

Commit a8c95c8

Browse files
committed
refactor: move response_content into backend code
1 parent 02a551d commit a8c95c8

14 files changed

+96
-70
lines changed

gitlab/_backends/protocol.py

+12-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import abc
22
import sys
3-
from typing import Any, Dict, Optional, Union
3+
from typing import Any, Callable, Dict, Iterator, Optional, Union
44

55
import requests
66
from requests_toolbelt.multipart.encoder import MultipartEncoder # type: ignore
@@ -17,6 +17,17 @@ def __init__(self, response: requests.Response) -> None: ...
1717

1818

1919
class Backend(Protocol):
20+
@staticmethod
21+
@abc.abstractmethod
22+
def response_content(
23+
response: requests.Response,
24+
streamed: bool,
25+
action: Optional[Callable[[bytes], None]],
26+
chunk_size: int,
27+
*,
28+
iterator: bool,
29+
) -> Optional[Union[bytes, Iterator[Any]]]: ...
30+
2031
@abc.abstractmethod
2132
def http_request(
2233
self,

gitlab/_backends/requests_backend.py

+38-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,16 @@
11
from __future__ import annotations
22

33
import dataclasses
4-
from typing import Any, BinaryIO, Dict, Optional, TYPE_CHECKING, Union
4+
from typing import (
5+
Any,
6+
BinaryIO,
7+
Callable,
8+
Dict,
9+
Iterator,
10+
Optional,
11+
TYPE_CHECKING,
12+
Union,
13+
)
514

615
import requests
716
from requests import PreparedRequest
@@ -55,6 +64,11 @@ def __post_init__(self) -> None:
5564
)
5665

5766

67+
class _StdoutStream:
68+
def __call__(self, chunk: Any) -> None:
69+
print(chunk)
70+
71+
5872
class RequestsResponse(protocol.BackendResponse):
5973
def __init__(self, response: requests.Response) -> None:
6074
self._response: requests.Response = response
@@ -126,6 +140,29 @@ def prepare_send_data(
126140

127141
return SendData(json=post_data, content_type="application/json")
128142

143+
@staticmethod
144+
def response_content(
145+
response: requests.Response,
146+
streamed: bool,
147+
action: Optional[Callable[[bytes], None]],
148+
chunk_size: int,
149+
*,
150+
iterator: bool,
151+
) -> Optional[Union[bytes, Iterator[Any]]]:
152+
if iterator:
153+
return response.iter_content(chunk_size=chunk_size)
154+
155+
if streamed is False:
156+
return response.content
157+
158+
if action is None:
159+
action = _StdoutStream()
160+
161+
for chunk in response.iter_content(chunk_size=chunk_size):
162+
if chunk:
163+
action(chunk)
164+
return None
165+
129166
def http_request(
130167
self,
131168
method: str,

gitlab/mixins.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -649,7 +649,7 @@ def download(
649649
)
650650
if TYPE_CHECKING:
651651
assert isinstance(result, requests.Response)
652-
return utils.response_content(
652+
return self.manager.gitlab._backend.response_content(
653653
result, streamed, action, chunk_size, iterator=iterator
654654
)
655655

gitlab/utils.py

+9-28
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,9 @@
44
import traceback
55
import urllib.parse
66
import warnings
7-
from typing import Any, Callable, Dict, Iterator, Literal, Optional, Tuple, Type, Union
7+
from typing import Any, Dict, Iterator, Literal, Optional, Tuple, Type, Union
88

9-
import requests
10-
11-
from gitlab import types
12-
13-
14-
class _StdoutStream:
15-
def __call__(self, chunk: Any) -> None:
16-
print(chunk)
9+
from gitlab import _backends, types
1710

1811

1912
def get_content_type(content_type: Optional[str]) -> str:
@@ -50,26 +43,14 @@ def format(self, record: logging.LogRecord) -> str:
5043

5144

5245
def response_content(
53-
response: requests.Response,
54-
streamed: bool,
55-
action: Optional[Callable[[bytes], None]],
56-
chunk_size: int,
57-
*,
58-
iterator: bool,
46+
*args: Any, **kwargs: Any
5947
) -> Optional[Union[bytes, Iterator[Any]]]:
60-
if iterator:
61-
return response.iter_content(chunk_size=chunk_size)
62-
63-
if streamed is False:
64-
return response.content
65-
66-
if action is None:
67-
action = _StdoutStream()
68-
69-
for chunk in response.iter_content(chunk_size=chunk_size):
70-
if chunk:
71-
action(chunk)
72-
return None
48+
warn(
49+
"`utils.response_content()` is deprecated and will be removed in a future"
50+
"version.\nUse the current backend's `response_content()` method instead.",
51+
category=DeprecationWarning,
52+
)
53+
return _backends.DefaultBackend.response_content(*args, **kwargs)
7354

7455

7556
def _transform_types(

gitlab/v4/objects/artifacts.py

+2-3
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99

1010
from gitlab import cli
1111
from gitlab import exceptions as exc
12-
from gitlab import utils
1312
from gitlab.base import RESTManager, RESTObject
1413

1514
__all__ = ["ProjectArtifact", "ProjectArtifactManager"]
@@ -90,7 +89,7 @@ def download(
9089
)
9190
if TYPE_CHECKING:
9291
assert isinstance(result, requests.Response)
93-
return utils.response_content(
92+
return self.gitlab._backend.response_content(
9493
result, streamed, action, chunk_size, iterator=iterator
9594
)
9695

@@ -142,6 +141,6 @@ def raw(
142141
)
143142
if TYPE_CHECKING:
144143
assert isinstance(result, requests.Response)
145-
return utils.response_content(
144+
return self.gitlab._backend.response_content(
146145
result, streamed, action, chunk_size, iterator=iterator
147146
)

gitlab/v4/objects/files.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -272,7 +272,7 @@ def raw(
272272
)
273273
if TYPE_CHECKING:
274274
assert isinstance(result, requests.Response)
275-
return utils.response_content(
275+
return self.gitlab._backend.response_content(
276276
result, streamed, action, chunk_size, iterator=iterator
277277
)
278278

gitlab/v4/objects/jobs.py

+3-4
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44

55
from gitlab import cli
66
from gitlab import exceptions as exc
7-
from gitlab import utils
87
from gitlab.base import RESTManager, RESTObject
98
from gitlab.mixins import RefreshMixin, RetrieveMixin
109
from gitlab.types import ArrayAttribute
@@ -152,7 +151,7 @@ def artifacts(
152151
)
153152
if TYPE_CHECKING:
154153
assert isinstance(result, requests.Response)
155-
return utils.response_content(
154+
return self.manager.gitlab._backend.response_content(
156155
result, streamed, action, chunk_size, iterator=iterator
157156
)
158157

@@ -195,7 +194,7 @@ def artifact(
195194
)
196195
if TYPE_CHECKING:
197196
assert isinstance(result, requests.Response)
198-
return utils.response_content(
197+
return self.manager.gitlab._backend.response_content(
199198
result, streamed, action, chunk_size, iterator=iterator
200199
)
201200

@@ -236,7 +235,7 @@ def trace(
236235
)
237236
if TYPE_CHECKING:
238237
assert isinstance(result, requests.Response)
239-
return utils.response_content(
238+
return self.manager.gitlab._backend.response_content(
240239
result, streamed, action, chunk_size, iterator=iterator
241240
)
242241

gitlab/v4/objects/packages.py

+1-2
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020

2121
from gitlab import cli
2222
from gitlab import exceptions as exc
23-
from gitlab import utils
2423
from gitlab.base import RESTManager, RESTObject
2524
from gitlab.mixins import DeleteMixin, GetMixin, ListMixin, ObjectDeleteMixin
2625

@@ -166,7 +165,7 @@ def download(
166165
result = self.gitlab.http_get(path, streamed=streamed, raw=True, **kwargs)
167166
if TYPE_CHECKING:
168167
assert isinstance(result, requests.Response)
169-
return utils.response_content(
168+
return self.gitlab._backend.response_content(
170169
result, streamed, action, chunk_size, iterator=iterator
171170
)
172171

gitlab/v4/objects/projects.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -499,7 +499,7 @@ def snapshot(
499499
)
500500
if TYPE_CHECKING:
501501
assert isinstance(result, requests.Response)
502-
return utils.response_content(
502+
return self.manager.gitlab._backend.response_content(
503503
result, streamed, action, chunk_size, iterator=iterator
504504
)
505505

gitlab/v4/objects/repositories.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ def repository_raw_blob(
145145
)
146146
if TYPE_CHECKING:
147147
assert isinstance(result, requests.Response)
148-
return utils.response_content(
148+
return self.manager.gitlab._backend.response_content(
149149
result, streamed, action, chunk_size, iterator=iterator
150150
)
151151

@@ -247,7 +247,7 @@ def repository_archive(
247247
)
248248
if TYPE_CHECKING:
249249
assert isinstance(result, requests.Response)
250-
return utils.response_content(
250+
return self.manager.gitlab._backend.response_content(
251251
result, streamed, action, chunk_size, iterator=iterator
252252
)
253253

gitlab/v4/objects/secure_files.py

+1-2
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99

1010
from gitlab import cli
1111
from gitlab import exceptions as exc
12-
from gitlab import utils
1312
from gitlab.base import RESTManager, RESTObject
1413
from gitlab.mixins import NoUpdateMixin, ObjectDeleteMixin
1514
from gitlab.types import FileAttribute, RequiredOptional
@@ -54,7 +53,7 @@ def download(
5453
)
5554
if TYPE_CHECKING:
5655
assert isinstance(result, requests.Response)
57-
return utils.response_content(
56+
return self.manager.gitlab._backend.response_content(
5857
result, streamed, action, chunk_size, iterator=iterator
5958
)
6059

gitlab/v4/objects/snippets.py

+2-3
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44

55
from gitlab import cli
66
from gitlab import exceptions as exc
7-
from gitlab import utils
87
from gitlab.base import RESTManager, RESTObject, RESTObjectList
98
from gitlab.mixins import CRUDMixin, ObjectDeleteMixin, SaveMixin, UserAgentDetailMixin
109
from gitlab.types import RequiredOptional
@@ -61,7 +60,7 @@ def content(
6160
)
6261
if TYPE_CHECKING:
6362
assert isinstance(result, requests.Response)
64-
return utils.response_content(
63+
return self.manager.gitlab._backend.response_content(
6564
result, streamed, action, chunk_size, iterator=iterator
6665
)
6766

@@ -154,7 +153,7 @@ def content(
154153
)
155154
if TYPE_CHECKING:
156155
assert isinstance(result, requests.Response)
157-
return utils.response_content(
156+
return self.manager.gitlab._backend.response_content(
158157
result, streamed, action, chunk_size, iterator=iterator
159158
)
160159

tests/unit/test_backends.py

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import requests
2+
import responses
3+
4+
from gitlab import _backends
5+
6+
7+
@responses.activate
8+
def test_streamed_response_content_with_requests(capsys):
9+
responses.add(
10+
method="GET",
11+
url="https://example.com",
12+
status=200,
13+
body="test",
14+
content_type="application/octet-stream",
15+
)
16+
17+
resp = requests.get("https://example.com", stream=True)
18+
_backends.RequestsBackend.response_content(
19+
resp, streamed=True, action=None, chunk_size=1024, iterator=False
20+
)
21+
22+
captured = capsys.readouterr()
23+
assert "test" in captured.out

tests/unit/test_utils.py

-21
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@
33
import warnings
44

55
import pytest
6-
import requests
7-
import responses
86

97
from gitlab import types, utils
108

@@ -23,25 +21,6 @@ def test_get_content_type(content_type, expected_type):
2321
assert parsed_type == expected_type
2422

2523

26-
@responses.activate
27-
def test_response_content(capsys):
28-
responses.add(
29-
method="GET",
30-
url="https://example.com",
31-
status=200,
32-
body="test",
33-
content_type="application/octet-stream",
34-
)
35-
36-
resp = requests.get("https://example.com", stream=True)
37-
utils.response_content(
38-
resp, streamed=True, action=None, chunk_size=1024, iterator=False
39-
)
40-
41-
captured = capsys.readouterr()
42-
assert "test" in captured.out
43-
44-
4524
class TestEncodedId:
4625
def test_init_str(self):
4726
obj = utils.EncodedId("Hello")

0 commit comments

Comments
 (0)