How to form an anonymous request to Imgur's APIv3
Asked Answered
S

2

6

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?

Swanger answered 22/12, 2012 at 0:48 Comment(2)
Did you try {'Authorization': clientID}? That is what it seems like to be, to me. That is, req.add_header('Authorization', clientID)Stork
Yeah, I think I tried that, as well as {'Client-ID': clientID} I'm pretty sure. I just tried the form you suggested just to know what error it gives, and it's a 403 forbidden. That wasn't the problem, it turns out..Swanger
S
5

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).

Swanger answered 22/12, 2012 at 3:6 Comment(2)
I've removed the {'key': clientSecret} POST parameter and it still works. It works without quote_plus() too, but I haven't tried URLs with spaces in them.Swanger
Update: links pasted from browsers replace the space with %20. When an URL like that is given to Imgur without any encoding, it fails (400 Bad Request). If I encode it (I use quote_plus, urlencode seems to have the same effect but can take a whole list of key/value pairs), the space becomes %2520 and the image uploads just fine. Hm.Swanger
G
0

In python 3.4 using urllib I was able to do it like this:

import urllib.request
import json

opener = urllib.request.build_opener()
opener.addheaders = [("Authorization", "Client-ID"+ yourClientId)]
jsonStr = opener.open("https://api.imgur.com/3/image/"+pictureId).read().decode("utf-8")
jsonObj = json.loads(jsonStr)
#jsonObj is a python dictionary of the imgur json response.
Globe answered 10/7, 2014 at 0:47 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.