Skip to content

Commit 60ea230

Browse files
committed
When chunk_size=None, Response.(a)iter_bytes returns data as it arrives in whatever size the chunks are received (#394)
1 parent eb3ea9e commit 60ea230

File tree

2 files changed

+22
-8
lines changed

2 files changed

+22
-8
lines changed

httpx/_models.py

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -915,12 +915,17 @@ def read(self) -> bytes:
915915
self._content = b"".join(self.iter_bytes())
916916
return self._content
917917

918-
def iter_bytes(self, chunk_size: int = 512) -> typing.Iterator[bytes]:
918+
def iter_bytes(
919+
self, chunk_size: typing.Optional[int] = 512
920+
) -> typing.Iterator[bytes]:
919921
"""
920922
A byte-iterator over the decoded response content.
921923
This allows us to handle gzip, deflate, and brotli encoded responses.
922924
"""
923-
yield from drain_by_chunks(self.__iter_bytes(), chunk_size)
925+
if chunk_size is None:
926+
yield from self.__iter_bytes()
927+
else:
928+
yield from drain_by_chunks(self.__iter_bytes(), chunk_size)
924929

925930
def __iter_bytes(self) -> typing.Iterator[bytes]:
926931
if hasattr(self, "_content"):
@@ -1001,12 +1006,19 @@ async def aread(self) -> bytes:
10011006
self._content = b"".join([part async for part in self.aiter_bytes()])
10021007
return self._content
10031008

1004-
async def aiter_bytes(self, chunk_size: int = 512) -> typing.AsyncIterator[bytes]:
1009+
async def aiter_bytes(
1010+
self, chunk_size: typing.Optional[int] = 512
1011+
) -> typing.AsyncIterator[bytes]:
10051012
"""
10061013
A byte-iterator over the decoded response content.
10071014
This allows us to handle gzip, deflate, and brotli encoded responses.
10081015
"""
1009-
async for chunk in async_drain_by_chunks(self.__aiter_bytes(), chunk_size):
1016+
if chunk_size is None:
1017+
aiterator = self.__aiter_bytes()
1018+
else:
1019+
aiterator = async_drain_by_chunks(self.__aiter_bytes(), chunk_size)
1020+
1021+
async for chunk in aiterator:
10101022
yield chunk
10111023

10121024
async def __aiter_bytes(self) -> typing.AsyncIterator[bytes]:

tests/models/test_responses.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -270,27 +270,29 @@ async def test_aiter_raw_increments_updates_counter():
270270
num_downloaded = response.num_bytes_downloaded
271271

272272

273-
def test_iter_bytes():
273+
@pytest.mark.parametrize("chunk_size", [2, 20, None])
274+
def test_iter_bytes(chunk_size):
274275
response = httpx.Response(
275276
200,
276277
content=b"Hello, world!",
277278
)
278279

279280
content = b""
280-
for part in response.iter_bytes():
281+
for part in response.iter_bytes(chunk_size):
281282
content += part
282283
assert content == b"Hello, world!"
283284

284285

285286
@pytest.mark.asyncio
286-
async def test_aiter_bytes():
287+
@pytest.mark.parametrize("chunk_size", [2, 20, None])
288+
async def test_aiter_bytes(chunk_size):
287289
response = httpx.Response(
288290
200,
289291
content=b"Hello, world!",
290292
)
291293

292294
content = b""
293-
async for part in response.aiter_bytes():
295+
async for part in response.aiter_bytes(chunk_size):
294296
content += part
295297
assert content == b"Hello, world!"
296298

0 commit comments

Comments
 (0)