CLI tool
n8henrie/pycookiecheat avatar
n8henrie/pycookiecheat

pycookiecheat: reusing your browser session inside a Python script

Borrow cookies from your browser's authenticated session for use in Python scripts.

827 stars117 forksPythonMIT

At a glance

What is it?
pycookiecheat is an MIT licensed Python package that copies decrypted cookies out of Chrome, Brave, Firefox or Slack on macOS and Linux so a requests session can act as an already logged in user. It suits someone automating a download that sits behind a login, and it is a poor fit on Windows, on a locked down Linux keyring, or anywhere the credential handling rules of an employer apply.
Who is it for?
pycookiecheat suits a developer with one specific problem, a script that needs to talk to a site the browser is already authenticated with, where re-implementing a login flow or handling a second factor would be more work than reusing the session.
Can I use it commercially?
Yes. MIT 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 117 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 October 24, 2026, and from our analysis. They are not legal advice.

Editorial analysis

Reusing the session you already have instead of logging in again

The package describes itself in one line: borrow cookies from your browser's authenticated session for use in Python scripts.

That is a narrow job, and the narrowness is the point. Many sites are easy to script until they are not, and the not is usually the login: a password to store, a captcha, a second factor, a session cookie that rotates. If you already have a browser logged in, the cookies in that browser profile are a valid credential, and this library reads them.

The mechanism is decryption. Browsers do not store cookie values in plain text, they store them encrypted with a key held in the operating system keychain, and pycookiecheat's job is to ask the keychain for that key and decrypt the cookie database. The features list is specific about the coverage: it returns decrypted cookies from Google Chrome, Brave, or Slack, on macOS or Linux. It can also output cookies to a file, credited to a contributor in the README.

The audience is a developer writing a one off or a small automation, not a service. The homepage is a blog post from 2013 about using Chrome's cookies for easier downloading with Python requests, which tells you the original use case: a download script that needed the session you had already established in the browser.

The project is MIT licensed, the primary language is Python, and the last push to the repository was on 2026-06-29, with no GitHub releases published.

The CLI copies cookies to stdout or to a Netscape file

The command line tool can be run as a Python module or through a standalone console script, and the entry point in the package metadata is a console script named pycookiecheat pointing at pycookiecheat.__main__:main.

console
$ python -m pycookiecheat --help
usage: pycookiecheat [-h] [-b BROWSER] [-p FIREFOX_PROFILE] [-o OUTPUT_FILE]
                     [-v] [-c COOKIE_FILE] [-V] url

The interface is one positional argument, the url, and a small set of options. The browser option selects which browser to read, the firefox profile option selects which Firefox profile to search, the output file option writes to a file in Netscape cookie file format, the cookie file option points at an existing cookie file, verbose increases logging verbosity and may be repeated with a default of logging.ERROR, and the version flag prints the version.

By default it prints the cookies to stdout as JSON, and it can also output a file in Netscape Cookie File Format. That default is the right one for piping into another tool, and the Netscape format exists because that is the format curl and wget understand with a cookie jar argument.

The verbose flag deserves a note because it is a repeatable flag with a level default, which is the sort of interface that lets you debug a failure without turning on a wall of output.

The library call is one function

Used as a library, the whole API in the README example is three lines of interest.

python
from pycookiecheat import BrowserType, get_cookies
import requests

url = 'https://n8henrie.com'

# Uses Chrome's default cookies filepath by default
cookies = get_cookies(url)
r = requests.get(url, cookies=cookies)

# Using an alternate browser
cookies = get_cookies(url, browser=BrowserType.CHROMIUM)

get_cookies takes the url and returns a cookie collection that requests accepts directly as the cookies argument. The browser argument selects an alternative browser, and BrowserType is an enum, so the choice is checked by the type rather than by a string.

