Skip to main content
cquarry logo

cquarry

Canonical Calibre database layer and search grammar engine for Calibre libraries.

This library powers CalibreQuarry (CLI/TUI), Hermitage (GTK4 gallery), Carrel-calibre-web (web reader), and Bindery (EPUB repair & audit). By centralizing the search grammar parser and metadata access, cquarry evaluates virtual library definitions and search queries consistently across frontends.

Features

  • Direct SQLite access. No calibredb binary required, no Calibre Python initialization overhead.
  • Lock-safe snapshots. Automatically detects if Calibre holds an exclusive write lock on metadata.db and routes queries through a temporary WAL-consistent copy.
  • Full search grammar parity. A recursive-descent parser implementing Calibre's native search capabilities: boolean logic, field prefixes, date math (hyphen and slash separators), hierarchical tags with ./.. component modifiers on every text field, custom columns, identifiers, saved-search interpolation (search:"Name"), multi-valued count operators (tags:#>3), language canonicalization (languages:Englisheng), and nested virtual library cross-references.
  • Native page counts. The pages: location reads Calibre's own books_pages_link table first (maintained by upstream's CountPages integration) and falls back to an int custom column labelled pages; counts also ride along in every book row.
  • Entity secondary columns & display config. Book rows carry author_sorts/author_links parallel to authors; get_entities(kind) exposes {id, name, sort, link, count} for authors/series/publishers/tags/languages; custom columns report editable, normalized and their decoded display JSON (enum_values, enum_colors, …); and a typed preferences accessor covers everything else (get_preference, get_field_metadata, get_user_categories, get_tag_browser_state).
  • Metadata portability. Read e-reader annotations, per-device reading progress, third-party plugin data, and conversion profiles; sanitize comments HTML for display.
  • Opt-in write path. cquarry.write.WritableCalibreDB offers trigger-safe mutations in a separate module the read-only API can never touch: title, authors (with author_sort recomputation), series (+index), publisher, rating (UNIQUE-deduped), languages (canonicalized to ISO codes), tags, identifiers, comments, generic custom-column writes (layout auto-detected, enumerations validated against display.enum_values, non-editable columns refused), format registration/removal, has_cover, and full book removal with orphan pruning; every mutation queued in metadata_dirtied for OPF resync.
  • Context manager. CalibreDB supports with statements for automatic cleanup of snapshot files.
  • Zero dependencies. Pure Python 3.14+ stdlib (sqlite3, re, json, unicodedata).

Usage

from cquarry.db import CalibreDB

# Open a library (creates a snapshot if Calibre has the lock)
with CalibreDB("~/Calibre Library/metadata.db") as db:
    # Fetch all books with pre-joined metadata
    books = db.get_all_books()

    # Search using Calibre's native grammar
    sci_fi = db.search("tags:Fic.SciFi and rating:>=4")
print(f"Found {len(sci_fi)} highly rated Sci-Fi books.")

    # Resolve a virtual library to a set of book IDs
    wing = db.resolve_vl("To Read")

    # Interpolate a saved search straight from Calibre's preferences
    award_winners = db.search('search:"Award Winners"')

    # Inspect custom columns (#label, bare label, or display name all work)
    cols = db.get_custom_columns()
    status = db.load_custom_column("#reading_status")

    # Single-entity helpers (no whole-library scan)
    book = db.get_book(42)
    epub = db.get_format_path(42, "EPUB")

    # Metadata portability
    highlights = db.get_annotations(42)
    progress = db.get_last_read_positions(42)
    wordcounts = db.get_plugin_data(name="wordcount")

The composed deep fetch combines metadata, formats, custom columns, and annotations:

dossier = db.get_book_dossier(42, include_comments=True)
print(dossier["formats"], dossier["custom_columns"])
print(dossier["comments"]["plain"])  # comments HTML, already stripped

Writes live behind an explicit opt-in import:

from cquarry.write import WritableCalibreDB

with WritableCalibreDB("~/Calibre Library/metadata.db") as wdb:
    wdb.add_tag(42, "Audited")
    wdb.set_identifier(42, "isbn", "9780123456789")
    wdb.clear_identifier(42, "mobi-asin")  # honest no-op when absent

