Search code examples
pythonhttppython-requestsimgur

requests post to imgur


from oauth_hook import OAuthHook
import requests, json
OAuthHook.consumer_key = "KEYHERE" 
OAuthHook.consumer_secret = "SECRET HERE"
oauth_hook = OAuthHook("TOKEN_KEY_HERE", "TOKEN_SECRET_HERE", header_auth=True)
headers = {'content-type': 'application/json'}
client = requests.session(hooks={'pre_request': oauth_hook}, headers=headers)
payload = {"title":"album title"}
r = client.post("http://api.imgur.com/2/account/albums.json",payload)
print r.text

This should create an album with the title album title how instead the return string is

{
    "albums": {
        "id": "IMGURID",
        "title": "",
        "description": "",
        "privacy": "public",
        "cover": "",
        "order": 0,
        "layout": "blog",
        "datetime": "2012-12-05 15:48:21",
        "link": "IMGUR LINK",
        "anonymous_link": "ANONYLINK"
    }
}

Does anyone have a solution for setting the album title using requests?

here is a link to the imgur API docs http://api.imgur.com/resources_auth


Solution

  • You are not posting JSON data; instead it'll be converted to URL-encoded data instead. requests does not provide automatic JSON encoding, even if you do set the content type to application/json.

    Use the json module to encode:

    import json
    
    r = client.post("http://api.imgur.com/2/account/albums.json", json.dumps(payload))
    

    You can see this when using the http://httpbin/post POST echo service:

    >>> import json, requests, pprint
    >>> headers = {'content-type': 'application/json'}
    >>> payload = {"title":"album title"}
    >>> pprint.pprint(requests.post('http://httpbin.org/post', payload, headers=headers).json)
    {u'args': {},
     u'data': u'title=album+title',
     u'files': {},
     u'form': {},
     u'headers': {u'Accept': u'*/*',
                  u'Accept-Encoding': u'gzip, deflate, compress',
                  u'Connection': u'keep-alive',
                  u'Content-Length': u'17',
                  u'Content-Type': u'application/json',
                  u'Host': u'httpbin.org',
                  u'User-Agent': u'python-requests/0.14.2 CPython/2.7.3 Darwin/11.4.2'},
     u'json': None,
     u'origin': u'xx.xx.xx.xx',
     u'url': u'http://httpbin.org/post'}
    >>> pprint.pprint(requests.post('http://httpbin.org/post', json.dumps(payload), headers=headers).json)
    {u'args': {},
     u'data': u'{"title": "album title"}',
     u'files': {},
     u'form': {},
     u'headers': {u'Accept': u'*/*',
                  u'Accept-Encoding': u'gzip, deflate, compress',
                  u'Connection': u'keep-alive',
                  u'Content-Length': u'24',
                  u'Content-Type': u'application/json',
                  u'Host': u'httpbin.org',
                  u'User-Agent': u'python-requests/0.14.2 CPython/2.7.3 Darwin/11.4.2'},
     u'json': {u'title': u'album title'},
     u'origin': u'xx.xx.xx.xx',
     u'url': u'http://httpbin.org/post'}
    

    If you are using requests version 2.4.2 or newer, you can leave the encoding to the library; simply pass in the payload as the json keyword argument; incidentally it'll also set the correct Content-Type header in that case:

    r = client.post("http://api.imgur.com/2/account/albums.json", json=payload)