There is a second, less obvious parameter. The cookie_file keyword argument specifies a different path to the file containing your cookies, so get_cookies(url, cookie_file='/abspath/to/cookies') works with a cookie file you have already located. The README suggests that this may let you retrieve cookies for alternative Chromium-based browsers by manually specifying a path such as "/home/username/.config/BrowserName/Default/Cookies".

That path is worth understanding rather than guessing at. The library knows the layout of the browsers it supports, and when it does not know yours, pointing it at the cookie database is the escape hatch. It is also the reason the tool is usable for a browser fork that the author does not maintain support for, at the cost of you knowing where the file lives.

The keyring, not the cookies, is the hard part

The installation notes carry the most important operational content in the README, and they are about Linux keyrings.

Chrome is now using a few different keyrings to store the Chrome Safe Storage password instead of a hard-coded password. Pycookiecheat does not work with most of these, and the README is honest about the reason: the author's enthusiasm for adding support for keyrings they do not use is limited. Users have contributed code that seems to work with some recent Ubuntu desktops, and to get it working you may have to install libsecret-1-dev, python-gi and python3-gi, and if you are installing into a virtualenv, which the README calls highly recommended, you need the --system-site-packages flag to get access to the necessary libraries.

shell
sudo apt-get install libsecret-1-dev python-gi python3-gi

Alternatively, some users have suggested running Chrome with the --password-store=basic or --use-mock-keychain flags.

KDE has its own variant of the same problem. On KDE, Chrome defaults to using KWallet, and for pycookiecheat to support it the dbus-python package must be installed.

Put together, the picture is clear. The cookie decryption is the easy part. The part that varies is where the operating system keeps the key, and that is a property of the desktop environment, not of the browser. A headless Linux server with no keyring, and a desktop with KWallet, are different problems even though the code path is the same.

Firefox profile naming changed and the answer moved to SQLite

The troubleshooting section on Firefox profiles is the most useful piece of documentation in the repository, because it describes a change that broke a lot of working setups.

The profile argument, --firefox-profile in the command line, specifies the profile in the Firefox profile directory to load from. The example lists the directory on Linux.

console
$ ls ~/.mozilla/firefox
'Profile Groups'   profiles.ini   wsw6frhw.default

And you can then select the profile with --firefox-profile=wsw6frhw.default.

