A small FastAPI service that re-implements, approximately, how Redlib talks to Reddit - so you get a REST API that serves Reddit data the way Redlib's own backend does, instead of hitting Reddit's official rate-limited public API directly.
Per Redlib's own README and the maintainer's public write-up:
- OAuth "installed_client" token spoofing - Reddit's official Android app
supports anonymous/logged-out browsing via the
https://oauth.reddit.com/grants/installed_clientgrant. It needs no username/password, just a public Androidclient_id+ a randomdevice_id. Using this grant makes Reddit treat your traffic like the real app, which gets a much higher rate limit than a generic script hittingreddit.com/.jsoncold. - Token refresh every ~24h, matching the real app's cadence, instead of re-authenticating per request.
- Header mimicking - Android-shaped
User-Agenton every call. - Fallbacks when something breaks: retry with backoff on 429/5xx,
force-refresh the token on 401/403, rotate to another client_id if one's
blocked, and if OAuth itself is unreachable, drop down to the public
unauthenticated
*.jsonendpoints onwww.reddit.comthenold.reddit.com.
This project implements that same chain in Python:
reddit_client.py
├── _fetch_token() # installed_client OAuth grant
├── _get_token() # cache + refresh + client_id rotation
├── _request_oauth() # oauth.reddit.com, retries once on 401/403
├── _request_public_json() # unauthenticated *.json fallback
└── get() # walks FALLBACK_TIERS, retries, stale-cache last resort
It's an approximation, not a port of Redlib's Rust source - the request shape and fallback strategy match, the exact header set and edge-case handling don't claim byte-for-byte parity.
pip install -r requirements.txt
uvicorn main:app --reload --port 8080| Route | Mirrors |
|---|---|
GET /r/{subreddit}/{sort} |
reddit.com/r/{sub}/{hot,new,top,rising,controversial}.json |
GET /r/{subreddit}/about |
subreddit info |
GET /r/{subreddit}/comments/{post_id} |
post + comment tree |
GET /comments/{post_id} |
same, short form |
GET /user/{username}/about |
user profile |
GET /user/{username}/{sort} |
overview/submitted/comments/upvoted/gilded |
GET /search?q=...&subreddit=... |
search, optionally scoped to a sub |
GET /best |
r/popular-style front page |
GET /raw/{path} |
escape hatch - any reddit.com JSON path through the same fallback chain |
curl http://localhost:8080/r/python/hot
curl http://localhost:8080/r/python/comments/abc123
curl "http://localhost:8080/search?q=rust&subreddit=programming"
curl "http://localhost:8080/raw/r/python/top?t=week"ANDROID_CLIENT_IDSinconfig.pyholds the historical public Android client_id. Reddit rotates/blocks these from time to time - if token requests start failing with 400/401, you'll need to capture a current one yourself (mitmproxy against the real app, same technique the Redlib maintainer used) or pull whatever Redlib'ssrc/client.rscurrently uses, and add it to the list. Multiple entries let the rotation logic actually do something when one gets blocked.- Cache is in-memory and per-process - fine for a single
uvicornworker, not for a multi-process/multi-machine deployment as-is. - ToS - this hits Reddit the same way Redlib does. Whether that's fine for your use case (personal self-hosted frontend vs. high-volume scraping) is worth checking against Reddit's terms yourself.
config.py- client_id pool, UA pools, fallback tier order, timing constantscache.py- tiny TTL cache (fresh + stale reads)reddit_client.py- the actual client + fallback chainmain.py- FastAPI routes