Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to form an anonymous request to Imgur's APIv3

A while ago, I made a python function which took a URL of an image and passed it to Imgur's API v2. Since I've been notified that the v2 API is going to be deprecated, I've attempted to make it using API v3.

As they say in the Imgur API documentation:

[Sending] an authorization header with your client_id along with your requests [...] also works if you'd like to upload images anonymously (without the image being tied to an account). This lets us know which application is accessing the API.**

Authorization: Client-ID YOURCLIENTID

It's unclear to me (especially with the italics they put) whether they mean that the header should be {'Authorization': 'Client-ID ' + clientID}, or {'Authorization: Client-ID ': clientID}, or {'Authorization:', 'Client-ID ' + clientID}, or some other variation...

Either way, I tried and this is what I got (using Python 2.7.3):

def sideLoad(imgURL):
    img = urllib.quote_plus(imgURL)
    req = urllib2.Request('https://api.imgur.com/3/image', 
                          urllib.urlencode([('image', img), 
                                            ('key', clientSecret)]))
    req.add_header('Authorization', 'Client-ID ' + clientID)
    response = urllib2.urlopen(req)
    return response.geturl()

This seems to me like it does everything Imgur wants me to do: I've got the right endpoint, passing data to urllib2.Request makes it a POST request according to the Python docs, I'm passing the image parameter with the form-encoded URL, I also tried giving it my client secret as a POST parameter since I got an error saying I need an ID (even though there is no mention of the need for me to use my client secret anywhere in the relevant documentation). I add the Authorization header and it seems to be the right form, so... why am I getting an Error 400: Bad Request?

Side-question: I might be able to debug it myself if I could see the actual error Imgur returns, but because it returns an erroneous HTTP status, Python dies and gives me one of those nauseating stack traces. Is there any way I could have Python stop whining and give me the error message JSON that I know Imgur returns?

like image 619
Azure Flash Avatar asked Dec 22 '12 00:12

Azure Flash


1 Answers

Well, I'll be damned. I tried taking out the encoding functions and just straight up forming the string, and I got it to work. I guess Imgur's API expects the non-form-encoded URL?

Oh... or was it because I used both quote_plus() and url_encode(), encoding the URL twice? That seems even more likely...

This is my working solution, at long last, for something that took me a day when I thought it'd take an hour at most:

def sideLoad(imgURL):
    img = urllib.quote_plus(imgURL)
    req = urllib2.Request('https://api.imgur.com/3/image', 'image=' + img)
    req.add_header('Authorization', 'Client-ID ' + clientID)
    response = urllib2.urlopen(req)
    response = json.loads(response.read())
    return str(response[u'data'][u'link'])

It's not a final version, mind you, it still lacks some testing (I'll see whether I can get rid of quote_plus(), or if it's perhaps preferable to use url_encode alone) as well as error handling (especially for big gifs, the most frequent case of failure).

I hope this helps! I searched all over Google, Imgur and Stack Overflow and the information about anonymous usage of APIv3 were confusing (and drowned in a sea of utterly horrifying OAuth2 stuff).

like image 142
Azure Flash Avatar answered Oct 23 '22 03:10

Azure Flash