The complication arrived around 2025, when Firefox added a new profile system that coexists with the old one. The metadata for legacy profiles is still in PROFILE_DIR/profiles.ini, but to find the path for the new profiles you need to check PROFILE_DIR/Profile Groups/*.sqlite, and the README shows the query.

console
$ sqlite3 ~/snap/firefox/common/.mozilla/firefox/Profile\ Groups/*.sqlite 'SELECT * FROM profiles;'
1|wsw6frhw.default|Original profile|shopping|[email protected]|rgb(255,255,255)|rgb(28,27,34)

So the answer to the question of which profile you are in is now a database query rather than a directory listing, at least for the new profile system. Anyone whose script started failing to find cookies after a Firefox update is looking at this section.

Windows is out of scope by the author's own statement

There is a short section answering the question about Windows, and it is worth quoting the reasoning rather than the conclusion alone.

The author writes that they do not use Windows or have a PC, so they will not be adding support themselves, and invite a pull request.

That is an honest scope statement rather than a technical impossibility, and it shapes what you can expect from the project. The supported environments in the feature list are macOS and Linux, and the troubleshooting guidance covers Ubuntu desktops, KDE and Firefox on Linux, plus a note about building the cryptography module on macOS with Homebrew and OpenSSL flags.

For a Windows user the practical options are to use the library under WSL against a browser profile in the Linux file system, to run the automation somewhere else, or to contribute the support. The two cryptography installation notes, one for macOS and one for Linux, both say the same thing in effect, which is that you may need the OpenSSL and build headers before pip can build the module.

The other installation route is the unreleased master branch, installed straight from Git.

shell
python -m pip install git+https://github.com/n8henrie/pycookiecheat@master

That is the route to take when you need a fix that has not been released, and it is also the route with no version pinning at all, which is worth remembering when you decide what to run in CI.

Two runtime dependencies, strict typing and a Nix flake

The packaging metadata is tidy enough to be worth reading, because it says a lot about the project's shape.

The runtime dependencies are just two, cryptography at 43 and keyring at 25, both pinned with the star syntax. That is a small surface: one library to decrypt the cookie database and one to ask the operating system for the key.

The build system is setuptools with setuptools_scm, and the version is read dynamically from the pycookiecheat.__version__ attribute rather than written in the metadata. The readme is assembled from README.md and CHANGELOG.md, which is why the changelog shows up in the long description of the package on PyPI.

Type checking is strict by configuration. The mypy section enables check_untyped_defs, disallow_untyped_calls and disallow_untyped_defs, with follow_imports set to silent and ignore_missing_imports on. The ruff configuration sets a line length of 79, which is a deliberate choice that keeps the code style consistent with a long standing Ruby and Python small library aesthetic.

The test extras cover mypy, playwright, pytest, ruff and tox. Playwright in the test set is interesting, since it suggests browser based testing rather than pure unit tests, and the tox configuration in the repository root supports running the suite across environments.

For development the README gives a four step setup, with a virtual environment and an editable install of the dev extras.

shell
git clone https://github.com/n8henrie/pycookiecheat.git
cd pycookiecheat
python3 -m venv .venv
./.venv/bin/python -m pip install -e .[dev]

The repository also carries a flake.nix and flake.lock, so a Nix user gets a reproducible environment, along with tox.ini, a .python-version file, AUTHORS.md, CHANGELOG.md and a TODO.txt.

Editorial conclusion

pycookiecheat suits a developer with one specific problem, a script that needs to talk to a site the browser is already authenticated with, where re-implementing a login flow or handling a second factor would be more work than reusing the session. It does not suit Windows, where the author states plainly that support will not be added, and it does not suit a machine whose browser credentials are in a keyring the library cannot read, such as a KDE system without dbus-python installed. Before you rely on it, check that the browser stores its safe storage password somewhere the keyring backend can reach, that the script runs as the same user as the browser profile, and note that the last push to the repository was on 2026-06-29 with no GitHub releases, so you are pinning a commit rather than a version.

Frequently asked questions

What does pycookiecheat do?

It borrows cookies from your browser's authenticated session for use in Python scripts, returning decrypted cookies from Google Chrome, Brave or Slack on macOS or Linux, and it can optionally write them to a file in Netscape cookie file format.

How do I install pycookiecheat?

Run python3 -m pip install pycookiecheat. Version 0.4.0 and later require Python 3, and on Linux you may need libsecret-1-dev, python-gi and python3-gi installed along with a virtualenv created with the --system-site-packages flag, depending on which keyring your desktop uses.

How do I use pycookiecheat from a Python script?

Import get_cookies and BrowserType, call get_cookies(url) to get cookies you can pass to requests.get(url, cookies=cookies), and pass browser=BrowserType.CHROMIUM to read a different browser, or cookie_file to point at a specific cookie database.

Does pycookiecheat support Windows?

Not currently. The README states that the author does not use Windows or have a PC and will not be adding support themselves, while inviting pull requests, and the feature list covers macOS and Linux only.

How do I find the right Firefox profile?

Use --firefox-profile with the profile directory name, for example --firefox-profile=wsw6frhw.default. Since the new Firefox profile system added around 2025, the path for new profiles is in the Profile Groups directory as a SQLite file, and the README shows the query to run against it.

Official sources

  1. Issues
  2. License: MIT
  3. n8henrie/pycookiecheat on GitHub
  4. Project website
  5. README
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.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/n8henrie-pycookiecheat.svg)](https://hysenlabs.com/projects/n8henrie-pycookiecheat)

Was this useful?