Łapanie wyjątku podczas api calla

0

Yo,

Mamy dwa przypadki.

Pierwszy:

r = requests.get("jakis web", "jakies headery")
try:
    r.raise_for_status()
except:
    zlap wyjatek i zrob z nim cos

Drugi:

try:
    r = requests.get("jakis web", "jakies headery")
    r.raise_for_status()
except:
    zlap wyjatek i zrob z nim cos

Generalnie założenie jest proste - zrobić coś w przypadku statusu innego niż 200. Ostatnio był to temat do dyskusji na CR. Api call najprostszy z możliwych (Zawsze zwróci Response object). Jestem ciekaw opinii, które podejście jest wg Was sensowniejsze i dlaczego.

6

Pytanie - czy jest opcja, żeby r = requests.get(... rzuciło wyjątkiem?

EDIT
nie chodzi mi o żadnen konkretny język, ani żadną konkretną funkcję/metodę, tylko taka ogólna zasada/przemyślenie. Wydaje mi się, że @ledi12 nie pytał o to, jak się zachowa r = requests.get(... w tym przypadku, tylko raczej o to, który sposób jest lepszy, a podany kod jest jedynie przykładem/ilustracją

EDIT 2
Z tych dwóch opcji bym był za drugą. Jeśli cos może rzucić wyjątkiem to lepiej to obsłużyć, a jeśli nie rzuci ale będzie objęte konstrukcja try /except to nic się nie stanie

1

Ani jedno ani drugie, requests ma już property od tego
https://requests.readthedocs.io/en/latest/api/#requests.Response.ok

0

Jedyna opcja to host musi przestać całkowicie działać, co w przypadku dużego publicznego api jest bardzo mało prawdopodobne.

2
ledi12 napisał(a):

Jedyna opcja to host musi przestać całkowicie działać, co w przypadku dużego publicznego api jest bardzo mało prawdopodobne.

A kto powiedział, że to po ich stronie coś się musi popsuć, żeby nawiązanie połączenia się nie udało?

0
def make_http_request(method, url, data=None, headers=None, verify=None, timeout=None, retry_number=1, delay=1):
    method = method.upper()

    if method not in ["POST", "GET", "PUT", "DELETE"]:
        raise ValueError("Invalid HTTP method, use one of available methods: POST, GET, PUT, DELETE")

    for attempt in range(retry_number + 1):
        try:
            if method == "POST":
                response = requests.post(url, data=json.dumps(data), headers=headers, verify=verify, timeout=timeout)
            elif method == "GET":
                response = requests.get(url, headers=headers, verify=verify, timeout=timeout)
            elif method == "PUT":
                response = requests.put(url, data=json.dumps(data), headers=headers, verify=verify, timeout=timeout)
            elif method == "DELETE":
                response = requests.delete(url, headers=headers, verify=verify, timeout=timeout)

            if response.status_code in [401, 409] or 'not authorized' in response.text.lower():
                return response

            if response.status_code in [500, 502, 503, 504]:
                if attempt < retry_number:
                    sleep(delay)
                    delay = delay + 1
                    continue
                else:
                    raise HTTPError(response=response)
            
            return response
        except Exception as e:
            if attempt < retry_number:
                sleep(1)  
            else:
                raise e
3
ledi12 napisał(a):

Jedyna opcja to host musi przestać całkowicie działać, co w przypadku dużego publicznego api jest bardzo mało prawdopodobne.

A jak zerwie się połączenie TCP, albo zużyjesz wszystkie dostępne porty SNAT/połączenia wychodzące (usługi chmurowe często mają jakieś limity i to nie za wysokie)?
A jak nie uda się rozwiązać nazwy DNS?

Jeśli w takich i podobnych przypadkach to nie rzuca wyjątku to nie widzę przeciwskazań do opcji nr 1.
Jesli rzuca to opcja nr 2.

W .NET zawsze robię opcję nr 2, bo te przypadki, które opisałem wyżej rzucają exceptiona. Tak samo jak przekażę CancellationToken do requestu i coś go w trakcie wykonywania requestu zcancelluje.

0

Co to za zawadiacki język, że trzeba aż dwóch linijek kodu, żeby pobrać dane z jakiegoś API?

1 użytkowników online, w tym zalogowanych: 0, gości: 1