Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When to use `raise_for_status` vs `status_code` testing

I have always used:

r = requests.get(url)
if r.status_code == 200:
    # my passing code
else:
    # anything else, if this even exists

Now I was working on another issue and decided to allow for other errors and am instead now using:

try:
    r = requests.get(url)
    r.raise_for_status()
except requests.exceptions.ConnectionError as err:
    # eg, no internet
    raise SystemExit(err)
except requests.exceptions.HTTPError as err:
    # eg, url, server and other errors
    raise SystemExit(err)
# the rest of my code is going here

With the exception that various other errors could be tested for at this level, is one method any better than the other?

like image 257
Madivad Avatar asked Apr 27 '20 16:04

Madivad


People also ask

What does Response Raise_for_status do?

raise_for_status() returns an HTTPError object if an error has occurred during the process. It is used for debugging the requests module and is an integral part of Python requests. Python requests are generally used to fetch the content from a particular resource URI.

How do you know if a response is 404?

If you have ever wanted to check whether a page has returned a 404 for any reason, one of the easiest ways is to use this little helper function UrlExists() with the current url, given by window. location. href.

How do I know if a response is 404 in Python?

Dealing with Errors The most common status codes are probably 200 - Success, and 404 - Not found. You can find the status code in the status_code property of the response object: # Passing in a non-existant URL will result in a 404 (not found) bad_response = requests.

What does Python Request Return?

When one makes a request to a URI, it returns a response. This Response object in terms of python is returned by requests. method(), method being – get, post, put, etc.


1 Answers

Response.raise_for_status() is just a built-in method for checking status codes and does essentially the same thing as your first example.

There is no "better" here, just about personal preference with flow control. My preference is toward try/except blocks for catching errors in any call, as this informs the future programmer that these conditions are some sort of error. If/else doesn't necessarily indicate an error when scanning code.


Edit: Here's my quick-and-dirty pattern.

import time

import requests
from requests.exceptions import HTTPError

url = "https://theurl.com"
retries = 3

for n in range(retries):
    try:
        response = requests.get(url)
        response.raise_for_status()

        break

    except HTTPError as exc:
        code = exc.response.status_code
        
        if code in [429, 500, 502, 503, 504]:
            # retry after n seconds
            time.sleep(n)
            continue

        raise
      

However, in most scenarios, I subclass requests.Session, make a custom HTTPAdapter that handles exponential backoffs, and the above lives in an overridden requests.Session.request method. An example of that can be seen here.

like image 118
Sam Morgan Avatar answered Sep 22 '22 08:09

Sam Morgan