Architecture Overview¶
Inkfeed follows a clean pipeline architecture: fetch → process → write.
High-Level Flow¶
┌─────────────┐ ┌──────────────┐ ┌──────────────┐
│ Config │────▸│ Archivers │────▸│ Writers │
│ (TOML) │ │ (fetch data)│ │ (format out) │
└─────────────┘ └──────────────┘ └──────────────┘
│ │
┌──────┴──────┐ ┌─────┴─────┐
│ Download │ │ Jinja2 │
│ Images │ │ Templates│
└─────────────┘ └───────────┘
Module Layout¶
inkfeed/
├── __init__.py
├── __main__.py # Entry point (python -m inkfeed)
├── main.py # CLI main function and orchestration
├── config.py # TOML config loading and validation
├── archiver/ # Source-specific content fetchers
│ ├── base.py # ArchiveResult, GroupResult, Article models
│ ├── hackernews.py # Hacker News API archiver
│ ├── kaginews.py # Kagi News API archiver
│ └── rss.py # Generic RSS/Atom feed archiver
├── output/ # Format-specific output writers
│ ├── base.py # FormatWriter base class, IndexEntry model
│ ├── html.py # HTML writer
│ ├── markdown.py # Markdown writer
│ ├── gemtext.py # Gemtext (Gemini) writer
│ ├── epub.py # EPUB writer
│ └── sleepscreen.py # E-ink display writer
├── templates/ # Jinja2 HTML templates
│ ├── base.html
│ ├── html_article.html
│ ├── html_index.html
│ ├── main_index.html
│ ├── hn_story.html
│ ├── kagi_story.html
│ ├── rss_story.html
│ └── sleepscreen_*.html
├── utils/ # Shared utilities
│ ├── images.py # Image downloading and embedding
│ ├── readability.py # Article content extraction
│ └── retry.py # Retry logic for HTTP requests
└── assets/
└── fonts/ # Bundled fonts for self-contained output
Key Concepts¶
Archivers¶
An archiver knows how to fetch content from a specific source. Each archiver produces an ArchiveResult containing one or more GroupResult objects, each with a list of Article objects.
See Archivers for details.
Writers¶
A writer knows how to serialize articles into a specific output format. All writers implement the FormatWriter base class.
See Output Formats for details.
Templates¶
HTML-based output formats use Jinja2 templates. Templates are stored in inkfeed/templates/ and bundled with the package.
See Templates for details.
Execution Flow¶
- Load config — Parse
config.tomlinto typed dataclasses - Initialize writers — Create a writer instance for each requested format, call
setup() - For each enabled source:
- Look up the archiver class from
ARCHIVER_MAP - Run the archiver to get an
ArchiveResult - Download images for each group (parallel, with progress bar)
- Pass the result to each writer's
write_source()method
- Look up the archiver class from
- Write indices — Each writer generates date-level and source-level index pages
- Teardown — Writers clean up any resources (e.g., Playwright browsers)