Response¶
The HTTP response object returned by all request methods.
Overview¶
The Response class provides access to all aspects of an HTTP response:
import httpr
response = httpr.get("https://httpbin.org/get")
# Status
print(response.status_code) # 200
# Body
print(response.text) # Decoded text
print(response.content) # Raw bytes
data = response.json() # Parsed JSON
# Headers (case-insensitive)
print(response.headers["content-type"])
print(response.headers["Content-Type"]) # Same result
# Cookies
print(response.cookies) # {"session": "value"}
# Metadata
print(response.url) # Final URL after redirects
print(response.encoding) # Detected encoding
Properties¶
status_code¶
HTTP status code (e.g., 200, 404, 500).
Example:
reason_phrase¶
Canonical reason phrase for the status code (e.g., "OK", "Not Found").
Example:
Status classification¶
A set of boolean properties for checking the status code class without comparing integers manually:
| Property | True when |
|---|---|
is_informational |
1xx status code |
is_success |
2xx status code |
is_redirect |
3xx status code |
is_client_error |
4xx status code |
is_server_error |
5xx status code |
is_error |
4xx or 5xx status code |
has_redirect_location |
3xx response with a Location header (301, 302, 303, 307, 308) |
Example:
response = httpr.get("https://httpbin.org/status/200")
if response.is_success:
print("Success!")
elif response.is_client_error:
print("Client error")
elif response.is_server_error:
print("Server error")
text¶
Response body decoded as text.
Encoding is automatically detected from:
Content-Typeheader charset- HTML meta charset tag
- Falls back to UTF-8
Example:
content¶
Response body as raw bytes.
Example:
response = httpr.get("https://httpbin.org/bytes/100")
print(len(response.content)) # 100
# Save binary file
response = httpr.get("https://httpbin.org/image/png")
with open("image.png", "wb") as f:
f.write(response.content)
headers¶
Response headers as a case-insensitive dict-like object.
Supports:
response.headers["Content-Type"]- get by keyresponse.headers.get("content-type", "default")- get with default"content-type" in response.headers- check existenceresponse.headers.keys()- all header namesresponse.headers.values()- all header valuesresponse.headers.items()- key-value pairs
Example:
response = httpr.get("https://httpbin.org/get")
# Case-insensitive access
print(response.headers["content-type"])
print(response.headers["Content-Type"]) # Same
# Iteration
for name, value in response.headers.items():
print(f"{name}: {value}")
cookies¶
Cookies set by the server via Set-Cookie headers.
Example:
response = httpr.get("https://httpbin.org/cookies/set?name=value")
print(response.cookies) # {"name": "value"}
url¶
Final URL after following any redirects.
Example:
response = httpr.get("https://httpbin.org/redirect/3")
print(response.url) # https://httpbin.org/get
encoding¶
Character encoding detected from response headers or content.
Example:
text_markdown¶
HTML response body converted to Markdown format.
Uses Rust's html2text crate for conversion.
Example:
response = httpr.get("https://example.com")
print(response.text_markdown)
# # Example Domain
#
# This domain is for use in illustrative examples...
text_plain¶
HTML response body converted to plain text (no formatting).
Example:
text_rich¶
HTML response body converted to rich text format.
Methods¶
json¶
Parse response body as JSON.
Returns: Parsed JSON (dict, list, str, int, float, bool, or None)
Raises: Exception if body is not valid JSON
Example:
response = httpr.get("https://httpbin.org/json")
data = response.json()
print(data["slideshow"]["title"])
Note
json() is a method, not a property. Call it with parentheses.
raise_for_status¶
Raise HTTPStatusError if the response has a non-2xx status
code. Returns the response itself on success, so the call can be chained.
Returns: The same Response object (when the status is 2xx)
Raises: HTTPStatusError for any non-2xx status code
Example:
response = httpr.get("https://httpbin.org/status/404")
try:
response.raise_for_status()
except httpr.HTTPStatusError as exc:
print(exc) # Client error '404 Not Found' for url '...'
# Chaining: raise on error, otherwise parse the body
data = httpr.get("https://httpbin.org/json").raise_for_status().json()
Note
Unlike requests, any non-2xx status raises — including 1xx and 3xx
responses — matching httpx behavior. With redirects followed (the
default), a 3xx is only seen when follow_redirects=False.
StreamingResponse¶
For streaming large responses without buffering the entire response in memory, use the Client.stream() method which returns a StreamingResponse.
import httpr
with httpr.Client() as client:
with client.stream("GET", "https://httpbin.org/stream-bytes/1000") as response:
for chunk in response.iter_bytes():
process(chunk)
Properties¶
status_code¶
HTTP status code (e.g., 200, 404, 500).
Example:
Status helpers¶
StreamingResponse exposes the same status API as Response, available
immediately after the headers arrive (before the body is read):
reason_phrase— canonical reason phrase for the status codeis_informational,is_success,is_redirect,is_client_error,is_server_error,is_error— status-class booleanshas_redirect_location— 3xx response with aLocationheaderraise_for_status()— raiseHTTPStatusErrorfor a non-2xx status, otherwise return the streaming response itself
Example:
with client.stream("GET", "https://httpbin.org/stream-bytes/1000") as response:
response.raise_for_status() # bail out early on a non-2xx status
for chunk in response.iter_bytes():
process(chunk)
headers¶
Response headers as a case-insensitive dict-like object.
Example:
with client.stream("GET", "https://httpbin.org/get") as response:
content_type = response.headers["content-type"]
cookies¶
Cookies set by the server via Set-Cookie headers.
url¶
Final URL after following any redirects.
is_closed¶
Whether the stream has been closed.
Example:
with client.stream("GET", "https://httpbin.org/get") as response:
print(response.is_closed) # False
print(response.is_closed) # True (after context manager exits)
is_consumed¶
Whether the stream has been fully consumed.
Example:
with client.stream("GET", "https://httpbin.org/get") as response:
print(response.is_consumed) # False
_ = list(response) # Consume the stream
print(response.is_consumed) # True
Methods¶
iter_bytes¶
Iterate over the response body as bytes chunks.
Returns: Iterator yielding bytes chunks
Example:
with client.stream("GET", "https://httpbin.org/stream-bytes/1000") as response:
for chunk in response.iter_bytes():
print(f"Received {len(chunk)} bytes")
iter_text¶
Iterate over the response body as text chunks, decoded using the response encoding.
Returns: TextIterator yielding string chunks
Example:
with client.stream("GET", "https://httpbin.org/html") as response:
for text in response.iter_text():
print(text, end="")
iter_lines¶
Iterate over the response body line by line.
Returns: LineIterator yielding string lines
Useful for Server-Sent Events (SSE) and line-based protocols.
Example:
with client.stream("GET", "https://httpbin.org/stream/10") as response:
for line in response.iter_lines():
print(line.strip())
read¶
Read the entire remaining response body into memory.
Returns: Response body as bytes
Example:
with client.stream("GET", "https://httpbin.org/get") as response:
if response.status_code == 200:
content = response.read()
close¶
Close the stream and release resources.
Note: When using the context manager, close() is called automatically.
Example:
with client.stream("GET", "https://httpbin.org/get") as response:
# Process headers
if response.status_code != 200:
response.close() # Close early without reading body
return
# Otherwise read body
content = response.read()
Direct Iteration¶
StreamingResponse supports direct iteration, which is equivalent to calling iter_bytes():
with client.stream("GET", "https://httpbin.org/stream-bytes/1000") as response:
for chunk in response: # Same as response.iter_bytes()
process(chunk)
Important Notes¶
- Always use as context manager: Ensures proper cleanup of resources
- Headers available immediately: Status code, headers, cookies, and URL are accessible before reading the body
- Body only read on demand: The response body is only fetched when you iterate or call
read() - Cannot re-read: Once consumed, the stream cannot be read again
- Supported for all methods: GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS
Exception Handling¶
The streaming response raises specific exceptions:
StreamClosed: Raised when attempting to read from a closed streamStreamConsumed: Raised when attempting to re-read a consumed stream
Example: