Python 3 with Requests trying to use Tumblr API, I get error 401?
Question: I have Python 3 and I am trying to post to Tumblr via API [link to API
documentation](https://www.tumblr.com/docs/en/api/v2). I keep getting an error
401 despite feeling like I am doing everything correctly. There is an official
API client in Python 2 but that feels a bit hard to follow and all other
mentions of it seem to be in PHP or Java. I also am not sure of the format to
post in after the 401 error because the documentation doesn't give any
explicit examples other than /post. My code:

    
    
    import requests
    from requests_oauthlib import OAuth1
    #variables for later
    client_key=""
    client_secret=""
    oauth_token=""
    oauth_token_secret=""
    
    #gets the values for the variables
    with open("API.txt", 'r') as readAPI:
        readAPI.readline()
        client_key=readAPI.readline()[23:]
        client_secret=readAPI.readline()[23:]
        oauth_token=readAPI.readline()[23:]
        oauth_token_secret=readAPI.readline()[23:]
    readAPI.close()
    
    #prints them to double check they are being read correctly
    print(client_key)
    print(client_secret)
    print(oauth_token)
    print(oauth_token_secret)
    
    #sets oauth for the connection
    oauth = OAuth1(client_key,
                   client_secret,
                   oauth_token,
                   oauth_token_secret)
    
    #check post that should return various blog stats
    r = requests.get("http://api.tumblr.com/v2/user/info" ,auth=oauth)
    
    print(r)
    

I am 100% sure I am getting the client key, the client secret, oauth token and
oauth token secret correct. I have double checked, the oauth tokens are both
put in the file that is being read manually and they are printed before the
connection attempt. I am 100% sure it is correct. I'm wondering if Tumblr's
API is broken?

Edit: This is with print(repr())

    
    
    'client_key'
    'client_secret'
    'oauth_token'
    'oauth_token_secret'
    {"meta":{"status":401,"msg":"Not Authorized"},"response":[]}
    

This is what happens after trying a new code and with Steven's method with
JSON.

    
    
    b'{"meta":{"status":401,"msg":"Not Authorized"},"response":[]}'
    


Answer: Instead of doing this:

    
    
    print(client_key)
    

What is the output of this?

    
    
    print(repr(client_key))
    

You're using `readline`, which includes a newline character at the end of each
line:

    
    
    $ cat foo.txt
    key
    secret
    blabla
    
    $ python3.4
    >>> f = open("foo.txt")
    >>> print(repr(f.readline()))
    'key\n'
    >>> print(repr(f.readline()))
    'secret\n'
    >>> print(repr(f.readline()))
    'blabla\n'
    

Have you tried stripping the newline character off of each line?

* * *

**Edit** : Updating my post based on @user2853325's comments. Your code works
for me under Python 3.4, requests==2.5.2, and requests-oauthlib==0.4.2.

API.json (redacted the keys/secrets):

    
    
    {
        "client_key": "XXXXXXXXXXXXXXXXXXXXdG7zXIMcDidwQ5pMHuQTbxyhNINrCE",
        "client_secret": "XXXXXXXXXXXXXXXXXXXX72A5HQO1axydP5nlOWCTQx4ECfXfyX",
        "oauth_token": "XXXXXXXXXXXXXXXXXXXX8WAnqMBWaAdnGhnc4gWhJ4j6cufK1W",
        "oauth_token_secret": "XXXXXXXXXXXXXXXXXXXX8Kf82k65JzIcMU7QUp54ssPEzJd7my"
    }
    

tumblr.py:

    
    
    import json
    
    import requests
    from requests_oauthlib import OAuth1
    
    #gets the values for the variables
    with open("API.json") as f:
        credentials = json.load(f)
    
    #prints them to double check they are being read correctly
    print(credentials)
    
    #sets oauth for the connection
    oauth = OAuth1(
        credentials['client_key'],
        credentials['client_secret'],
        credentials['oauth_token'],
        credentials['oauth_token_secret']
    )
    
    #check post that should return various blog stats
    r = requests.get("http://api.tumblr.com/v2/user/info", auth=oauth)
    print(r)
    print(r.content)
    

Output (redacted the oauth stuff):

    
    
    $ bin/python tumblr.py
    {'oauth_token_secret': 'XXXXXXXXXXXXXXXXXXXX8Kf82k65JzIcMU7QUp54ssPEzJd7my', 'client_secret': 'XXXXXXXXXXXXXXXXXXXX72A5HQO1axydP5nlOWCTQx4ECfXfyX', 'client_key': 'XXXXXXXXXXXXXXXXXXXXdG7zXIMcDidwQ5pMHuQTbxyhNINrCE', 'oauth_token': 'XXXXXXXXXXXXXXXXXXXX8WAnqMBWaAdnGhnc4gWhJ4j6cufK1W'}
    <Response [200]>
    b'{"meta":{"status":200,"msg":"OK"},"response":{"user":{"name":"lost-theory","likes":0,"following":2,"default_post_format":"html","blogs":[{"title":"Untitled","name":"lost-theory","posts":0,"url":"http:\\/\\/lost-theory.tumblr.com\\/","updated":0,"description":"","is_nsfw":false,"ask":false,"ask_page_title":"Ask me anything","ask_anon":false,"followed":false,"can_send_fan_mail":true,"share_likes":true,"likes":0,"twitter_enabled":false,"twitter_send":false,"facebook_opengraph_enabled":"N","tweet":"N","facebook":"N","followers":0,"primary":true,"admin":true,"messages":0,"queue":0,"drafts":0,"type":"public"}]}}}'
    

So now that I've tested your code out for myself:

  * How did you get the `oauth_token` and `oauth_token_secret`? I got mine by clicking "Explore API" on the [Applications developer page](https://www.tumblr.com/oauth/apps).
  * You don't need to call `readAPI.close()`, as the `with` block automatically closes the file for you (see the [official docs](https://docs.python.org/2/tutorial/inputoutput.html#methods-of-file-objects)).
  * I used JSON for storing and reading the credentials, that way I'm 100% sure that I'm getting the correct strings. The code is cleaner too. I'm still suspicious about the way you're reading lines from the file and slicing them.
  * Try printing `r.content` in your code the same way I am. Does it give you a more descriptive error message than "401 Unauthorized"?

