Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions docs/compatibility.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,10 @@ async with request.stream("GET", "https://www.example.com") as response:

Within a `stream()` block request data is made available with:

* `.stream_bytes()` - Instead of `response.iter_content()`
* `.stream_text()` - Instead of `response.iter_content(decode_unicode=True)`
* `.stream_lines()` - Instead of `response.iter_lines()`
* `.stream_raw()` - Use this instead of `response.raw`
* `.aiter_bytes()` - Instead of `response.iter_content()`
* `.aiter_text()` - Instead of `response.iter_content(decode_unicode=True)`
* `.aiter_lines()` - Instead of `response.iter_lines()`
* `.aiter_raw()` - Use this instead of `response.raw`
* `.read()` - Read the entire response body, making `request.text` and `response.content` available.

## SSL configuration
Expand Down
8 changes: 4 additions & 4 deletions docs/quickstart.md
Original file line number Diff line number Diff line change
Expand Up @@ -304,23 +304,23 @@ You can stream the binary content of the response...

```
>>> async with httpx.stream("GET", "https://www.example.com") as r:
... async for data in r.stream_bytes():
... async for data in r.aiter_bytes():
... print(data)
```

Or the text of the response...

```
>>> async with httpx.stream("GET", "https://www.example.com") as r:
... async for text in r.stream_text():
... async for text in r.aiter_text():
... print(text)
```

Or stream the text, on a line-by-line basis...

```
>>> async with httpx.stream("GET", "https://www.example.com") as r:
... async for line in r.stream_lines():
... async for line in r.aiter_lines():
... print(line)
```

Expand All @@ -330,7 +330,7 @@ In some cases you might want to access the raw bytes on the response without app

```
>>> async with httpx.stream("GET", "https://www.example.com") as r:
... async for chunk in r.stream_raw():
... async for chunk in r.aiter_raw():
... print(chunk)
```

Expand Down
24 changes: 12 additions & 12 deletions httpx/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -919,57 +919,57 @@ async def read(self) -> bytes:
Read and return the response content.
"""
if not hasattr(self, "_content"):
self._content = b"".join([part async for part in self.stream_bytes()])
self._content = b"".join([part async for part in self.aiter_bytes()])
return self._content

@property
def stream(self): # type: ignore
warnings.warn(
"Response.stream() is due to be deprecated. "
"Use Response.stream_bytes() instead."
"Use Response.aiter_bytes() instead."
)
return self.stream_bytes
return self.aiter_bytes

@property
def raw(self): # type: ignore
warnings.warn(
"Response.raw() is due to be deprecated. "
"Use Response.stream_raw() instead."
"Use Response.aiter_raw() instead."
)
return self.stream_raw
return self.aiter_raw

async def stream_bytes(self) -> typing.AsyncIterator[bytes]:
async def aiter_bytes(self) -> typing.AsyncIterator[bytes]:
"""
A byte-iterator over the decoded response content.
This allows us to handle gzip, deflate, and brotli encoded responses.
"""
if hasattr(self, "_content"):
yield self._content
else:
async for chunk in self.stream_raw():
async for chunk in self.aiter_raw():
yield self.decoder.decode(chunk)
yield self.decoder.flush()

async def stream_text(self) -> typing.AsyncIterator[str]:
async def aiter_text(self) -> typing.AsyncIterator[str]:
"""
A str-iterator over the decoded response content
that handles both gzip, deflate, etc but also detects the content's
string encoding.
"""
decoder = TextDecoder(encoding=self.charset_encoding)
async for chunk in self.stream_bytes():
async for chunk in self.aiter_bytes():
yield decoder.decode(chunk)
yield decoder.flush()

async def stream_lines(self) -> typing.AsyncIterator[str]:
async def aiter_lines(self) -> typing.AsyncIterator[str]:
decoder = LineDecoder()
async for text in self.stream_text():
async for text in self.aiter_text():
for line in decoder.decode(text):
yield line
for line in decoder.flush():
yield line

async def stream_raw(self) -> typing.AsyncIterator[bytes]:
async def aiter_raw(self) -> typing.AsyncIterator[bytes]:
"""
A byte-iterator over the raw response content.
"""
Expand Down
4 changes: 2 additions & 2 deletions tests/client/test_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ async def test_stream_iterator(server):

async with httpx.Client() as client:
async with client.stream("GET", server.url) as response:
async for chunk in response.stream_bytes():
async for chunk in response.aiter_bytes():
body += chunk

assert response.status_code == 200
Expand All @@ -84,7 +84,7 @@ async def test_raw_iterator(server):

async with httpx.Client() as client:
async with client.stream("GET", server.url) as response:
async for chunk in response.stream_raw():
async for chunk in response.aiter_raw():
body += chunk

assert response.status_code == 200
Expand Down
18 changes: 9 additions & 9 deletions tests/models/test_responses.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,41 +137,41 @@ async def test_raw_interface():
response = httpx.Response(200, content=b"Hello, world!")

raw = b""
async for part in response.stream_raw():
async for part in response.aiter_raw():
raw += part
assert raw == b"Hello, world!"


@pytest.mark.asyncio
async def test_stream_interface():
async def test_bytes_interface():
response = httpx.Response(200, content=b"Hello, world!")

content = b""
async for part in response.stream_bytes():
async for part in response.aiter_bytes():
content += part
assert content == b"Hello, world!"


@pytest.mark.asyncio
async def test_stream_text():
async def test_text_interface():
response = httpx.Response(200, content=b"Hello, world!")

await response.read()

content = ""
async for part in response.stream_text():
async for part in response.aiter_text():
content += part
assert content == "Hello, world!"


@pytest.mark.asyncio
async def test_stream_lines():
async def test_lines_interface():
response = httpx.Response(200, content=b"Hello,\nworld!")

await response.read()

content = []
async for line in response.stream_lines():
async for line in response.aiter_lines():
content.append(line)
assert content == ["Hello,\n", "world!"]

Expand All @@ -183,7 +183,7 @@ async def test_stream_interface_after_read():
await response.read()

content = b""
async for part in response.stream_bytes():
async for part in response.aiter_bytes():
content += part
assert content == b"Hello, world!"

Expand All @@ -207,7 +207,7 @@ async def test_cannot_read_after_stream_consumed():
response = httpx.Response(200, content=async_streaming_body())

content = b""
async for part in response.stream_bytes():
async for part in response.aiter_bytes():
content += part

with pytest.raises(httpx.StreamConsumed):
Expand Down