The Problem
Calibre-Web solves the problem of accessing a Calibre ebook library over the web. Calibre itself is a desktop application; this project exposes the same database through a browser interface so users can browse, read, and download books from any device, without needing Calibre installed locally.
What This Does
This is a fork of janeczku/calibre-web (18k stars upstream). The application is a Python web service built on Flask (the cps/ package, 289 code files), serving an HTML/JavaScript frontend. It reads a Calibre database directly, providing user management, OPDS feeds for ebook readers, metadata editing, and Kobo device sync.
The core logic lives in cps/web.py (routes), cps/helper.py (shared utilities), and cps/db.py (database models). The cps/static/ directory contains 700+ font-mapping files for PDF rendering, which accounts for the large file count.
How It Is Wired
Execution starts at cps/main.py:30 (main), which reaches 95 functions. It calls create_app to initialize the Flask application, which routes through cps/__init__.py and cps/web.py to register handlers. A separate worker thread (cps/services/worker.py:124, run) handles background tasks like ebook conversion, reaching 136 functions independently.
The call graph shows heavy centralization: render_title_template is called from 57 places, error_or_exception from 54, and delete from 40. The cps package itself is a hub with 63 modules importing it, and it participates in an import cycle with cps/helper, cps/web, and cps/main. That cycle means changes to shared helpers ripple through the entire application with no clean dependency boundary.
File responsibilities by effect:
cps/db.py— database models; 74 functions, 16 classes, used by 17 filescps/helper.py— mixed concerns: file I/O, crypto, network calls, database accesscps/admin.py— admin routes; 80 functions, makes outbound network callscps/kobo.py— Kobo sync; makes outbound calls to the Kobo storecps/services/worker.py— background task queue; reads/writes files and database
External effects are one or two hops from entry points: main -> create_app -> get_encryption_key touches the filesystem via os.chmod; run -> del_temp_dir deletes directories via shutil.rmtree. 183 functions read or write the database; 31 make network calls.
How To Use It
The README documents installation via pip:
python3 -m venv calibre-web-env
source calibre-web-env/bin/activate
pip install calibreweb
cps
Configuration is done through the web interface during first run (database path, user accounts). There is no config file to edit beforehand; cps/config_sql.py handles settings persistence in SQLite. The requirements.txt and pyproject.toml confirm pip-based dependency management.
Real-World Use
A typical deployment runs Calibre-Web on a home server or NAS, pointing at a Calibre library directory. Users access it via browser to download books in their preferred format, or sync a Kobo e-reader through the built-in Kobo integration. The OPDS feed (cps/opds.py) lets mobile reading apps browse the same catalog.
Code Health & Issues
Static analysis (166 findings: 103 high, 59 medium, 4 low) identified:
- High — Import cycle members:
cps/main.py,cps/helper.py,cps/web.pyparticipate in circular imports; breaking these requires extracting shared types or deferring imports - High — Oversized files:
cps/web.pyhas 1433 lines,cps/helper.pyandcps/admin.pyare also oversized - High — Deep nesting: 33 instances of indentation depth 8 in
cps/constants.py,cps/usermanagement.py,cps/helper.py - Medium — Broad exception handling in
cps.py,cps/file_helper.py,cps/helper.py - Medium — File opened without context manager in
cps/web.py
SDLC gaps: no CI configuration, no dependency lockfile, and a test ratio of 1 test file per 291 source files (0.003). The test suite cannot meaningfully cover this codebase.
The Bottom Line
A mature, feature-complete ebook server that works well for its purpose. The codebase carries real maintenance debt — import cycles, oversized modules, and minimal test coverage — but the upstream project is actively maintained. Use it if you need a self-hosted Calibre web interface; budget time for refactoring if you plan to extend it significantly.