74

What is the easiest way to check whether the response received from a requests post was "200 OK" or an error has occurred?

I tried doing something like this:

....
resp = requests.post(my_endpoint_var, headers=header_var, data=post_data_var)
print(resp)
if resp == "<Response [200]>":
    print ('OK!')
else:
    print ('Boo!')

The output on the screen is:

Response [200] (including the "<" and ">")
Boo!

So even though I am getting a 200, my check in the if statement is somehow not matching?

Shaido
  • 27,497
  • 23
  • 70
  • 73
Monty
  • 1,161
  • 2
  • 15
  • 26
  • I am not sure if it would work, but try to replace print(resp) with print(resp.status_code) and check if it works – Daweo Jan 08 '19 at 07:52
  • I think resp should have a field "status_code". Check for resp.status_code == 200 – kirkegaard Jan 08 '19 at 07:52
  • Your comparison operation fails because you are [comparing objects](https://docs.python.org/3/library/stdtypes.html#comparisons) of different types: a [`str`](https://docs.python.org/3/library/stdtypes.html#text-sequence-type-str) object on the right *with* a [`requests.models.Response`](https://docs.python-requests.org/en/v3.0.0/api/#requests.Response) instance on the left. What you want on the left is the [string representation](https://docs.python.org/3/library/stdtypes.html#str) of the response object. That said, the answers to this question present better ways to achieve your goal. – Olúwátóósìn Anímáṣahun May 16 '22 at 11:30

8 Answers8

108

According to the docs, there's a status_code property on the response-object. So you can do the following:

if resp.status_code == 200:
    print ('OK!')
else:
    print ('Boo!')

EDIT:

As others have pointed out, a simpler check would be

if resp.ok:
    print ('OK!')
else:
    print ('Boo!')

if you want to consider all 2xx response codes and not 200 explicitly. You may also want to check Peter's answer for a more python-like way to do this.

eol
  • 23,236
  • 5
  • 46
  • 64
45

Just checking the response attribute resp.ok is True is sufficient for all 2xx responses (while it will be False for 4xx and 5xx)

However, a potentially more Pythonic way to check for success would be to test and optionally raise an exception with Response.raise_for_status() (which will raise requests.HTTPError if the request was unsuccessful, or continue without interruption for a successful request)

This can be directly handled or raised to the calling function (which might, for example, try the request again after a few seconds if it believes the error was transient)

try:
    resp = requests.post(url, headers=headers, data=data, timeout=timeout)
    resp.raise_for_status()
except requests.HTTPError as ex:
    # possibly check response for a message
    raise ex  # let the caller handle it
except requests.Timeout:
    # request took too long

EAFP: It’s Easier to Ask for Forgiveness than Permission
It's frequently clearer to just do what you expect to work and if an exception is raised from the operation, except and handle it.

Finally, note that some APIs will return a valid response (200) for errors with information about why the request was bad, while others may respond with a 400-level with additional information that might be useful (such as a link to documentation or a specific message about what to do), which can be worth checking for.

ti7
  • 16,375
  • 6
  • 40
  • 68
Peter
  • 10,959
  • 2
  • 30
  • 47
  • 2
    While EAFP works for _most_ of Python, I think in this case it's better asking for the response first. If you're dealing with an API for example, it could give a 4xx response without raising any exception. – Peter Jan 16 '20 at 17:51
  • This is the way! – Daniel Dec 26 '21 at 14:35
  • At first, I thought that the [Peter](https://stackoverflow.com/users/7108589/peter) who has answered this was the same [Peter](https://stackoverflow.com/users/2403000/peter) who raised the [EAFP caveat](https://stackoverflow.com/questions/54087303/python-requests-how-to-check-for-200-ok#comment105694404_58465267) in the comments. That said, there are issues with both comments. See my other comments below. – Olúwátóósìn Anímáṣahun May 16 '22 at 11:39
  • I am giving this a downvote, as it does not quite answer the asker's question about "how to ascertain a [HTTP 200 OK](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/200)". [`resp.ok`](https://docs.python-requests.org/en/latest/api/#requests.Response.ok) covers a broader range of values -- status codes below 400 that is. A [simple check for a status code that is equal to 200](https://stackoverflow.com/a/54087354/1650240) achieves the goal. – Olúwátóósìn Anímáṣahun May 16 '22 at 12:00
  • [@Peter](https://stackoverflow.com/users/2403000/peter): Exception raising is not a function of the actual [HTTP API or the web service](https://www.educative.io/blog/what-are-rest-apis#http) being interacted with. In this case, it is the result of evaluating the same "response" which you refer to. So you must indeed have a response first before you can even call `resp.raise_for_status()` (which throws an exception when the inspected [HTTP status code](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status) is above 399). – Olúwátóósìn Anímáṣahun May 16 '22 at 12:15
8

Since any 2XX class response is considered successful in HTTP, I would use:

if 200 <= resp.status_code <= 299:
    print ('OK!') 
else:
    print ('Boo!')
rouble
  • 16,364
  • 16
  • 107
  • 102
8

Much simpler check would be

    if resp.ok :
        print ('OK!')
    else:
        print ('Boo!')
MrHumble
  • 81
  • 1
  • 1
3

I'm surprised no one has mentioned this so:

If you want to check for exactly a 200 response:

if resp.status_code == requests.codes.ok:

The status_code of a response contains the HTTP status returned.

requests.codes.ok is exactly 200.


If you want to check if the status code is "ok", and not an error:

if resp.ok:

The ok attribute of a response checks that the status code of the response is less than 400.


Make sure you know what it is you want to check, for example a 201 HTTP Created is a successful response that you would be omitting if you only check for exactly 200.

gdvalderrama
  • 713
  • 1
  • 17
  • 26
2

resp.status_code will return the status code as an integer.

See http://docs.python-requests.org/en/master/

orangeInk
  • 1,360
  • 8
  • 16
1

try:

if resp.status_code == 200:
    print ('OK!')
else:
    print ('Boo!)
Caders117
  • 319
  • 3
  • 18
0

In easy case:

import requests

response = requests.get(url)
if not response:
    #handle error here
else:
    #handle normal response
qloveshmily
  • 1,017
  • 9
  • 5