DPO Reader
Turn Discourse threads into podcasts. Each author gets their own voice.
I got tired of skimming long forum threads. DPO Reader converts them to audio so I can listen while doing other things. Point it at any Discourse thread and it'll synthesize the whole thing with different voices for each participant.
Install
# uv (recommended)
uv tool install dpo-reader
# Or run directly without installing
uvx dpo-reader listen "https://discuss.python.org/t/your-thread"
# pipx works too
pipx install dpo-reader
Usage
# Basic: generate audio and play it
dpo-reader listen "https://discuss.python.org/t/your-thread"
# Interactive TUI with read-along highlighting
dpo-reader listen "https://discuss.python.org/t/your-thread" --ui
# Start from a specific post (the /50 in the URL does this automatically)
dpo-reader listen "https://discuss.python.org/t/your-thread/12345/50" --ui
# Or explicitly with -s
dpo-reader listen "https://discuss.python.org/t/your-thread" -s 50
# Export without playing
dpo-reader export "https://discuss.python.org/t/your-thread" -o thread.wav
# See what you're getting into before generating
dpo-reader info "https://discuss.python.org/t/your-thread"
dpo-reader preview "https://discuss.python.org/t/your-thread"
Options
-o, --output PATH Output file (default: output.wav)
-e, --engine ENGINE openai | bark | piper
-s, --start-post INT Start from this post number
-n, --max-posts INT Limit number of posts
--ui Interactive TUI with controls
--no-attribution Skip "Author says:" prefix
--no-play Don't auto-play after generating
-c, --cache-dir PATH Cache audio chunks (useful if generation crashes)
-p, --pause FLOAT Seconds between posts (default: 1.5)
-f, --file PATH Load from local JSON (testing)
TTS Engines
| Engine | Quality | Speed | Notes |
|---|---|---|---|
| OpenAI | Best | Fast | Needs API key, costs money |
| Bark | Excellent | Slow (~10s/sentence) | Local, wants a GPU |
| Piper | Good | Fast (~0.1s/sentence) | Local, CPU-only |
Bark is the default. It runs locally and produces natural-sounding speech with good intonation. A GPU helps a lot but isn't strictly required.
OpenAI (-e openai) sounds the best if you have an API key. Get one at platform.openai.com/api-keys and set OPENAI_API_KEY in your environment or a .env file.
Piper (-e piper) is the lightweight option. Install with uv pip install dpo-reader[piper]. Good for batch processing or machines without GPUs.
TUI Controls
When using --ui:
| Key | Action |
|---|---|
| Space | Play/Pause |
| ←/→ | Skip 5 seconds |
| ↑/↓ | Speed up/down |
| n/p | Next/Previous post |
| l | Toggle logs |
| q | Quit |
Requirements
Python 3.10-3.13. The onnxruntime dependency doesn't support 3.14 yet.
Development
git clone https://github.com/JacobCoffee/dpo-reader.git
cd dpo-reader
make dev
make lint # Linting
make type-check # Type checking
make test # Tests
make ci # All of the above
# Test TTS locally
make test-listen # Piper
make test-bark # Bark
License
MIT
Metadata
Release files for dpo-reader 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 | |
|---|---|---|---|
| dpo_reader-0.1.0.tar.gz | 26.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| dpo_reader-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 56.0 kB
Release files / dpo_reader-0.1.0.tar.gz
| Download URL | dpo_reader-0.1.0.tar.gz |
|---|---|
| Size | 26.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
8328ef1a412f0156e8004bf64b5a584f17e2044673ef2f69ef2f3dda0823d6ac
|
|
BLAKE2b-256 checksum How to use checksums |
ae574939e2731d4a02abb1f45dce1d82e5a106de93eb4a7db2aec23a986986a5
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
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 Jan 19, 2026.
Transparency logRelease files / dpo_reader-0.1.0-py3-none-any.whl
| Download URL | dpo_reader-0.1.0-py3-none-any.whl |
|---|---|
| Size | 29.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
274b2459fad463526281ebfb66bc34696652ce437ee411a464307c7a7c2c600f
|
|
BLAKE2b-256 checksum How to use checksums |
ffda54bf3b6a9ecb3f22e74e9a015ae0d0ffd5ca69403d5e772455a44569fd5f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
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 Jan 19, 2026.
Transparency log