boko-python
Independent Python bindings for Boko,
the native Rust ebook converter. This project depends on the published boko
Rust crate; it does not fork or patch the converter and is not maintained
by the upstream Boko project.
The Python distribution is boko-ebook, imported as boko. The first release
is not published yet; build locally using the instructions below. The unrelated
PyPI distribution boko uses the same import name: do not install both together.
Usage
from pathlib import Path
import boko
boko.convert_file(Path('input.epub'), Path('output.kfx'))
# Use bytes when the input is already in memory.
source = Path('input.epub').read_bytes()
output = boko.convert(source, 'epub', 'kfx')
| Format | Input | Output |
|---|---|---|
EPUB 2/3 (epub) |
yes | yes |
AZW3 (azw3) |
yes | yes |
MOBI (mobi, azw) |
yes | no |
KFX (kfx) |
yes | yes |
Markdown (markdown, md) |
no | yes |
Format names are case-insensitive. convert returns bytes (UTF-8 for Markdown).
convert() buffers input and output in memory. convert_file() infers formats from
case-insensitive file extensions and writes directly to a same-filesystem temporary file,
without buffering the entire output in the binding. It replaces an existing destination
only after export and file synchronization succeed. The same input/output file, including
symlink and hardlink aliases, raises ValueError. Output extensions are .epub, .azw3,
.kfx, .md, and .markdown. POSIX outputs use private file permissions (0600).
For inspection, repeated reads, or export options, use the Book API below. Parsing,
conversion, chapter loading/rendering, link resolution, and optimization release the GIL.
- Invalid/unsupported formats and malformed books raise
ValueError. - DRM-protected books raise
PermissionError; no decryption is provided. - Missing resources raise
KeyError; genuine I/O failures raiseOSError. - Unrecognized future core errors fall back to
RuntimeError. - Rust panics during detached native operations raise
RuntimeError. After a panic, close and discard the affected book; continued use is not supported. Allocation aborts and OS process kills cannot be caught this way, so untrusted books still need worker limits.
Regular CPython 3.11+ is supported. Wheels use abi3-py311 and do not require Rust
to install. Free-threaded Python, PyPy, and GraalPy wheels are not currently built.
Untrusted books
Parsing is not a sandbox. Input, decompressed chapters, parsed content, image processing,
and exports can consume much more memory than the uploaded file. The core's 512 MiB
limit per decompressed EPUB entry is not a whole-book memory budget; neither compressed
file size nor spine size estimates provide that budget.
Process each untrusted book in a disposable worker process or container with an OS-enforced
memory limit and a parent-enforced wall-clock timeout. Limit concurrent workers too.
On Linux, resource.RLIMIT_AS bounds virtual address space, including libraries and thread
stacks; choose the budget for your workload. Other platforms need their own process/container
limits. A Rust allocation failure can abort the worker rather than raise a Python exception:
treat nonzero exits and timeouts as failed jobs, not failures of the parent service.
These limits must be configured by the calling application; the library does not impose a whole-book memory budget.
Book API
with boko.Book.open(Path('input.epub')) as book:
print(book.metadata['identifier'], book.metadata['is_rtl'])
print(book.toc, book.landmarks, book.spine)
cover = book.cover()
first = book.chapter(book.spine[0]['id'])
print(first.text)
sections = book.sections()
links = book.resolve_links()
print(links.broken_links)
output = book.export('epub', normalize=True, compression_level=6)
Use Book.from_bytes(data, format) for in-memory inputs. Book.open(path, format=None) accepts strings and PathLike objects, inferring formats from the
file extension unless supplied explicitly. Use a with statement or close() to
release the file and caches. closed reports the state; operations on a closed
book raise ValueError.
Inspection and assets
metadata: every core metadata field, including contributor roles, collection/ series, sort names, cover path, reading direction, and inferredis_rtl.toc: nested entries with title, href, play order, children, and optional resolved target. Callresolve_links()to populate targets.landmarks: structural navigation entries, using snake-casetypenames.spine: reading-order entries withid,source_path, andsize_estimate.assets: archive-relative asset names.load_asset(path)returns their bytes.cover(): cover bytes, orNonewhen no cover is identified. An identified but missing resource raisesKeyError.font_faces: family, numeric weight, style, and archive source path.requires_normalized_export: whether source content needs normalized export.
Dictionaries and lists are independent snapshots: modifying them does not edit
the book. Absent optional metadata uses None; absent collections use empty lists.
boko.pyi describes these dictionaries; they are not runtime model classes.
Chapters and sections
chapter(id) loads a read-only Chapter snapshot. chapters(ids=None) loads all
chapters in spine order, or the supplied IDs in that order, using the core's
parallel/cache support. Chapter IDs come from spine, not TOC indexes.
| Chapter property/method | Result |
|---|---|
id, source_path |
Chapter identifier and original archive path, if available |
raw |
Format-specific bytes; KFX raw content is binary, not HTML |
text |
Readable live-node text, including footnotes, code whitespace retained by the core, image alt text, and math fallback text |
xhtml |
Normalized XHTML, linking its stylesheet as chapter.css |
css |
The CSS matching the XHTML's generated class names |
node_text(node_id) |
Readable text of a normalized node, for link navigation |
XHTML/CSS are normalized renderings, not source-preserving edits. The generated CSS
may include unused styles from the chapter's style pool. They do not copy or embed
image/font assets: retrieve those separately with load_asset().
sections() returns title, authors, language, preamble, and nested sections.
Each section contains level, title, content, and children; content blocks
are tagged by type: paragraph, code_block, block_quote, list, table,
image, or rule. This is a reading/search representation: upstream extraction
omits nodes classified as footnotes by the core and drops inline formatting.
Footnote classification varies by importer, so some EPUB notes may instead appear
as ordinary blocks. Use chapter text/XHTML when footnote content is required.
clear_cache() clears parsed core chapters and requires exclusive access to the book.
Existing chapter and link snapshots remain usable after cache clearing, optimization,
or closing their book, and keep their own memory alive until released.
Links
resolve_links() returns a read-only ResolvedLinks snapshot:
links: ordered{source, target}entries;len(result)counts resolved links.broken_links: ordered{source, href}entries.get(chapter_id, node_id): the target of a source link, orNone.links_to(chapter_id, node_id=None): source nodes linking to a specific node, or to the chapter start whennode_idis omitted (not all nodes in the chapter).
Sources contain chapter_id and node_id. Targets are discriminated by kind:
internal includes both IDs; chapter includes chapter_id; external includes
url. IDs refer to normalized nodes, not source-file byte offsets.
Export and optimization
export(format, *, normalize=None, compression_level=None) returns bytes.
normalize applies only to EPUB/AZW3; compression_level applies only to EPUB
and must be 1–9 (the current ZIP backend rejects level 0). Incompatible options raise
ValueError. KFX input is normalized automatically where needed.
optimize() explicitly mutates the book using Boko's default image pass and
returns passes, assets_changed, and bytes_saved. This is lossy image
optimization: the core may downscale and re-encode images as JPEG and rename
assets, including the cover path. JPEG quality (80), dimension limit (1236), and
minimum savings are fixed by the core. Inspect fresh metadata/assets after it runs.
Previously returned snapshots still describe the pre-optimization state.
Read-only operations may run concurrently on one book. clear_cache(), close(),
sections(), and optimize() require exclusive access: do not run them concurrently with other
operations on the same book. PyO3 rejects conflicting borrows rather than waiting.
Development
Requires CPython 3.11+, Rust 1.91+, and platform native build tools.
Development uses Python 3.11, the oldest supported minor version.
Rust, Python, and uv versions are pinned in mise.toml. With
mise activated in your shell:
mise run dev # uv sync: editable install
uv run python -m unittest discover -s tests -v # run tests
mise run build # uv build: wheel + source archive
uv manages .venv and builds the extension with maturin; no manual activation or
maturin installation is needed.
Additional Rust checks: cargo fmt --check,
cargo clippy --locked --all-targets -- -D warnings, and cargo test --locked --lib.
For Rust's embedded-interpreter test, relocatable Python installations may need
PYTHONHOME set to Python's base prefix. On Linux, also add $PYTHONHOME/lib to
LD_LIBRARY_PATH so the test executable can load the Python shared library.
Importing the extension does not require these settings.
Build artifacts go to dist/. Use release builds when measuring performance.
Local Linux wheels are not necessarily portable: use manylinux containers or
maturin's compatible Zig support for distribution.
Releases
CI checks Rust, tests wheels for Linux x86_64/ARM64, macOS x86_64/ARM64, and Windows
x86_64 on Python 3.11 and 3.15, and rebuilds/tests the source distribution.
Pushing a v<version> tag matching Cargo.toml publishes the tested artifacts to
PyPI and GitHub.
The PyPI Trusted Publisher must use workflow publish.yml and environment pypi.
Protect that GitHub environment with required reviewers and tag restrictions before publishing.
License
GPL-3.0-or-later, matching the linked Boko core. See LICENSE. Boko's Rust implementation and original authorship remain with the upstream project.
Metadata
Release files for boko-ebook 0.1.0
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 | Actions |
|---|---|---|---|---|
| boko_ebook-0.1.0.tar.gz | 50.3 kB | With provenance | Details for boko_ebook-0.1.0.tar.gz |
Built distributions (wheels)
| File | Actions Reset | |||
|---|---|---|---|---|
| boko_ebook-0.1.0-cp311-abi3-win_amd64.whl | CPython 3.11 | abi3 | Windows x86-64 | Details for boko_ebook-0.1.0-cp311-abi3-win_amd64.whl |
| boko_ebook-0.1.0-cp311-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl | CPython 3.11 | abi3 | Linux glibc 2.17+ x86-64 | Details for boko_ebook-0.1.0-cp311-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl |
| boko_ebook-0.1.0-cp311-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl | CPython 3.11 | abi3 | Linux glibc 2.17+ ARM64 | Details for boko_ebook-0.1.0-cp311-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl |
| boko_ebook-0.1.0-cp311-abi3-macosx_11_0_arm64.whl | CPython 3.11 | abi3 | macOS 11.0+ ARM64 | Details for boko_ebook-0.1.0-cp311-abi3-macosx_11_0_arm64.whl |
| boko_ebook-0.1.0-cp311-abi3-macosx_10_12_x86_64.whl | CPython 3.11 | abi3 | macOS 10.12+ x86-64 | Details for boko_ebook-0.1.0-cp311-abi3-macosx_10_12_x86_64.whl |
Total release size: 12.5 MB
Release files / boko_ebook-0.1.0.tar.gz
| Download URL | boko_ebook-0.1.0.tar.gz |
|---|---|
| Size | 50.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
561acf651abeaaeef8432cd6729bf005b23bcdc1826f737a3f166cfd52625b78
|
|
BLAKE2b-256 checksum How to use checksums |
bd0638fad096ede1ccaefb99553383a755cfb2d49e87dc5a3b3b740baa1da9ce
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.13.7 {"installer":{"name":"uv","version":"0.13.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"26.04","id":"resolute","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
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 Nov 5, 2026.
Transparency logRelease files / boko_ebook-0.1.0-cp311-abi3-win_amd64.whl
| Download URL | boko_ebook-0.1.0-cp311-abi3-win_amd64.whl |
|---|---|
| Size | 2.5 MB |
| Tags | CPython 3.11 Windows x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
746cb91f5a3f4469150d0b1481d8457be2f4ff895c0287f7e1d960e96458503d
|
|
BLAKE2b-256 checksum How to use checksums |
19adb6af4a81c646792ac0664bb58701974b2da77d523281a3d2a5368924820b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.13.7 {"installer":{"name":"uv","version":"0.13.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"26.04","id":"resolute","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
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 Nov 5, 2026.
Transparency logRelease files / boko_ebook-0.1.0-cp311-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl
| Download URL | boko_ebook-0.1.0-cp311-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl |
|---|---|
| Size | 2.6 MB |
| Tags | CPython 3.11 Linux glibc 2.17+ x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
55c6325133c33f571296a3691d9aa49cc7686429c0eb7c0f6006f62b1d65c7c2
|
|
BLAKE2b-256 checksum How to use checksums |
7f11275617e46a33b69e0d3b2f7653a1badeb1b55845a4b7a25333e05ef76c4e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.13.7 {"installer":{"name":"uv","version":"0.13.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"26.04","id":"resolute","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
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 Nov 5, 2026.
Transparency logRelease files / boko_ebook-0.1.0-cp311-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl
| Download URL | boko_ebook-0.1.0-cp311-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl |
|---|---|
| Size | 2.5 MB |
| Tags | CPython 3.11 Linux glibc 2.17+ ARM64 abi3 |
|
SHA-256 checksum How to use checksums |
b2e08bdebc3a6879d70692450c260d0ca7a3c12cdd5bb96ad6d5308f82057e09
|
|
BLAKE2b-256 checksum How to use checksums |
c6505ab6e2bb93ed8e5cea5abf43161b3fe35a9fc4d8b7274f132066719bb7ca
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.13.7 {"installer":{"name":"uv","version":"0.13.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"26.04","id":"resolute","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
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 Nov 5, 2026.
Transparency logRelease files / boko_ebook-0.1.0-cp311-abi3-macosx_11_0_arm64.whl
| Download URL | boko_ebook-0.1.0-cp311-abi3-macosx_11_0_arm64.whl |
|---|---|
| Size | 2.4 MB |
| Tags | CPython 3.11 abi3 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
99694c1560e427601637b82c9ad94e5ef80abc024d76cd24fe719625b874f405
|
|
BLAKE2b-256 checksum How to use checksums |
162ba684e2b90e09b433b5d01793222ef425c5050234f39cafdcd551f74bd844
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.13.7 {"installer":{"name":"uv","version":"0.13.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"26.04","id":"resolute","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
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 Nov 5, 2026.
Transparency logRelease files / boko_ebook-0.1.0-cp311-abi3-macosx_10_12_x86_64.whl
| Download URL | boko_ebook-0.1.0-cp311-abi3-macosx_10_12_x86_64.whl |
|---|---|
| Size | 2.5 MB |
| Tags | CPython 3.11 abi3 macOS 10.12+ x86-64 |
|
SHA-256 checksum How to use checksums |
fe0cc110d342856c517bdb4efda12b68ab03b3f134f775b94a719749e12ddfe8
|
|
BLAKE2b-256 checksum How to use checksums |
0fb30f98c3a3292873edfd053f85d5aa488d4dbc8b73e0b0b1e1de22cf78c072
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.13.7 {"installer":{"name":"uv","version":"0.13.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"26.04","id":"resolute","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
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 Nov 5, 2026.
Transparency logSecurity for boko-ebook 0.1.0
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 6 files in this release have been uploaded with provenance metadata.
Attestation for boko_ebook-0.1.0.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 Nov 5, 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.
To learn more about protecting yourself from malicious actors, visit our package security documentation.