goodscraps
goodscraps is a standalone, read-only Python client for public Goodreads
metadata, including books, authors, works, series, editions, and cover images.
Goodreads has no supported public developer API. These endpoints are unofficial and may change or become unavailable. The package does not log in, read cookies, mutate shelves, submit ratings, or fetch review text.
Development
poetry install
poetry run pytest
poetry run ruff check .
poetry run mypy src/
The test suite runs the live Goodreads smoke test by default. Set
GOODSCRAPS_LIVE=0 to run completely offline:
GOODSCRAPS_LIVE=0 poetry run pytest
CI and PyPI releases
GitHub Actions runs offline tests, Ruff, and mypy on pushes to main and on
pull requests. Live Goodreads requests are intentionally disabled in CI.
After those checks pass, a change to the package version on main
automatically creates the matching GitHub release, which triggers PyPI
publishing.
To release a new version:
# Bump the package version in pyproject.toml and the CLI source, then commit
# and push it. CI handles the tag,
# GitHub release, and PyPI publication.
poetry run python scripts/set_version.py 0.1.2
git add pyproject.toml
git add src/goodscraps/__init__.py
git commit -m "Bump package version"
git push origin main
Usage
Install the package and create a ~/.local/bin/goodscraps command:
./install.sh
If needed, add ~/.local/bin to your PATH.
Help and usage output uses Tinta ANSI colors when displayed in a terminal.
Set NO_COLOR=1 to disable them.
from goodscraps import Goodscraps
with Goodscraps() as client:
matches = client.search("Elantris", limit=5, resolve_canonical=True)
authors = client.search_author("John Scalzi", limit=5)
book_id = matches[0].canonical_book_id or matches[0].book_id
book = client.book(book_id)
work = client.work(book.book_id)
requested_book = work.requested_book
canonical_book = work.canonical_book
editions = client.editions(book.book_id, limit=5)
series = client.series(book.series[0].series_id) if book.series else None
client.download_cover(book.book_id, "/tmp/elantris.jpg")
The optional smoke CLI is available as:
poetry run goodscraps search "Elantris" --limit 5
poetry run goodscraps search "Elantris" --limit 5 --no-canonical
poetry run goodscraps search-author "John Scalzi" --limit 5
poetry run goodscraps book 68427
Searches resolve each result to the first edition Goodreads returns for its
work by default and include that ID as canonical_book_id. Use
--no-canonical when the original search-result edition IDs are required.
search_author and search-author use Goodreads' explicit author-filtered
book search, aggregate authors by exact normalized name, and rank them by the
number of matching works returned as works_score. Book searches return author and
additional_authors using the same AuthorRef schema as book metadata. Search
titles remove trailing Goodreads series markers from title while preserving
the original in title_complete.
Lookup failures return readable JSON by default:
{
"error": {
"type": "NotFound",
"message": "No author matched 'Unknown'"
}
}
Use --raise-errors when debugging or when a shell traceback is preferred:
goodscraps --raise-errors author "Unknown"
Metadata
Release files for goodscraps 0.1.5
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| goodscraps-0.1.5.tar.gz | 15.5 kB | With provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| goodscraps-0.1.5-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 34.3 kB
Release files / goodscraps-0.1.5.tar.gz
| Download URL | goodscraps-0.1.5.tar.gz |
|---|---|
| Size | 15.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
a4f8bdd83c247b8171dae9f16a59c5a4cb7cefa110645ea0a17eb96281d93b5c
|
|
BLAKE2b-256 checksum How to use checksums |
656ac7304147405aa3a69871b3c0d22fde3a3197d06d7ee1a1a182985bb1be5c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 6, 2026.
Transparency logRelease files / goodscraps-0.1.5-py3-none-any.whl
| Download URL | goodscraps-0.1.5-py3-none-any.whl |
|---|---|
| Size | 18.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
634fb8737bbc2486a5631ebfb35e1694622f11723de9ac6e2621fa26f2097742
|
|
BLAKE2b-256 checksum How to use checksums |
497d5545cb04c4ec96b814db3e40c8ce0d0e27cf8154551d3d84394b316ff254
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 6, 2026.
Transparency logSecurity for goodscraps 0.1.5
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for goodscraps-0.1.5.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 6, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.