Skip to main content
bookpeek

bookpeek

bookpeek scans the opening seconds of an audiobook and extracts the spoken title, title candidates, authors, and narrators without requiring an online AI service or API key. By default it runs Whisper and Vosk together, merges their extraction evidence, and always returns per-engine transcripts and extractions arrays (one entry for a single backend, two when both run). Long pauses in the intro become hard sentence breaks so cues like read by … do not swallow the next section. Title candidates can come from Audible-style introductions, ID3 tags, filenames, folders, and chapter text, with scores indicating which candidate was preferred.

Online results are grouped by provider under online_matches, with separate authors and works arrays. Goodreads author results with zero similarity are omitted when any positive-scoring author exists; otherwise authors with at least ten works are retained as a fallback.

The result's top-level title, author, and narrators fields contain the final values after provider validation (narrators are de-duplicated case-insensitively with proper name casing). Per-engine raw ASR text and unmodified extraction evidence live under transcripts and extractions.

Audnexus results appear under online_matches.audnexus.works and include matched Audible identifiers, authors, narrators, region, and confidence scores. Verified narrator names are also collected under online_matches.audnexus.narrators.

Install

First-time setup

There are only two steps:

  1. Install ffmpeg, which decodes audiobook files:
 # macOS with Homebrew
 brew install ffmpeg

 # Debian/Ubuntu
 sudo apt update && sudo apt install ffmpeg
  1. Run the installer:
 ./install.sh

The installer bootstraps Poetry if necessary, installs Whisper and Vosk plus online enrichment, downloads spaCy's English model, and creates ~/.local/bin/bookpeek. ASR model weights are not downloaded during install; the first bookpeek scan prompts for them (or use -d to download automatically). If ffmpeg is missing, the installer prints the appropriate commands and exits. Add ~/.local/bin to your PATH if the bookpeek command is not found.

# Skip Open Library / Goodreads packages (ASR engines are still installed):
./install.sh --offline

On Apple Silicon, Whisper uses Metal automatically when device = "auto". Vosk is installed from the matching bookpeek GitHub Release wheel because upstream PyPI does not publish macOS arm64 wheels for 0.3.45. Whisper and Vosk model files download into ~/.config/bookpeek/models/ (and the usual Hugging Face cache for Whisper) on first use.

Usage

By default, bookpeek uses both Whisper and Vosk. Pass --engine whisper or --engine vosk to use only one backend. It scans 30 seconds first; if that only produces an Audible bumper such as This is Audible, it automatically retries at 60 seconds and then 90 seconds. A normal introduction stops after the first successful scan.

# Scan an audiobook file (Whisper + Vosk by default, then merge evidence):
bookpeek scan /path/to/book.m4b

# Scan a folder; bookpeek uses the first audio file alphabetically:
bookpeek scan /path/to/audiobook-folder/

# Use only the small CPU-friendly Vosk engine:
bookpeek scan /path/to/book.m4b --seconds 42 --engine vosk

# Force Whisper's tiny English model on the CPU:
bookpeek scan /path/to/book.m4b --engine whisper --model tiny.en --device cpu

# Choose Whisper and Vosk models independently for the default dual scan:
bookpeek scan /path/to/book.m4b --whisper-model base.en --vosk-model vosk-model-small-en-us-0.15

# Automatically download any missing ASR models (Vosk zip / Whisper weights).
# Vosk models are stored under ~/.config/bookpeek/models/ next to config.toml:
bookpeek scan /path/to/book.m4b -d

# Search (only) the specific Audible regions, in this order:
bookpeek scan /path/to/book.m4b --regions uk,ca,au

# Enable Open Library, Goodreads, and Audnexus enrichment for this scan:
bookpeek scan /path/to/book.m4b -w

# Force a completely offline scan, even if config enables enrichment:
bookpeek scan /path/to/book.m4b --offline

# Print the active configuration:
bookpeek config show

# Create a new config file with bookpeek's defaults:
# (Saves to ~/.config/bookpeek/config.toml; use --force to overwrite.)
bookpeek config new

Example response

The JSON result includes the extracted metadata and online provider matches:

{
  "path": "/path/to/The Blighted Stars.m4b",
  "title": "The Blighted Stars (The Devoured Worlds, #1)",
  "author": "Megan E. O'Keefe",
  "narrators": [
    "Ciaran Saward"
  ],
  "transcripts": [
    {
      "text": "This is audible. Ashet audio presents the blighted stars...",
      "engine": "whisper",
      "model": "tiny.en",
      "seconds": 60.0
    },
    {
      "text": "this is audible. the blighted stars written by megan e okeefe...",
      "engine": "vosk",
      "model": "vosk-model-small-en-us-0.15",
      "seconds": 60.0
    }
  ],
  "extractions": [
    {
      "engine": "whisper",
      "title": "The Blighted Stars",
      "title_candidates": [
        {
          "text": "The Blighted Stars",
          "source": "id3_title",
          "score": 0.9
        },
        {
          "text": "The Devoured Worlds 01 - The Blighted Stars",
          "source": "folder",
          "score": 0.65
        }
      ],
      "author": "Megan E. O'Keefe",
      "narrators": [
        "Kieran Sord"
      ]
    },
    {
      "engine": "vosk",
      "title": "The Blighted Stars",
      "author": "Megan E. O'Keefe",
      "narrators": [
        "Kieran Sord"
      ]
    }
  ],
  "online_matches": {
    "audnexus": {
      "authors": [
        {
          "asin": "B00IMSE6VQ",
          "name": "Megan E. O'Keefe",
          "region": "us",
          "score": 1.0
        }
      ],
      "works": [
        {
          "asin": "B0BJ4JLW57",
          "title": "The Blighted Stars",
          "authors": ["Megan E. O'Keefe"],
          "narrators": ["Ciaran Saward"],
          "region": "us",
          "isbn": "9781668615331",
          "score": 0.933,
          "narrator_score": 0.667,
          "match_reason": "title_author"
        }
      ],
      "narrators": ["Ciaran Saward"]
    },
    "goodreads": {
      "authors": [],
      "works": [
        {
          "title": "The Blighted Stars (The Devoured Worlds, #1)",
          "title_complete": "The Blighted Stars (The Devoured Worlds, #1)",
          "author": "Megan E. O'Keefe",
          "score": 0.857
        }
      ]
    },
    "openlibrary": {
      "authors": [],
      "works": [
        {
          "title": "Devoured Worlds Series, 3-book collection ...",
          "author": "Megan E. O'Keefe",
          "score": 0.632
        }
      ]
    }
  }
}

Configuration is read from ~/.config/bookpeek/config.toml; command-line options override it. Downloaded Vosk models are stored under ~/.config/bookpeek/models/ so config and models share one directory tree.

bookpeek config new creates that file with the default settings. It will not overwrite an existing config unless bookpeek config new --force is used.

[asr]
engine = "both"
whisper_model = "tiny.en"
vosk_model = "vosk-model-small-en-us-0.15"
device = "auto"
seconds = 30

[extract]
spacy_model = "en_core_web_sm"

[enrich]
enabled = false # set true to always perform web lookup
openlibrary = true
goodreads = true
audnexus = true
# Search order matters: earlier regions win ties and are returned first.
audible_regions = ["us", "uk", "ca", "au"]

Supported Audnexus/Audible regions are us, uk, ca, and au. audible_regions is an ordered priority list, not just a set of enabled regions: if equivalent matches are found in multiple stores, the first region listed wins and its result is returned first. --regions replaces this priority order for one scan, so --regions ca,us gives Canada precedence over the US.

-w / --online may query Open Library, Goodreads, and Audnexus. Goodreads support is installed as a package dependency. Set [enrich].enabled = true to perform that lookup on every scan without passing the flag. Use --offline to override that setting for a single scan. Narrator lookup is performed through Audible catalog search followed by Audnexus metadata lookup when matching is enabled.

CI and PyPI releases

GitHub Actions runs tests, Ruff, and mypy on pushes to main and pull requests. After those checks pass, a change to the package version on main automatically creates the matching GitHub release, which triggers PyPI publishing through Trusted Publishing.

To release a new version:

poetry run python scripts/set_version.py 0.2.0
git add pyproject.toml src/bookpeek/__init__.py
git commit -m "Bump package version"
git push origin main

The repository's PyPI project must have a Trusted Publisher configured for the GitHub repository, workflow .github/workflows/publish.yml, and pypi environment before the first release.

Homebrew releases update brandonscript/homebrew-tap automatically when the HOMEBREW_TAP_TOKEN repository secret is configured. The token needs fine-grained Contents: Read and write access to that tap repository. Without the secret, the Python release still succeeds and CI reports that the tap update was skipped.

Development

poetry run pytest
poetry run ruff check .
poetry run mypy src/

The provider URL smoke test is opt-in because it makes network requests:

BOOKPEEK_LIVE=1 poetry run pytest tests/test_urls_live.py

Metadata

Release files for bookpeek 0.2.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for bookpeek 0.2.1
File Size Uploaded Provenance
bookpeek-0.2.1.tar.gz 30.2 kB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for bookpeek 0.2.1
File Interpreter ABI Platform
bookpeek-0.2.1-py3-none-any.whl Python 3 none any Details

Total release size: 64.2 kB

Release files / bookpeek-0.2.1.tar.gz

Download URL bookpeek-0.2.1.tar.gz
Size 30.2 kB
Tags Source
SHA-256 checksum
How to use checksums
4e2d06091327372edc44d6bc859e8e25102236ac8b72ef8be116446fb9bca993
BLAKE2b-256 checksum
How to use checksums
c83339ced4205cdd55775ba8cb82e3bbb1fdaf0aad09c22793c45a3859b769bf
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 9, 2026.

Transparency log

Release files / bookpeek-0.2.1-py3-none-any.whl

Download URL bookpeek-0.2.1-py3-none-any.whl
Size 34.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
f430ea64195040371eec978b21a08af471f0b6a7123e4c49b4362fab65dac14e
BLAKE2b-256 checksum
How to use checksums
52cdca5ad76014a0f57c2e134eb072424c2550e6d518fcdf164798f696773f26
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 9, 2026.

Transparency log

Security for bookpeek 0.2.1

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.

Select from 2 files

Attestation for bookpeek-0.2.1.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 9, 2026.

Transparency log

A 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.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page