diff --git a/CHANGES/4711.feature b/CHANGES/4711.feature new file mode 100644 index 00000000000..eebb65c5cbe --- /dev/null +++ b/CHANGES/4711.feature @@ -0,0 +1 @@ +Add ClientResponse.ok property for checking status code under 400. diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt index b8c39b67fc8..041d58fcae8 100644 --- a/CONTRIBUTORS.txt +++ b/CONTRIBUTORS.txt @@ -100,6 +100,7 @@ Eugene Ershov Eugene Naydenov Eugene Nikolaiev Eugene Tolmachev +Evan Kepner Evert Lammerts Felix Yan Fernanda GuimarĂ£es diff --git a/aiohttp/client_reqrep.py b/aiohttp/client_reqrep.py index 70bf1bde6ba..33b3174a3cb 100644 --- a/aiohttp/client_reqrep.py +++ b/aiohttp/client_reqrep.py @@ -876,6 +876,19 @@ def release(self) -> Any: self._cleanup_writer() return noop() + @property + def ok(self) -> bool: + """Returns ``True`` if ``status`` is less than ``400``, ``False`` if not. + + This is **not** a check for ``200 OK`` but a check that the response + status is under 400. + """ + try: + self.raise_for_status() + except ClientResponseError: + return False + return True + def raise_for_status(self) -> None: if 400 <= self.status: # reason should always be not None for a started response diff --git a/docs/client_reference.rst b/docs/client_reference.rst index 1d17717521a..1fa6c66444d 100644 --- a/docs/client_reference.rst +++ b/docs/client_reference.rst @@ -1091,6 +1091,11 @@ Response object HTTP status reason of response (:class:`str`), e.g. ``"OK"``. + .. attribute:: ok + + Boolean representation of HTTP status code (:class:`bool`). + ``True`` if ``status`` is less than ``400``; otherwise, ``False``. + .. attribute:: method Request's method (:class:`str`). diff --git a/tests/test_client_functional.py b/tests/test_client_functional.py index 656a14e2b9a..ecebea642d2 100644 --- a/tests/test_client_functional.py +++ b/tests/test_client_functional.py @@ -2202,6 +2202,29 @@ async def handler_redirect(request): assert data == body +@pytest.mark.parametrize( + ("status", "expected_ok"), + ( + (200, True), + (201, True), + (301, True), + (400, False), + (403, False), + (500, False), + ) +) +async def test_ok_from_status(aiohttp_client, status, expected_ok) -> None: + + async def handler(request): + return web.Response(status=status, body=b'') + + app = web.Application() + app.router.add_route('GET', '/endpoint', handler) + client = await aiohttp_client(app, raise_for_status=False) + resp = await client.get('/endpoint') + + assert resp.ok is expected_ok + async def test_raise_for_status(aiohttp_client) -> None: async def handler(request):