Contributing Guide
July 13, 2026 · View on GitHub
-
Check the GitHub Issues for open issues that need attention.
-
Follow the How to submit a contribution Guide.
-
Make sure unit tests pass. Please read how to run unit tests below.
-
If you are fixing a bug:
- If you are resolving an existing issue, reference the issue ID in a commit message
(e.g., fixed #XXXX). - If the issue has not been reported, please add a detailed description of the bug in the Pull Request (PR).
- Please add a regression test case to check the bug is fixed.
- If you are resolving an existing issue, reference the issue ID in a commit message
-
If you are adding a new feature:
- Please open a suggestion issue first.
- Provide a convincing reason to add this feature and have it greenlighted before working on it.
- Add tests to cover the functionality.
-
Please follow Style Guide for Python Code.
Tests
To run tests, add your credentials to tests/creds.json and run
GS_CREDS_FILENAME="tests/creds.json" GS_RECORD_MODE="all" tox -e py -- -k "<specific test to run>"
On Windows (PowerShell), set the environment variables first — PowerShell has no inline VAR=value command prefix:
$env:GS_CREDS_FILENAME = "tests/creds.json"
$env:GS_RECORD_MODE = "all"
tox -e py -- -k "<specific test to run>"
The variables stay set for the rest of the PowerShell session. To clear them again, use
Remove-Item Env:GS_CREDS_FILENAME, Env:GS_RECORD_MODE — this matters in particular for
GS_RECORD_MODE, since leaving it set will keep later runs online.
The rest of this guide shows the commands in bash form; on Windows, apply the same translation
(export the variables with $env:NAME = "value", then run the command on its own line).
For more information on tests, see below.
CI checks
If the test or lint commands fail, the CI will fail, and you won't be able to merge your changes into gspread.
Use format to format your code before submitting a PR. Not doing so may cause lint to fail.
Install dependencies
pip install tox
Run tests (offline)
If the calls to the Sheets API have not changed, you can run the tests offline. Otherwise, you will have to run them online to record the new API calls.
This will use the currently recorded HTTP requests + responses. It does not make any HTTP calls, and does not require an active internet connection.
tox -e py
Run a specific test
tox -e py -- -k TEST_NAME
The CI uses tox. For faster local development, you can set up an environment and use pytest, where -k TEST_NAME is used to filter to tests matching TEST_NAME. For more info run pytest --help.
python -m venv env
source env/bin/activate
pip install -r test-requirements.txt
pytest -k TEST_NAME
On Windows (PowerShell), the activation script lives elsewhere:
python -m venv env
.\env\Scripts\Activate.ps1
pip install -r test-requirements.txt
pytest -k TEST_NAME
If PowerShell refuses to run the activation script, allow local scripts for the current session with
Set-ExecutionPolicy -Scope Process -ExecutionPolicy RemoteSigned.
Format
tox -e format
Lint
tox -e lint
Render Documentation
The documentation uses reStructuredText markup and is rendered by Sphinx.
tox -e doc
The rendered documentation is placed into docs/build/html. index.html is an entry point.
Run tests (online)
gspread uses vcrpy to record and replay HTTP interactions with Sheets API.
GS_CREDS_FILENAME environment variable
You must provide Service account or OAuth user credentials using the GS_CREDS_FILENAME environment variable
in order to make HTTP requests to the Sheets API. Note, that service account can only be used in the
Google Workspace environment, as otherwise service accounts have no Drive storage quota and can't own files, which is
required to run tests.
To obtain the Service Account credentials
-
Follow the Using Service Account procedure
-
Point
GS_CREDS_FILENAMEat the key file you download from the Google Cloud Console (the one containingprivate_keyandclient_email).
To obtain the OAuth user credentials
-
Follow the Using OAuth Client ID procedure
-
Point
GS_CREDS_FILENAMEat theauthorized_user.jsonproduced by the browser flow — the file containingrefresh_token— not the OAuth client-secrets file, which the linked guide callscredentials.json.
GS_RECORD_MODE environment variable
You can control vcrpy's Record Mode using GS_RECORD_MODE environment variable. It can be:
all- record all HTTP requests, overwriting existing onesnew_episodes- record new HTTP requests and replay existing onesnone- replay existing HTTP requests only
In the following cases, you must record new HTTP requests:
- a new test is added
- an existing test is updated and does a new HTTP request
- gspread is updated and does a new HTTP request
Run tests online, but not capture any HTTP requests
GS_CREDS_FILENAME=<./YOUR_CREDS.json> tox -e py -- --disable-vcr
$env:GS_CREDS_FILENAME = "./YOUR_CREDS.json"
tox -e py -- --disable-vcr
--disable-vcr runs every request against the live API and leaves tests/cassettes/ untouched.
GS_RECORD_MODE is ignored in this mode.
Run test, capturing all HTTP requests
In some cases if the test suite can't record new episodes, or it can't replay them offline, you can run a complete update of the cassettes.
GS_CREDS_FILENAME=<./YOUR_CREDS.json> GS_RECORD_MODE=all tox -e py
$env:GS_CREDS_FILENAME = "./YOUR_CREDS.json"
$env:GS_RECORD_MODE = "all"
tox -e py
Run test, capturing only new HTTP requests
To record new HTTP requests:
- Remove the file holding the recorded HTTP requests of the test(s).
e.g.,
- for the file
tests/cell_test.py: - for the test
test_a1_value - remove the file
tests/cassettes/CellTest.test_a1_value.json
- for the file
- Run the tests with
GS_RECORD_MODE=new_episodes.
GS_CREDS_FILENAME=<./YOUR_CREDS.json> GS_RECORD_MODE=new_episodes tox -e py
$env:GS_CREDS_FILENAME = "./YOUR_CREDS.json"
$env:GS_RECORD_MODE = "new_episodes"
tox -e py
This will mostly result in a lot of updated files in tests/cassettes/. Don't forget to add them in your PR.
Please add them in a dedicated commit, in order to make the review process easier.
Afterwards, remember to run the tests in offline mode to make sure you have recorded everything correctly.
On Windows, clear GS_RECORD_MODE first (Remove-Item Env:GS_RECORD_MODE), otherwise the offline run
will still try to record.
Release
Old release notes are here.
New release system:
- Update version number in
gspread/__init__.py. - Get changelog from drafting a new GitHub release (do not publish, instead cancel.)
- Add changelog to
HISTORY.rst. - Commit the changes as
Release vX.Y.Z(do not push yet.) - Run
tox -e lint,py,build,docto check build/etc. - Push the commit. Wait for the CI to pass.
- Add a tag
vX.Y.Zto the commit locally. This will trigger a new release on PyPi, and make a release on GitHub. - View the release on GitHub and PyPi!
- Sync or add the latest version to the Gspread ReadTheDocs