PRAW: the Python Reddit API Wrapper, reviewed for real workloads
PRAW, an acronym for "Python Reddit API Wrapper", is a python package that allows for simple access to Reddit's API.
At a glance
- What is it?
- PRAW wraps Reddit's API in Python objects and handles rate limiting for you. It is a solid fit for scripts and bots, but the README points asynchronous projects at Async PRAW instead.
- Who is it for?
- Adopt PRAW when you need a synchronous, object-oriented client for Reddit's API and you can register a script-type OAuth application. Do not adopt it if your codebase is asynchronous, since the README points those users at Async PRAW, or if you need an interface in a language other than Python.
- Can I use it commercially?
- Yes. BSD-2-Clause is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 2 days ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 30, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What PRAW solves, and who it is written for
Reddit's API is HTTP with OAuth, and any client that talks to it directly has to manage token refresh, request pacing and the response shapes that come back. PRAW, short for Python Reddit API Wrapper, is a Python package that puts a typed object layer over that transport. The README states the goal plainly: PRAW "aims to be easy to use and internally follows all of Reddit's API rules", and it adds that with PRAW "there's no need to introduce sleep calls in your code". Rate limiting is the package's job, not yours.
The audience is Python developers writing scripts, bots and data collection jobs against Reddit. The pyproject.toml classifiers mark the project as Production/Stable, intended for developers, typed, and OS independent, with Python 3.10 through 3.14 listed. That is a narrow but well-defined audience. If you are not writing Python, PRAW gives you nothing.
How PRAW is put together: prawcore, websocket-client and a typed surface
The repository is a single package directory, praw/, alongside tests/, docs/ and tools/. The runtime dependencies in pyproject.toml tell you where the work is split. prawcore>=4,<5 is the HTTP and OAuth layer. websocket-client>=0.54.0,<2 backs streaming, which is what makes PRAW able to sit on a comment or submission stream rather than poll. defusedxml==0.7.1 is pinned exactly, which is a hardening choice for XML parsing. update_checker>=1.0,<2.0 is what lets the library warn you when a newer release exists. typing-extensions is pulled in only on Python 3.10, which matches the requires-python = ">=3.10" floor.
The design consequence is that PRAW is not a thin HTTP wrapper. Objects such as Subreddit, Submission and Comment are lazy: the README's quickstart calls reddit.subreddit("test").submit(...) and reddit.submission(url="https://www.reddit.com/comments/5e1az9") without any explicit fetch step. Iteration is where the pacing shows up, for example reddit.front.hot(limit=256). The limit argument is a client-side bound on how many items you walk, and the library spaces the underlying requests. That is the mechanism behind the no-sleep claim.
One thing the README does not cover is pagination semantics beyond limit, or what happens when a listing is exhausted mid-iteration. The documentation site is the place that would answer it; the README simply defers there.
Installing PRAW and posting your first comment
PRAW supports Python 3.10 and newer. The README recommends uv and gives pip as the alternative, so either of these installs the current release from PyPI:
uv add prawpip install prawIf you need unreleased code rather than the latest release, the README gives this command for the development version:
pip install --upgrade https://github.com/praw-dev/praw/archive/main.zipThe quickstart assumes you already hold credentials for a script-type OAuth application, so registering that application on Reddit comes first. With the four credential values in hand, the client is constructed like this:
import praw
reddit = praw.Reddit(
client_id="CLIENT_ID",
client_secret="CLIENT_SECRET",
password="PASSWORD",
user_agent="USERAGENT",
username="USERNAME",
)The user_agent value is not decoration. The README ties the no-sleep behaviour to it: "Give your client an appropriate user agent and you're set." A generic or missing user agent is the most common way a first script behaves worse than expected. Once the instance exists, the README's own first interaction is a submission reply:
submission = reddit.submission(url="https://www.reddit.com/comments/5e1az9")
submission.reply("Super rad!")You should see the reply appear on that thread under the account you authenticated as. The same quickstart shows reading without writing, which is the safer first test: iterating reddit.front.hot(limit=256) and printing submission.score.
Where PRAW is the wrong tool
The README's own warning is the clearest limitation. "If you plan on using PRAW in an asynchronous environment, (e.g., discord.py, asyncio) it is strongly recommended to use Async PRAW." PRAW is synchronous. Dropping it into an event loop means blocking calls inside your coroutine, and the README does not offer a workaround, it points at a different package with "the same features".
The second limitation is structural rather than documented: PRAW is a client for an API it does not control. The dependency pins show how tightly the stack is coupled. prawcore is constrained to the 4.x line and defusedxml to exactly 0.7.1, so a breaking change upstream in prawcore lands as a PRAW release, and a security fix in defusedxml lands as a pin bump. You inherit that release cadence.
There is also a boundary around credentials. The quickstart's constructor takes password and username, which is the script-type application flow. The README does not describe an installed-app or read-only flow in the quickstart, so if your use case is anonymous reading, the quickstart is not the path you want and the documentation is where you would look.
PRAW against talking to Reddit's API directly
The real alternative is not another wrapper, it is requests plus your own OAuth handling, or a different language's client. The difference is where the complexity sits. With requests you write the token exchange, the refresh, the retry on 429, the backoff, and the mapping from JSON to something usable. The pyproject.toml test group includes requests>=2.20.1,<3, so PRAW itself builds on that same library, which is a fair signal that the wrapper is not hiding a different transport, only the bookkeeping above it.
With PRAW you get the object model and the pacing, at the cost of the library's opinions about how listings and lazy objects behave. That trade is usually worth it for a bot that posts and replies, and usually not worth it for a one-off script that fetches a single endpoint, where the dependency tree (prawcore, websocket-client, defusedxml, update_checker) is more surface than the task needs. Async PRAW is the other alternative, and it is not a competitor so much as the same project's answer for a different concurrency model.
Release cadence, licence and upgrade cost
The last push to the repository was on 2026-09-21, and the most recent release listed is v8.0.3 on 2026-08-12, preceded by v8.0.2 in June and v8.0.1 in June. Releases are frequent and versioned, and the package ships a CHANGES.rst at the repository root, with the changelog also published on the documentation site. That is the file to read before bumping a major version.
The licence is BSD-2-Clause, declared in pyproject.toml as license = { file = "LICENSE.txt" }. A two-clause BSD licence is permissive: it permits use and redistribution with the copyright notice and disclaimer retained, and it does not carry the patent grant or the naming restrictions that some other permissive licences do. That is a description of the licence text, not legal advice; if your organisation has licence policy, the file to hand to it is LICENSE.txt.
Upgrade cost concentrates in the pinned dependencies. The prawcore>=4,<5 bound means PRAW 8.x will not silently jump to a prawcore 5 line, and defusedxml==0.7.1 means that pin moves only when PRAW moves it. In practice, upgrading PRAW is a matter of reading CHANGES.rst and checking that your installed prawcore still satisfies the bound.
Editorial conclusion
Adopt PRAW when you need a synchronous, object-oriented client for Reddit's API and you can register a script-type OAuth application. Do not adopt it if your codebase is asynchronous, since the README points those users at Async PRAW, or if you need an interface in a language other than Python. Verify first that your Python version is 3.10 or newer, that the installed prawcore version satisfies the prawcore>=4,<5 pin, and that your account's API access matches what you intend to automate.
Frequently asked questions
What does PRAW stand for?
PRAW is an acronym for "Python Reddit API Wrapper", as stated in the README and the package description in pyproject.toml.
How do I install PRAW?
The README recommends uv and gives pip as the alternative, so uv add praw or pip install praw installs the current release. PRAW is supported on Python 3.10 and newer.
Is PRAW free to use?
PRAW is released under the BSD-2-Clause licence, declared in pyproject.toml as license = { file = "LICENSE.txt" }. That is a permissive licence rather than a paid product.
Can I use PRAW with asyncio or discord.py?
The README says that in an asynchronous environment it is strongly recommended to use Async PRAW instead, described there as the official asynchronous version with the same features and similar usage.
Where is the PRAW documentation?
The README points to https://praw.readthedocs.io/, and pyproject.toml lists the same URL under the project's Documentation link. The README defers there for more examples beyond the quickstart.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/praw-dev-praw)