Skip to content

Instantly share code, notes, and snippets.

@kemitche
Last active August 19, 2025 09:04
Show Gist options
  • Save kemitche/9749639 to your computer and use it in GitHub Desktop.
Save kemitche/9749639 to your computer and use it in GitHub Desktop.
reddit OAuth 2.0 Python Webserver Example
#!/usr/bin/env python
from flask import Flask, abort, request
from uuid import uuid4
import requests
import requests.auth
import urllib
CLIENT_ID = None # Fill this in with your client ID
CLIENT_SECRET = None # Fill this in with your client secret
REDIRECT_URI = "http://localhost:65010/reddit_callback"
def user_agent():
'''reddit API clients should each have their own, unique user-agent
Ideally, with contact info included.
e.g.,
return "oauth2-sample-app by /u/%s" % your_reddit_username
'''
raise NotImplementedError()
def base_headers():
return {"User-Agent": user_agent()}
app = Flask(__name__)
@app.route('/')
def homepage():
text = '<a href="%s">Authenticate with reddit</a>'
return text % make_authorization_url()
def make_authorization_url():
# Generate a random string for the state parameter
# Save it for use later to prevent xsrf attacks
state = str(uuid4())
save_created_state(state)
params = {"client_id": CLIENT_ID,
"response_type": "code",
"state": state,
"redirect_uri": REDIRECT_URI,
"duration": "temporary",
"scope": "identity"}
url = "https://ssl.reddit.com/api/v1/authorize?" + urllib.urlencode(params)
return url
# Left as an exercise to the reader.
# You may want to store valid states in a database or memcache.
def save_created_state(state):
pass
def is_valid_state(state):
return True
@app.route('/reddit_callback')
def reddit_callback():
error = request.args.get('error', '')
if error:
return "Error: " + error
state = request.args.get('state', '')
if not is_valid_state(state):
# Uh-oh, this request wasn't started by us!
abort(403)
code = request.args.get('code')
access_token = get_token(code)
# Note: In most cases, you'll want to store the access token, in, say,
# a session for use in other parts of your web app.
return "Your reddit username is: %s" % get_username(access_token)
def get_token(code):
client_auth = requests.auth.HTTPBasicAuth(CLIENT_ID, CLIENT_SECRET)
post_data = {"grant_type": "authorization_code",
"code": code,
"redirect_uri": REDIRECT_URI}
headers = base_headers()
response = requests.post("https://ssl.reddit.com/api/v1/access_token",
auth=client_auth,
headers=headers,
data=post_data)
token_json = response.json()
return token_json["access_token"]
def get_username(access_token):
headers = base_headers()
headers.update({"Authorization": "bearer " + access_token})
response = requests.get("https://oauth.reddit.com/api/v1/me", headers=headers)
me_json = response.json()
return me_json['name']
if __name__ == '__main__':
app.run(debug=True, port=65010)
@prashant2796
Copy link

prashant2796 commented Feb 16, 2018

what is user agent and where can i find it ? i am implementing this code for google

@neonoatmeal
Copy link

@prashant2796 A user agent is a description that tells a little bit about what your using such as "MozillaFirefox17.1;Ubuntu16.04;Python3; by: Mynameiskaleb"
From what I can tell, some sites expect them to be in certain formats like Firefox and others aren't too picky as long as it gives a decent description.

@srivatsshankar
Copy link

This is brilliant! This is the first time I have understood what is going on with OAuth! Simple and clear. Thank you!

@AbdulhadeAhmad
Copy link

Thank you very much, this helped me a lot!

@ayhamakeed2000
Copy link

ayhamakeed2000 commented Aug 19, 2025

In the final step when I try to fetch the token I got this response:
{'message': 'Unauthorized', 'error': 401}

After asking Gemini about that It said that Reddit has changed the fetch token url
the new url I used is: 'https://www.reddit.com/api/v1/access_token' and its worked

so the get_token method looks like:

def get_token(code):
    client_auth = requests.auth.HTTPBasicAuth(CLIENT_ID, CLIENT_SECRET)
    post_data = {"grant_type": "authorization_code",
                 "code": code,
                 "redirect_uri": REDIRECT_URI}

    headers = base_headers()
    # Use the corrected URL below
    response = requests.post("https://www.reddit.com/api/v1/access_token",
                             auth=client_auth,
                             headers=headers,
                             data=post_data)
    token_json = response.json()  
    # Check if 'access_token' is in the response before trying to access it
    if "access_token" in token_json:
        return token_json["access_token"]
    else:
        # Handle the error gracefully if the token isn't in the response
        print("Error fetching token.")
        return None

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment