Skip to main content

OPDS server that bridges read-it-later services to e-readers

Project description

Later.ink

Your Readwise Reader queue, on your e-reader.

Browsing the Later.Ink catalog in KOReader, downloading a saved article, and reading it as an EPUB with images.

Later.Ink is a small server that turns your Readwise Reader account into an OPDS catalog. Point KOReader — or any ebook reader that speaks OPDS, including on iPhone and iPad (Fablum, justRead, PocketBook), Android (Moon+ Reader), or desktop (Thorium Reader) — at one URL and browse your saved articles, downloading any of them as a clean EPUB, generated on the fly from the article HTML that Reader has already cleaned up.

No plugin, no sync daemon, and nothing to install from us — ebook readers already speak OPDS.

Free and open source (MIT), and built to self-host with your own Readwise token. Run it on a NAS, a Raspberry Pi, a VPS, or your laptop — it stores nothing, reading your queue live from Readwise.

Scope: later.ink is a reading path, not a sync path. It never writes back to Readwise, so articles stay in your queue as you read them. If you want finished articles archived and removed from the device automatically, the Endle/readwisereader KOReader plugin does that — this project trades write-back for zero install and working on any OPDS client. (Note: Readwise already serves Kindle natively via send-to-Kindle; the sweet spot here is Kobo, Boox, and other non-Kindle e-ink.)

Self-host quickstart

Upgrading from ≤0.3.x? The internal package was renamed for the brand: read_later_opds is now later_ink. Docker users just rebuild (docker compose up -d --build --remove-orphans — the flag retires the container from the old opds service name). If you run without Docker, reinstall (pip install -e .) and use the new module path: python -m uvicorn later_ink.main:app .... Your .env and database are untouched. One cosmetic side effect: EPUB identifiers changed with the rename, so a re-downloaded article registers as a new book in your reader's library rather than an update to the old copy.

With Docker:

git clone https://github.com/brendanlefebvre/later-ink.git
cd later-ink
cp .env.example .env
# put your token from https://readwise.io/access_token into .env
docker compose up -d

Without Docker (Python 3.11+):

git clone https://github.com/brendanlefebvre/later-ink.git
cd later-ink
python -m venv .venv && . .venv/bin/activate   # Windows: .venv\Scripts\activate
pip install .
cp .env.example .env
# put your token from https://readwise.io/access_token into .env
python -m uvicorn later_ink.main:app --host 0.0.0.0 --port 8000 --env-file .env

Your catalog is now at http://your-host:8000/opds/.

KOReader setup: top menu → magnifying glass → OPDS catalog+ → enter the URL. Browse folders (Later, New, Shortlist, Archive, Feed), tap an article to download and read. Images are embedded in the EPUB, so articles read fully offline. Use KOReader's OPDS search box to find articles by title, author, or summary; search scans your most recent saved items (a bounded slice of a very large queue) rather than the entire history.

On iPhone/iPad: use an ebook reader that supports OPDS — Fablum, justRead, or PocketBook — and add the same catalog URL. On desktop: Thorium Reader works too.

What appears: articles, newsletters, PDFs, books (uploaded EPUBs), video transcripts, tweet threads, and podcasts — each delivered as an EPUB, converted from the content Readwise exposes. Multi-section books and long articles are split into chapters with a navigable table of contents, and every EPUB opens on a generated cover. A podcast converts only after you've loaded its transcript in Readwise Reader (until then the API returns a stub, and the download reports that). Configurable via READWISE_CATEGORIES (e.g. article,pdf).

Hosted version

There's no public hosted instance running yet — self-hosting is the supported path today. The server does include an optional multi-tenant mode (short, e-ink-typeable catalog URLs like later.ink/maple-crater-lantern-owl/, with per-user tokens encrypted at rest), so a free hosted instance may come later. If you want to stand one up yourself, see the multi-tenant env vars in .env.example.

Architecture

src/later_ink/
  main.py          # FastAPI routes: OPDS feeds, EPUB downloads, onboarding
  config.py        # env-var configuration
  opds.py          # OPDS 1.x Atom feed builder
  epub.py          # HTML → EPUB (ebooklib + lxml cleanup)
  covers.py        # generated EPUB covers (hero image + typographic fallback)
  store.py         # SQLite user store + word-based secret URLs
  words.py         # wordlist behind the secret URLs (e-ink-typeable words)
  ratelimit.py     # per-IP throttle for unknown-secret probes
  pages.py         # server-rendered HTML pages
  payments.py      # Stripe verification (optional; inactive unless configured)
  connectors/
    base.py        # Connector interface: folders / articles / article HTML
    readwise.py    # Readwise Reader API v3 connector
    wallabag.py    # Wallabag API v2 connector (OAuth2)

Readwise and Wallabag are supported today (set the WALLABAG_* vars in .env.example to enable Wallabag). More connectors (Instapaper) are planned — the connector interface is three methods.

Development

pip install -e ".[dev]"
ALLOW_FREE_SIGNUP=1 python -m uvicorn later_ink.main:app --reload
pytest

Credits

Generated EPUB covers use League Spartan by The League of Moveable Type, bundled under the SIL Open Font License (src/later_ink/assets/fonts/OFL.txt).

License

MIT

Project details


Download files

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

Source Distribution

later_ink-0.4.1.tar.gz (1.2 MB view details)

Uploaded Source

Built Distribution

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

later_ink-0.4.1-py3-none-any.whl (1.2 MB view details)

Uploaded Python 3

File details

Details for the file later_ink-0.4.1.tar.gz.

File metadata

  • Download URL: later_ink-0.4.1.tar.gz
  • Upload date:
  • Size: 1.2 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for later_ink-0.4.1.tar.gz
Algorithm Hash digest
SHA256 d1027737d1859703f065167e3a1f37ec1f7657f919dc8d7b5818e9070789fd12
MD5 b4c09f7c98901710d8f96a0bd01564e0
BLAKE2b-256 521f20539da19e83ff950c01d656419a8aa1ca11e1b6e195ff699716fd941ac7

See more details on using hashes here.

Provenance

The following attestation bundles were made for later_ink-0.4.1.tar.gz:

Publisher: release.yml on brendanlefebvre/later-ink

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

File details

Details for the file later_ink-0.4.1-py3-none-any.whl.

File metadata

  • Download URL: later_ink-0.4.1-py3-none-any.whl
  • Upload date:
  • Size: 1.2 MB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for later_ink-0.4.1-py3-none-any.whl
Algorithm Hash digest
SHA256 afec3a15bb04dc685e510864139a9a5879f66271fd867ce17367d8a68dffcfd5
MD5 a421a08beb98df9378c8a626c1c301e1
BLAKE2b-256 d5adee6427b8f22bec0d8107cd91001131aa5acfe8d1cd7fdb36f2646e20cf88

See more details on using hashes here.

Provenance

The following attestation bundles were made for later_ink-0.4.1-py3-none-any.whl:

Publisher: release.yml on brendanlefebvre/later-ink

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

Supported by

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