Skip to content

Installation

Supported matrix

Kenkui requires CPython >=3.11,<3.14. The complete tier-1 CI matrix is:

GitHub runner platform 3.11 3.12 3.13
Ubuntu 24.04 (ubuntu-24.04) tested tested tested
macOS 14 (macos-14) tested tested tested

The distribution is a py3-none-any wheel. That does not make unlisted host platforms supported: native M4B behavior also depends on the host FFmpeg build. The runner labels above deliberately state the platform exactly; they do not promise every Linux distribution, macOS release, CPU architecture, PyPy, or Windows.

Install size

pocket-tts==2.1.0 is a required dependency, and it pulls torch, scipy, sentencepiece, numpy, and pydantic. Expect a torch-scale install of well over a gigabyte, not the few hundred kilobytes a pure-Python EPUB library would suggest.

Provisioning downloads more on top of that, on first use only: roughly 225 MB per language engine plus roughly 6.5 MB per voice. See the guide.

Install

Install the library and its synthesis dependencies:

python -m pip install kenkui

Or add it to a uv project:

uv add kenkui

To install from a checkout of the repository:

python -m pip install .

pocket-tts==2.1.0 is pinned exactly: the adapter depends on the inspected upstream API and rejects any other installed version. The wheel does not contain model weights or voice recordings. Explicit load_voice() provisioning downloads the necessary assets and records them in the local manifest; rendering verifies that manifest before synthesis. See Pocket-TTS adapter.

Optional offline character discovery with spaCy

The base install uses your configured LiteLLM model for character discovery. To discover characters locally instead, install the optional spaCy dependency and its English pipeline into the same Python environment:

python -m pip install "kenkui[spacy]"
python -m spacy download en_core_web_lg

infer_characters("spacy") selects en_core_web_lg. The download is explicit; Kenkui loads the installed pipeline and does not fetch it during resolution. To choose a smaller pipeline, install en_core_web_sm and use infer_characters("spacy:en_core_web_sm"). Different pipeline sizes can change the discovered roster. Kenkui uses dependency parsing and English speech/name heuristics, so this path is intended for English books.

import kenkui as kk

if __name__ == "__main__":
    review = kk.epub("book.epub").infer_characters("spacy").resolve(until="characters")
    print(review.inspect().roster)

This replaces character discovery only. attribute_quotes(model) still uses a LiteLLM provider/model identifier and may make network requests; "spacy" is not a quote-attribution provider. See character review to correct the roster before continuing. Missing dependencies raise spacy_package_missing or spacy_pipeline_missing; install the missing component in the environment running Kenkui.

FFmpeg prerequisite

M4B production requires both ffmpeg and ffprobe version 5 or newer on PATH, with MP4/M4B muxing, AAC encoding, probing, and full decoding available. They are external executables and are never bundled in the wheel.

# Ubuntu 24.04
sudo apt-get update
sudo apt-get install -y ffmpeg

# macOS with Homebrew
brew install ffmpeg

ffmpeg -version
ffprobe -version
ffmpeg -hide_banner -encoders

Kenkui performs a capability preflight rather than trusting a version string. Missing executables report ffmpeg_not_found or ffprobe_not_found; incomplete builds report ffmpeg_unsupported or ffprobe_unsupported. Encoding, probing, decoding, semantic validation, and publication have distinct stable errors. No candidate is published after a failed check.

Why dependencies are pinned

  • Base runtime pins defusedxml==0.7.1: XML hardening is part of the reviewed EPUB parser boundary, so silent behavior drift is avoided.
  • pocket-tts==2.1.0 is pinned exactly: the adapter depends on the inspected package API and rejects any other installed version.
  • Development/docs tools are resolved transitively and locked in uv.lock. uv sync --frozen --all-groups makes that lock authoritative in CI without rewriting it.

For a locked contributor environment:

uv lock --check
uv sync --frozen --all-groups