python requests randomly breaks with JSONDecodeError python requests randomly breaks with JSONDecodeError json json

python requests randomly breaks with JSONDecodeError


Looking at the documentation for this API it seems the only responses are in JSON format, so receiving HTML is strange. To increase the likelihood of receiving a JSON response, you can set the 'Accept' header to 'application/json'.

I tried querying this API many times with parameters and did not encounter a JSONDecodeError. This error is likely the result of another error on the server side. To handle it, except a json.decoder.JSONDecodeError in addition to the ConnectionError error you currently except and handle this error in the same way as the ConnectionError.

Here is an example with all that in mind:

import requests, json, time, randomdef get_submission_records(client, since, try_number=1):    url = 'http://reymisterio.net/data-dump/api.php/submission?filter[]=form,cs,'+client+'&filter[]=date,cs,'+since    headers = {'Accept': 'application/json'}    try:        response = requests.get(url, headers=headers).json()    except (requests.exceptions.ConnectionError, json.decoder.JSONDecodeError):        time.sleep(2**try_number + random.random()*0.01) #exponential backoff        return get_submission_records(client, since, try_number=try_number+1)    else:        return response['submission']['records']

I've also wrapped this logic in a recursive function, rather than using while loop because I think it is semantically clearer. This function also waits before trying again using exponential backoff (waiting twice as long after each failure).

Edit: For Python 2.7, the error from trying to parse bad json is a ValueError, not a JSONDecodeError

import requests, time, randomdef get_submission_records(client, since, try_number=1):    url = 'http://reymisterio.net/data-dump/api.php/submission?filter[]=form,cs,'+client+'&filter[]=date,cs,'+since    headers = {'Accept': 'application/json'}    try:        response = requests.get(url, headers=headers).json()    except (requests.exceptions.ConnectionError, ValueError):        time.sleep(2**try_number + random.random()*0.01) #exponential backoff        return get_submission_records(client, since, try_number=try_number+1)    else:        return response['submission']['records']

so just change that except line to include a ValueError instead of json.decoder.JSONDecodeError.


Try this. it might work

while True:        try:            submissions = requests.get('http://reymisterio.net/data-dump/api.php/submission?filter[]=form,cs,'+client+'&filter[]=date,cs,'+since).json()['submission']['records']            sub = json.loads(submissions.text)            print(sub)            break        except requests.exceptions.ConnectionError:            time.sleep(100)