Search code examples
python-3.xoauthreddit

401 error when trying to authenticate with reddit api and python 3


I'm trying to authenticate using a python 3 script without PRAW or any other wrapper. Both reddit's official documentation and what I've found searching refer to python 2's urllib utils. This is the guide I'm using to write the code.

I've set up in my reddit profile an application configuration for a script application. Extracted from it both app_password and app_id. I'm also using my reddit account credentials, user_id and user_psw, in order to authenticate as displayed in the guide previously linked.

This is my code:

import urllib.request as request
import urllib.parse as parse

pman = request.HTTPPasswordMgrWithDefaultRealm()
pman.add_password(None, "https://reddit.com",
                                  app_id,
                                  app_password)
handler = request.HTTPBasicAuthHandler(pman)
opener = request.build_opener(handler)
request.install_opener(opener)

        # headers
        d = {"grant_type": "password",
             "username": user_id,
             "password": user_pass}
        post_data = parse.urlencode(d).encode("utf-8")

        headers = {"User-Agent": "QuickParsingScript/0.1 by user_id"}

response = request.Request("https://reddit.com/api/v1/access_token",
                                   data=post_data, headers=headers)

request.urlopen(response) # urllib.error.HTTPError: HTTP Error 401: Unauthorized

I've noticed that in python 2 urllib you can POST using a dictionary, but in p3's Request you have the following restriction:

The supported object types include bytes, file-like objects, and iterables.

I'm using urllib.parse.urlencode() because I found a SO talking about moving http auth calls and general urllib operations from a p2 codebase to a p3 one. So it might be an encoding problem? I've also thought about the password manager using "https://reddit.com" as uri rendering my request invalid but I don't know how to check whether the root cause comes from there or not.


Solution

  • Try "https://www.reddit.com" and "https://www.reddit.com/api/v1/access_token", respectively. I believe reddit returns 301 redirect for your request.

    Answered on r/redditdev.