# A multi-book curation pass commits exactly once:
with WritableCalibreDB("~/Calibre Library/metadata.db") as wdb:
    with wdb.batch():
        wdb.set_pubdate(42, "1991-10-01")
        wdb.add_tag(43, "Audited")

# Every mutation queues an OPF regeneration; check what Calibre will resync:
with CalibreDB("~/Calibre Library/metadata.db") as db:
print(db.get_dirtied_books())  # e.g. [42, 43]

Installation

pip install cquarry

API at a glance

The full per-method reference lives in API.md. One line per module:

Module What it is
cquarry.db The read-only database layer (CalibreDB): hydrated rows, single-entity fetches, format/cover path resolution, custom columns, preferences, annotations and progress extractors, VL/saved-search resolution, and the composed get_book_dossier() deep fetch.
cquarry.search The lexer/parser/evaluator porting Calibre's search grammar; usable standalone behind the MetadataProvider protocol.
cquarry.helpers Domain utilities: rating conversion, comment sanitization, author display, series gaps, image dimension sniffing, the ISBN family (isbn_normalize, isbn_check_digit_is_valid, to_isbn13), and tag_rollup.
cquarry.integrity The shared library-integrity predicates: untagged, unrated, authorless, formatless, coverless, missing cover files, deprecated formats, low-res covers, duplicates, series gaps.
cquarry.analytics Shared derivations: addition timeline, per-author stats, rating distribution, virtual library (wing) overlap.
cquarry.write The opt-in mutation path (WritableCalibreDB): trigger-safe setters, batch() transactions, remove_book. Every mutation queues OPF resync.
cquarry.config Saved database-path configuration (~/.config/cquarry/config.json).

Development

python -m pytest tests/           # full suite
python -m pytest tests/ -v        # verbose

Run with PYTHONPATH=src to exercise this checkout rather than any installed copy.

Six test modules: test_db.py (CalibreDB against fixture databases), test_helpers.py (utility functions), test_search.py (parser, matcher, and integration tests), test_write.py (opt-in write module with trigger-hazard fixtures), test_integrity.py (library integrity predicates), and test_analytics.py (analytics derivations).

See spec.md for the full contract and roadmap.md for planned work.

Acknowledgements

Carrel-calibre-web is a fork of calibre-web that uses cquarry as its search and virtual-library engine. Features proven there flow back into cquarry's roadmap (see Phase 7); calibre-web's original authors deserve the credit for the web experience that fork builds on.

Support

If cquarry is useful to you and you'd like to chip in:

License

MIT. See LICENSE.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

cquarry-1.11.1.tar.gz (139.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

cquarry-1.11.1-py3-none-any.whl (55.0 kB view details)

Uploaded Python 3

File details

Details for the file cquarry-1.11.1.tar.gz.

File metadata

  • Download URL: cquarry-1.11.1.tar.gz
  • Upload date:
  • Size: 139.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for cquarry-1.11.1.tar.gz
Algorithm Hash digest
SHA256 bd1fed5b5d3b79f9217d55997c2c33acdac102c0bf5ed2a4f3ee706742b9a0a9
MD5 f121bdb3ae8e7432d8f84d8f0c08a080
BLAKE2b-256 42c141ec4cc1d9d8c2c02a092de85b5eaf428a26a8fef8dc651cdd9c4a3c78d7

See more details on using hashes here.

Provenance

The following attestation bundles were made for cquarry-1.11.1.tar.gz:

Publisher: publish.yml on VirInvictus/cquarry

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file cquarry-1.11.1-py3-none-any.whl.

File metadata

  • Download URL: cquarry-1.11.1-py3-none-any.whl
  • Upload date:
  • Size: 55.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for cquarry-1.11.1-py3-none-any.whl
Algorithm Hash digest
SHA256 d59e8e940cca0ffd1d947e84ea2c3385b12e12c1900c840095d83bb2fbf688a2
MD5 9be23e331ccc85935cca69d4d9355140
BLAKE2b-256 368ac010d0d0ae6a5c6a182c442cfe6c5febeb61fffd435b425096f1ac4c1fb3

See more details on using hashes here.

Provenance

The following attestation bundles were made for cquarry-1.11.1-py3-none-any.whl:

Publisher: publish.yml on VirInvictus/cquarry

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

This release

1.11.1 This release

2 files

1.9.0

2 files

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