Skip to main content

webrender-worker

The paired local worker — the box side of WebRender's local rung. Install it on a machine you own (a Mac mini, a Linux box, a NAS), pair it once to your WebRender account, and it runs your jobs at home — unlimited, private, and free at the point of use. No third-party AI provider ever sees your text.

Two job kinds today:

  • read-aloud TTS — renders audio with Kokoro;
  • handwriting recognition — reads rendered ink with a local vision model via Ollama (default qwen2.5vl:7b-16k; override with WEBRENDER_OLLAMA / WEBRENDER_OLLAMA_MODEL).

The poll declares which kinds this daemon supports, so an older daemon is never handed work it cannot run.

It makes only outbound HTTPS calls (no inbound ports, works behind NAT), holds one revocable account-scoped token, and imports nothing from the WebRender server — this package is the whole box side. Licence: AGPL-3.0-or-later; the wheel is pure Python, so the source you are running is the source in the package.

How it works

CLOUD (WebRender)                          YOUR BOX (this daemon)
  preprocess text, enqueue a job
                                  ← poll   GET /worker/jobs      (outbound)
                                    job →  render each segment with Kokoro
                                  ← MP3    POST …/result         (framed upload)
  store MP3 (same store as a paid gen)
  player serves it → you listen, any device

The box never sees the document — only the per-segment spoken text the cloud already preprocessed. It renders each segment to an MP3, keyed by the segment's global index, and uploads the batch; the cloud reassembles it into the exact artifact a paid generation would produce. A recognition job mirrors that line one step further: the box sees rendered ink pixels and a server-supplied prompt, never the document.

Install

Python (recommended on macOS)

Requires Python 3.10–3.13 (the Kokoro stack has no 3.14 wheels yet) and ffmpeg on PATH (the MP3 encoder).

# ffmpeg:  macOS → brew install ffmpeg   ·   Debian/Ubuntu → sudo apt install ffmpeg
pip install 'webrender-worker[render]'      # or: uv pip install 'webrender-worker[render]'

The render extra is the Kokoro TTS stack. Plain pip install webrender-worker gives only the daemon skeleton — useful if you are implementing against the protocol, not for actually rendering audio. The first render downloads the Kokoro model weights (~a few hundred MB, cached).

On Linux, pip install pulls the default PyPI PyTorch wheel, which drags several GB of CUDA libraries a CPU rung never loads. Either install CPU-only torch first (pip install torch --index-url https://download.pytorch.org/whl/cpu) or use the Docker image below, which does exactly that for you.

Docker (Linux / WSL2 / NAS)

No Python or ffmpeg on the host, and CPU-only by design:

docker run --rm -it -v webrender-worker:/data \
    ghcr.io/josephnhopkins/webrender-worker pair          # open the printed link

docker run -d --restart unless-stopped --name webrender-worker \
    -v webrender-worker:/data ghcr.io/josephnhopkins/webrender-worker

Logs: docker logs -f webrender-worker. The webrender-worker named volume holds the pairing token and the Kokoro model cache, so it survives container recreation.

On macOS, run the daemon natively instead — Docker on a Mac is a hidden Linux VM: it taxes RAM and cannot use Apple-silicon acceleration.

Use

webrender-worker pair                 # prints a link; open it signed in to WebRender
webrender-worker run                  # start rendering (leave it running)
webrender-worker status               # build, host + paired state
webrender-worker status --json        # the same, machine-readable
webrender-worker unpair               # revoke this box + forget the token

Pairing is a device flow: the daemon prints a one-time link, you open it in a browser where you are already signed in to WebRender, and the box receives its token. Nothing inbound, and no password ever reaches the box.

The token lives in ~/.webrender-worker/config.json (mode 0600). You can also disconnect the box from your WebRender account page — the kill-switch — and the daemon then stops with a "re-pair" message on its next poll.

pair and run accept --host URL to point at a different WebRender deployment (a self-hosted one, or a dev server). You do not need it for the hosted service.

status --json

The machine-readable contract — parse this rather than the text face, and paste it into any support conversation. It never contains the pairing token.

{
  "version": "0.1.0",
  "host": "https://magic-box.co.uk",
  "paired": true,
  "account": "you@example.com",
  "doorbell": true,
  "config_path": "/home/you/.webrender-worker/config.json"
}

doorbell reports whether the wake-free transport is configured. When it is, the daemon sleeps between jobs instead of polling on a timer — which is what lets both your box and the cloud idle. A build old enough to lack it falls back to a 5-second HTTP poll, so keep the daemon reasonably current (pip install -U webrender-worker, or re-pull the image). The daemon reports its version to the cloud on every call so that a future release can tell you when an update matters.

Resilience

  • Sleep-wake / dynamic IP / NAT: the loop only dials out, so it resumes cleanly after the box wakes; network blips and cloud cold-starts are retried with backoff.
  • Crash mid-render: the cloud reclaims a job whose heartbeat goes stale and re-queues it, so a job is never lost — the box just re-renders it on the next poll.
  • More than one box: the protocol tolerates N workers on one account; claims are atomic, so whichever box polls first takes a given job.

Licence

AGPL-3.0-or-later. It is a component of the AGPL WebRender system.

Download files

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

Source Distribution

webrender_worker-0.1.0.tar.gz (35.3 kB view details)

Uploaded Source

Built Distribution

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

webrender_worker-0.1.0-py3-none-any.whl (39.8 kB view details)

Uploaded Python 3

File details

Details for the file webrender_worker-0.1.0.tar.gz.

File metadata

  • Download URL: webrender_worker-0.1.0.tar.gz
  • Upload date:
  • Size: 35.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.7 {"installer":{"name":"uv","version":"0.11.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"22.04","id":"jammy","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for webrender_worker-0.1.0.tar.gz
Algorithm Hash digest
SHA256 c438a8df97f90fe5ce43d29801a0a3d1b129af5b0af7f273b0369562733a1741
MD5 af07441a5ff443552daa890cc9fe12d7
BLAKE2b-256 a01d45e8a414e6212aeede2d2b0cdb792d62e89e08a7a9628e6dae5437cb9467

See more details on using hashes here.

File details

Details for the file webrender_worker-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: webrender_worker-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 39.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.7 {"installer":{"name":"uv","version":"0.11.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"22.04","id":"jammy","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for webrender_worker-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 d3407976680f30724b133e7b4a50ca39f1245d760fd57a79a94f653f373d0e18
MD5 08925dfd114583783b435cf9b6abdbc1
BLAKE2b-256 691bd744f1b760a8df5c2bf3decf54e908eb22c8b88362cbf9bdcd6e744b635a

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page