```python
>>> import http3
>>> r = http3.get('https://www.example.org/')
+>>> r
+<Response [200 OK]>
>>> r.status_code
-<StatusCode.OK: 200>
+200
>>> r.protocol
'HTTP/2'
>>> r.headers['content-type']
*An HTTP response.*
* `def __init__(...)`
-* `.status_code` - **int** *(Typically a `StatusCode` IntEnum.)*
+* `.status_code` - **int**
* `.reason_phrase` - **str**
* `.protocol` - `"HTTP/2"` or `"HTTP/1.1"`
* `.url` - **URL**
```python
>>> import http3
>>> r = http3.get('https://www.example.org/')
+>>> r
+<Response [200 OK]>
>>> r.status_code
-<StatusCode.OK: 200>
+200
>>> r.protocol
'HTTP/2'
>>> r.headers['content-type']
```python
>>> r = http3.get('https://httpbin.org/get')
+>>> r
+<Response [200 OK]>
```
Similarly, to make an HTTP POST request:
```python
>>> r = http3.get('https://httpbin.org/get')
>>> r.status_code
-<StatusCode.OK: 200>
-```
-
-The status code is an integer enum, meaning that the Python representation gives
-use some descriptive information, but the value itself can be used as a regular integer.
-
-```python
->>> r.status_code == 200
-True
+200
```
HTTP3 also includes an easy shortcut for accessing status codes by their text phrase.
```python
->>> r.status_code == requests.codes.OK
+>>> r.status_code == http3.codes.OK
True
```
```python
>>> not_found = http3.get('https://httpbin.org/status/404')
>>> not_found.status_code
-<StatusCode.NOT_FOUND: 404>
+404
>>> not_found.raise_for_status()
Traceback (most recent call last):
File "/Users/tomchristie/GitHub/encode/httpcore/http3/models.py", line 776, in raise_for_status
>>> r.url
URL('https://github.com/')
>>> r.status_code
-<StatusCode.OK: 200>
+200
>>> r.history
-[<Response [301]>]
+[<Response [301 Moved Permanently]>]
```
You can modify the default redirection handling with the allow_redirects parameter:
>>> r.url
'https://github.com/'
>>> r.history
-[<Response [301]>]
+[<Response [301 Moved Permanently]>]
```
## Timeouts
response = Response(
status_code=async_response.status_code,
- reason_phrase=async_response.reason_phrase,
protocol=async_response.protocol,
headers=async_response.headers,
content=sync_content,
event = await self._receive_event(timeout)
assert isinstance(event, h11.Response)
- reason_phrase = event.reason.decode("ascii", errors="ignore")
status_code = event.status_code
headers = event.headers
content = self._body_iter(timeout)
return AsyncResponse(
status_code=status_code,
- reason_phrase=reason_phrase,
protocol="HTTP/1.1",
headers=headers,
content=content,
return AsyncResponse(
status_code=sync_response.status_code,
- reason_phrase=sync_response.reason_phrase,
protocol=sync_response.protocol,
headers=sync_response.headers,
content=async_content,
self,
status_code: int,
*,
- reason_phrase: str = None,
protocol: str = None,
headers: HeaderTypes = None,
request: BaseRequest = None,
on_close: typing.Callable = None,
):
- self.status_code = StatusCode.enum_or_int(status_code)
- self.reason_phrase = StatusCode.get_reason_phrase(status_code)
+ self.status_code = status_code
self.protocol = protocol
self.headers = Headers(headers)
self.on_close = on_close
self.next = None # typing.Optional[typing.Callable]
+ @property
+ def reason_phrase(self) -> str:
+ return StatusCode.get_reason_phrase(self.status_code)
+
@property
def url(self) -> typing.Optional[URL]:
"""
return self._cookies
def __repr__(self) -> str:
- return f"<Response({self.status_code}, {self.reason_phrase!r})>"
+ return f"<Response [{self.status_code} {self.reason_phrase}])>"
class AsyncResponse(BaseResponse):
self,
status_code: int,
*,
- reason_phrase: str = None,
protocol: str = None,
headers: HeaderTypes = None,
content: AsyncResponseContent = None,
):
super().__init__(
status_code=status_code,
- reason_phrase=reason_phrase,
protocol=protocol,
headers=headers,
request=request,
self,
status_code: int,
*,
- reason_phrase: str = None,
protocol: str = None,
headers: HeaderTypes = None,
content: ResponseContent = None,
):
super().__init__(
status_code=status_code,
- reason_phrase=reason_phrase,
protocol=protocol,
headers=headers,
request=request,
def __str__(self) -> str:
return str(self.value)
- @classmethod
- def enum_or_int(cls, value: int) -> int:
- try:
- return StatusCode(value)
- except ValueError:
- return value
-
@classmethod
def get_reason_phrase(cls, value: int) -> str:
try:
assert response.text == "Hello, world!"
assert response.protocol == "HTTP/1.1"
assert response.headers
- assert repr(response) == "<Response(200, 'OK')>"
+ assert repr(response) == "<Response [200 OK])>"
@pytest.mark.asyncio
assert response.request.url == http3.URL(url)
assert response.headers
assert response.is_redirect is False
- assert repr(response) == "<Response(200, 'OK')>"
+ assert repr(response) == "<Response [200 OK])>"
@threadpool
def test_response_repr():
response = http3.Response(200, content=b"Hello, world!")
- assert repr(response) == "<Response(200, 'OK')>"
+ assert repr(response) == "<Response [200 OK])>"
def test_response_content_type_encoding():
--- /dev/null
+import http3
+
+
+def test_status_code_as_int():
+ assert http3.codes.NOT_FOUND == 404
+ assert str(http3.codes.NOT_FOUND) == "404"
+
+
+def test_lowercase_status_code():
+ assert http3.codes.not_found == 404
+
+
+def test_reason_phrase_for_status_code():
+ assert http3.codes.get_reason_phrase(404) == "Not Found"
+
+
+def test_reason_phrase_for_unknown_status_code():
+ assert http3.codes.get_reason_phrase(499) == ""