Python: Response code returns 200 even when internet is turned off?

Viewed 697

Been trying to create a loop which keeps iterating even when the net connection gets disrupted(try/except block). For the most part, it works. But midway execution, when I test the response code after turning the Wi-Fi off it still returns 200. Can't seem to understand why that is. I mean, 200 means a successful fetched request which can't happen without a Wi-Fi connection, right? I read response code 200 is cached by default, is that the reason? What can I do to get over the issue? It can't because of the latter requests method used, right? Here's the main code.

base = datetime.datetime.today()
date_list = [base + datetime.timedelta(days=x) for x in range(numdays)]
date_str = [x.strftime("%d-%m-%Y") for x in date_list]

loop_starts = time.time()
for INP_DATE in date_str:
    try:
        # API to get planned vaccination sessions on a specific date in a given district.
        URL = f"https://cdn-api.co-vin.in/api/v2/appointment/sessions/public/findByDistrict?district_id=" \
              f"512&date={INP_DATE}"
        response = requests.get(URL, headers=browser_header)
        response.raise_for_status()

    except requests.exceptions.HTTPError as errh:
        print("Http Error:", errh)
    except requests.exceptions.ConnectionError as errc:
        print("Error Connecting:", errc)
    except requests.exceptions.Timeout as errt:
        print("Timeout Error:", errt)
    except requests.exceptions.RequestException as err:
        print("OOps: Something Else", err)

    finally:
        print(f'Response code: {response.status_code}') #Why do you always return 200?!

        #code not important to the question
        if response.ok:
            resp_json = response.json()
            # read documentation to understand following if/else tree
            if resp_json["sessions"]:
                print("Available on: {}".format(INP_DATE))
                if print_flag == 'y' or print_flag == 'Y':
                    for center in resp_json["sessions"]:  # printing each center
                        if center["min_age_limit"] <= age:
                            print("\t", "Name:", center["name"])
                            print("\t", "Block Name:", center["block_name"])
                            print("\t", "Pin Code:", center["pincode"])
                            #   print("\t", "Center:", center)
                            print("\t", "Min Age:", center['min_age_limit'])
                            print("\t Free/Paid: ", center["fee_type"])
                            if center['fee_type'] != "Free":
                                print("\t", "Amount:", center["fee"])
                            else:
                                center["fee"] = '-'
                            print("\t Available Capacity: ", center["available_capacity"])
                            if center["vaccine"] != '':
                                print("\t Vaccine: ", center["vaccine"])
                            else:
                                center["vaccine"] = '-'
                            print("\n\n")

                            # Sending text message when availability of vaccine >= 10
                            # Creating text to send to telegram

                            txt = f'Available on: {INP_DATE}\nName: {center["name"]}\nBlock ' \
                                  f'Name: {center["block_name"]}\nPinCode: {center["pincode"]}\n' \
                                  f'Min Age: {center["min_age_limit"]}\nFree/Paid: {center["fee_type"]}\n' \
                                  f'Amount: {center["fee"]}\nAvailable Capacity: {center["available_capacity"]}\n' \
                                  f'Vaccine: {center["vaccine"]}\n\nhttps://selfregistration.cowin.gov.in/'
                            if center["available_capacity"] >= 10:
                                to_url = 'https://api.telegram.org/bot{}/sendMessage?chat_id={}&text={}&parse_mode=' \
                                         'HTML'.format(token, chat_id, txt)
                                resp = requests.get(to_url)
                                print('Sent')
            else:
                print("No available slots on {}".format(INP_DATE))
        else:
            print("Response not obtained.") #Should output when net is off.

        time.sleep(25)  # Using 7 requests in 1 second. 100 requests per 5 minutes allowed. You do the math.
        #  timing the loop
        now = time.time()
        print("It has been {} seconds since the loop started\n".format(now - loop_starts))
2 Answers

Rewrote your code like this

  1. response was not overwritten in case of network exception, so response was the previous value
  2. finally was the pitfall, as the code is executed even if the exception is caught, which is not what you want
  3. use continue in your exception to try again
base = datetime.datetime.today()
date_list = [base + datetime.timedelta(days=x) for x in range(numdays)]
date_str = [x.strftime("%d-%m-%Y") for x in date_list]

loop_starts = time.time()
for INP_DATE in date_str:
    try:
        # API to get planned vaccination sessions on a specific date in a given district.
        URL = f"https://cdn-api.co-vin.in/api/v2/appointment/sessions/public/findByDistrict?district_id=" \
              f"512&date={INP_DATE}"
        response = requests.get(URL, headers=browser_header)
        response.raise_for_status()

    except requests.exceptions.HTTPError as errh:
        print("Http Error:", errh)
        continue
    except requests.exceptions.ConnectionError as errc:
        print("Error Connecting:", errc)
        continue
    except requests.exceptions.Timeout as errt:
        print("Timeout Error:", errt)
        continue
    except requests.exceptions.RequestException as err:
        print("OOps: Something Else", err)
        continue

    # will now only been displayed when you DO have a 200
    print(f'Response code: {response.status_code}') #Why do you always return 200?!

    #code not important to the question
    resp_json = response.json()
    # read documentation to understand following if/else tree
    if not resp_json["sessions"]:
        print("No available slots on {}".format(INP_DATE))
        continue

    print("Available on: {}".format(INP_DATE))
    if print_flag != 'y' and print_flag != 'Y':
        continue

    for center in resp_json["sessions"]:  # printing each center
        if center["min_age_limit"] > age:
            continue
        print("\t", "Name:", center["name"])
        print("\t", "Block Name:", center["block_name"])
        print("\t", "Pin Code:", center["pincode"])
        #   print("\t", "Center:", center)
        print("\t", "Min Age:", center['min_age_limit'])
        print("\t Free/Paid: ", center["fee_type"])
        if center['fee_type'] != "Free":
            print("\t", "Amount:", center["fee"])
        else:
            center["fee"] = '-'
        print("\t Available Capacity: ", center["available_capacity"])
        if center["vaccine"] != '':
            print("\t Vaccine: ", center["vaccine"])
        else:
            center["vaccine"] = '-'
        print("\n\n")

        # Sending text message when availability of vaccine >= 10
        # Creating text to send to telegram

        txt = f'Available on: {INP_DATE}\nName: {center["name"]}\nBlock ' \
              f'Name: {center["block_name"]}\nPinCode: {center["pincode"]}\n' \
              f'Min Age: {center["min_age_limit"]}\nFree/Paid: {center["fee_type"]}\n' \
              f'Amount: {center["fee"]}\nAvailable Capacity: {center["available_capacity"]}\n' \
              f'Vaccine: {center["vaccine"]}\n\nhttps://selfregistration.cowin.gov.in/'
        if center["available_capacity"] >= 10:
            to_url = 'https://api.telegram.org/bot{}/sendMessage?chat_id={}&text={}&parse_mode=' \
                     'HTML'.format(token, chat_id, txt)
            resp = requests.get(to_url)
            print('Sent')

    time.sleep(25)  # Using 7 requests in 1 second. 100 requests per 5 minutes allowed. You do the math.
    #  timing the loop
    now = time.time()
    print("It has been {} seconds since the loop started\n".format(now - loop_starts))

As others have commented and replied, finally is not appropriate here. allan.simon offers a solution using continue in the exception handlers. That's certainly a good solution.

An alternative solution (not necessarily better): replace finally with else. An else clause in a try-statement "is executed if the control flow leaves the try suite, no exception was raised, and no return, continue, or break statement was executed." (quoting the documentation). That's exactly what you were trying to do with the finally here.

Related