Search code examples
pythonpass-by-referenceimgur

Imgur API: Dictionary values magically turns into None?


I know voodoo magic probably isn't the cause of this - but it sure seems like it!

I have the following code snippets, making use of the imgur API. The imgur object is the client which the imgur API uses and contains an attribute credits which displays the number of access credits the user has on the website.

imgur = imgurpython.ImgurClient(client_id, client_secret)

Calling:

imgur.credits

Returns the credits as normal, i.e.:

{'ClientLimit': 12500, 'UserReset': 1503185179, 'UserLimit': 500, 'UserRemaining': 0, 'ClientRemaining': 12000}

However when I attempt to call the dictionary in a later function:

def check_credits(imgur):
    '''
        Receives a client - and if there is not much credits left,
        wait until the credit refills - i.e. pause the program
    '''
    credits = imgur.credits
    credits_remaining = credits['UserRemaining']
    reset_time = credits['UserReset']

    if credits_remaining < 10:
        print('not enough credits, remaining: %i' % credits_remaining)
        now = int(dt.utcnow().timestamp())
        wait_time = reset_time - now
        print('waiting for: %i' % wait_time)
        time.sleep(wait_time)

Sometimes the values in the dictionaries seem to turn into None instead of the integers they are supposed to be. In this case both reset_time and credits_remaining sometimes turn out to be None. In order to allow my code to run I'm having to add try-catches all over the code and it's getting quite frustrating. By the way, this function is called whenever the error ImgurClientRateLimitError, which is when imgur.credits['UserRemaining'] == 0. I'm wondering if anyone know why this may have been the case.


Solution

  • Upon looking at the source code for the client it seems that this is updated automatically upon each request. The updated values are obtained from the response headers after a call to ImgurClient.make_request. The header values are obtained from dict.get which can return None if the key does not exist in the headers dictionary. The code for reference is here: https://github.com/Imgur/imgurpython/blob/master/imgurpython/client.py#L143

    I am not sure if these headers are still used on errors like 404 or 403 but I would investigate further from there. It seems though that because of this behavior you would need to either cache previous values or manually call the ImgurClient.get_credits method in these cases to get the real values. Whichever fix you go with is up to you.