Skip to main content

wallatag

A CLI for finding and tagging your untagged Wallabag articles.

wallatag can apply tags from your existing Wallabag vocabulary, match keywords and rules you define, or ask an optional LLM for suggestions. Use run for a batch job or manual to review suggestions in your terminal. By default it runs as a command line application, but it can optionally be integrated into Prefect scheduling; see the Prefect integration guide. See CHANGELOG.md for what changed between releases.

Minimum requirements:

  • Python 3.11 or newer
  • A Wallabag instance and API credentials
  • A virtual environment utility like uv for installation or running from source

The CLI does not require Prefect or an LLM. Its only runtime dependency is requests.

Install and configure

Install through pip, pipx or uv:

uv tool install git+https://github.com/marty-oehme/wallatag.git

Then generate a starter configuration file:

wallatag config init

This writes an annotated wallatag.toml to $XDG_CONFIG_HOME/wallatag/wallatag.toml (~/.config/wallatag/wallatag.toml by default), creating the directory if needed. Pass --config PATH to write it elsewhere (for a project-local ./wallatag.toml) and --force to overwrite an existing file.

Edit that file with your Wallabag URL, API client ID and secret, username, and password. Create an API client in Wallabag under Developer -> Create your own client. A project-local wallatag.toml is gitignored so your credentials stay local.

For a local SQLite history file, set:

[store]
path = "./wallatag.db"

A user-wide config should keep its database out of the config directory, e.g. path = "~/.local/share/wallatag/wallatag.db". A missing parent directory is created on first use, so no manual mkdir is needed.

You can also supply settings through environment variables instead of TOML. Configuration precedence is built-in defaults, a TOML config file, environment variables, then command-line flags. wallatag looks for ./wallatag.toml first, then $XDG_CONFIG_HOME/wallatag/wallatag.toml (~/.config/... by default) and the $XDG_CONFIG_DIRS entries (/etc/xdg). Use --config PATH or WALLATAG_CONFIG to point at a specific file. A relative [store] path is resolved against the config file's directory. The configuration reference covers all settings; the annotated example config is also available in the repository as wallatag/wallatag.toml.example.

Check the effective (non-secret) configuration before connecting:

wallatag config

wallatag config show is the explicit form, and wallatag status remains as an alias.

Start with a dry run. It fetches eligible articles and reports what it would tag without applying changes or writing history:

uv run wallatag run --max 5 --no-apply

To review suggestions one article at a time, use the interactive mode:

uv run wallatag manual --max 5

At each article, press Enter to apply the current suggestions, a to add tags, d to drop suggestions, s to skip, or q to quit. A skipped article is eligible again after the seven-day cooldown when history is enabled.

For unattended batch tagging, omit --no-apply:

uv run wallatag run --max 5

wallatag --help, wallatag run --help, and wallatag manual --help list the available options. Common flags:

Flag Purpose
--max N Limit a run to at most N articles.
--focus NAME Activate selected focus groups; repeat to choose several. By default, all groups are active.
--tag-policy POLICY Choose only-existing, prefer-existing (default), or all.
--no-apply Preview without applying tags or writing history.
--no-history Run without the SQLite store; entries can recur on every run and concurrent runs are not deduplicated.
--config PATH Read settings from a specific TOML file.
--verbose Print more diagnostic information.

How tagging works

  • Existing-tag vocabulary: match Wallabag’s tags against article fields. By default, matching checks the title, URL, domain, and content.
  • Focus groups: define keywords that map to tags, then select groups with --focus. Groups can also match regular expressions and choose which article fields to inspect.
  • Optional LLM suggestions: disabled by default. Enable with [tagger] enable_llm = true and configure an ollama or openai-compatible provider under [ai]. The confidence threshold gates headless application; manual mode lets you review suggestions first. When LLM tagging is enabled, the article title, URL, domain, language, reading time, and content excerpt are sent to the configured model endpoint.

prefer-existing favors tags already in your Wallabag vocabulary while still allowing new suggestions. only-existing prevents new tags; all allows them. The final number of tags applied per article is capped by [tagger] max_applied_tags (default: 5).

History and reconsideration

With history enabled, wallatag atomically claims an article when processing starts. When CLI and Prefect runs share the same SQLite store, this prevents them from double-processing an article. The claim expires after seven days: skipped, rejected-wholesale, no-suggestion, interrupted, or deterministically failed articles can return to the queue instead of being excluded forever. Transient and LLM failures are requeued immediately. Without history (--no-history or an empty WALLATAG_DB), there is no persistent cooldown or cross-run deduplication.

Versus Wallabag's built-in rules

Wallabag has native regex tagging rules, but they apply only to new entries and cannot be managed through its API. wallatag complements them by backfilling existing entries, applying shared vocabulary and focus-group rules, offering interactive review, and optionally using an LLM.

Prefect integration

Prefect is an optional way to schedule wallatag and monitor each article as a Prefect task. The standalone CLI works without it. For flow behavior, UI configuration, and the Dokku deployment, see the dedicated Prefect integration and deployment guide.

Development

Clone from source

Clone the project and install its locked dependencies:

git clone https://github.com/marty-oehme/wallatag.git
cd wallatag
uv sync --locked
uv run wallatag config init --config ./wallatag.toml

Version control

I develop wallatag with Jujutsu (jj), a Git-compatible VCS. You do not need it: the repository is a normal Git repository, and contributions through plain git (branches, commits, pull requests) are just as welcome. Use whichever you prefer.

Install dev dependencies

Install development and optional integration dependencies, then run the checks:

uv sync --all-groups --locked
uv run ruff check .
uv run ruff format --check .
uv run python -m unittest discover -s tests -t .

Tests are grouped into tiers (unit, integration, e2e) selected with the WALLATAG_TEST_TIERS environment variable; the default is unit only, so the command above is the fast loop. Use WALLATAG_TEST_TIERS=all to run everything, or e.g. WALLATAG_TEST_TIERS=unit,integration to skip e2e. Integration tests need the optional prefect group and exercise real child processes (Prefect's ephemeral API server, concurrent SQLite writers) over fakes for the network; there are no e2e tests yet. The -t . flag is required for the selection to take effect (it imports tests/ as a package).

Woodpecker CI runs linting, formatting, and all test tiers on pushes to main and pull requests targeting main.

License

MIT

Metadata

Release files for wallatag 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for wallatag 0.1.0
File Size Uploaded
wallatag-0.1.0.tar.gz 134.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for wallatag 0.1.0
File Interpreter ABI Platform
wallatag-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 192.5 kB

Release files / wallatag-0.1.0.tar.gz

Download URL wallatag-0.1.0.tar.gz
Size 134.8 kB
Tags Source
SHA-256 checksum
How to use checksums
5afef703d05824e507f644813dbc3dfbf518f28216164d1279abe36a3b3609d8
BLAKE2b-256 checksum
How to use checksums
c8729b26d5ba96cf1a9225527dbf90df01901abdcc577aeaf107d2a25475bbec
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.12.23 {"installer":{"name":"uv","version":"0.12.23","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Alpine Linux","version":"3.23.6","id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / wallatag-0.1.0-py3-none-any.whl

Download URL wallatag-0.1.0-py3-none-any.whl
Size 57.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
1880c02211521345c715a75cec7a7d5447758d590343f1c2c3fdf53cb13e81a7
BLAKE2b-256 checksum
How to use checksums
23d99a7fcf17bc9d3ed541e5fcc6d191f74a14f35f02d8e5392ffa76458912b8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.12.23 {"installer":{"name":"uv","version":"0.12.23","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Alpine Linux","version":"3.23.6","id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page