Bumps the python-deps group with 10 updates in the / directory: | Package | From | To | | --- | --- | --- | | [flask-socketio](https://code.miguelgrinberg.com/miguelgrinberg/flask-socketio) | `5.6.1` | `5.7.0` | | [dnspython](https://github.com/rthalley/dnspython) | `2.8.0` | `2.9.0` | | [qbittorrent-api](https://github.com/rmartin16/qbittorrent-api) | `2026.8.1` | `2026.10.0` | | [authlib](https://github.com/authlib/authlib) | `1.8.0` | `1.9.1` | | [apprise](https://github.com/caronc/apprise) | `2.0.0` | `2.0.1` | | [publicsuffixlist](https://github.com/ko-zu/psl) | `1.0.2.20260925` | `1.1.0.20261010` | | [seleniumbase](https://github.com/seleniumbase/SeleniumBase) | `4.54.12` | `4.56.2` | | [basedpyright](https://github.com/detachhead/basedpyright) | `1.40.1` | `1.40.2` | | [prek](https://github.com/j178/prek) | `0.5.4` | `0.5.5` | | [ruff](https://github.com/astral-sh/ruff) | `0.16.9` | `0.17.1` | Updates `flask-socketio` from 5.6.1 to 5.7.0 Updates `dnspython` from 2.8.0 to 2.9.0 <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/rthalley/dnspython/releases">dnspython's releases</a>.</em></p> <blockquote> <h2>dnspython 2.9.0</h2> <p>This release fixes a potential <a href="https://github.com/rthalley/dnspython/security/advisories/GHSA-45c3-73f7-pv4m">excessive CPU consumption</a> issue. Thanks to Evgenios Gkritsis, Constantinos Patsakis, and George Stergiopoulos, for discovering and reporting this issue.</p> <p>See <a href="https://dnspython.readthedocs.io/en/stable/whatsnew.html">What's New</a> for details.</p> <p>The minimum supported version of Python is 3.11.</p> <p>My thanks to the many people who have contributed to this release. Also thanks to my co-maintainers: Nicki Křížek, Petr Špaček, and Brian Wellington.</p> <p>This release was published to PyPI using Trusted Publishing.</p> </blockquote> </details> <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/rthalley/dnspython/blob/main/doc/whatsnew.rst">dnspython's changelog</a>.</em></p> <blockquote> <h2>2.9.0</h2> <ul> <li> <p>Decompression chain length is limited to 16. Prior to this change, a maliciously crafted DNS message could cause dns.name.from_wire_parser() to use excessive CPU for DNS name decompression. Applications which processed untrusted DNS wire form messages with dnspython could be degraded or DoS'd by the extra CPU use required.</p> <p>Thanks to Evgenios Gkritsis, Constantinos Patsakis, and George Stergiopoulos for finding and reporting this issue.</p> <p>See <a href="https://github.com/rthalley/dnspython/security/advisories/GHSA-45c3-73f7-pv4m">https://github.com/rthalley/dnspython/security/advisories/GHSA-45c3-73f7-pv4m</a></p> </li> <li> <p>Httpx2 has replaced httpx for HTTPS TCP connections.</p> </li> <li> <p>The minimum supported Python version is now 3.11.</p> </li> <li> <p>DNSSEC now supports ML-DSA-44, a post-quantum signature algorithm.</p> </li> <li> <p>The NSEC3 Next Hashed Owner Name in presentation format is now decoded as base32hex (RFC 5155 Section 1.3, RFC 4648 Extended Hex Alphabet). The letters W, X, Y, and Z are not in that alphabet; they used to be accepted and silently decoded to a different owner name, so <code>to_text</code> of the result did not match the input. They are now rejected.</p> </li> <li> <p>The NID and L64 node/locator ids in presentation format are now rejected when a group contains anything other than hex digits. A sign or underscore, which <code>int()</code> silently accepts, produced a record whose text form did not parse back the same way (RFC 6742).</p> </li> <li> <p>Rdata of a known type in the generic <code>\#</code> syntax, such as an NS record in a zone file, no longer fails to parse when it contains a name under the origin. Its names are relativized as in the type's own text form.</p> </li> <li> <p>The SVCB and HTTPS <code>ech</code> parameter value must now be an ECHConfigList with a correct length prefix and at least 4 octets of content (RFC 9848, RFC 9849). The individual ECHConfig structures are not checked.</p> </li> <li> <p>SVCB and HTTPS SvcParamKeys in presentation format, including those listed in <code>mandatory</code>, must now be spelled as RFC 9460 requires: 1-63 lowercase letters, digits, or hyphens. Uppercase keys such as <code>ALPN</code> and keys with underscores such as <code>no_default_alpn</code> are rejected.</p> </li> <li> <p>SVCB and HTTPS presentation format parsing now follows the escaping rules of RFC 9460. SvcParamKeys may not contain escapes (e.g. <code>\097lpn=h2</code>), and in comma-separated values (<code>alpn</code>, <code>docpath</code>) only <code>\,</code> and <code>\\</code> are valid escapes after character-string decoding (e.g. <code>alpn="h2\\x"</code> is rejected).</p> </li> </ul> <!-- raw HTML omitted --> </blockquote> <p>... (truncated)</p> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/rthalley/dnspython/commit/e790c8f20a67ad439c7aafef2321e161c6028eee"><code>e790c8f</code></a> add missing test file</li> <li><a href="https://github.com/rthalley/dnspython/commit/b72af6723fa0df2113522132363eeda99c9abaa6"><code>b72af67</code></a> CI release branch update</li> <li><a href="https://github.com/rthalley/dnspython/commit/bdd62fed595a80b65feac75d7c2e1e3b908c56e6"><code>bdd62fe</code></a> release prep</li> <li><a href="https://github.com/rthalley/dnspython/commit/bafc96391dc352832fb17cc7939782735b642fb8"><code>bafc963</code></a> Merge branch 'decompression-limit'</li> <li><a href="https://github.com/rthalley/dnspython/commit/c5fecf515b4fa3a12e882bf80da232c94134cf50"><code>c5fecf5</code></a> release tidying</li> <li><a href="https://github.com/rthalley/dnspython/commit/c7686f3ef513d0da121f57fe1899bf2a2997da35"><code>c7686f3</code></a> update dependencies</li> <li><a href="https://github.com/rthalley/dnspython/commit/3c855c8d8f8269eb672aef3679cd2e33db924c03"><code>3c855c8</code></a> more type lint</li> <li><a href="https://github.com/rthalley/dnspython/commit/52815c91bbd831f6cbe85ed7bba4d7b8e1c25400"><code>52815c9</code></a> type lint</li> <li><a href="https://github.com/rthalley/dnspython/commit/f563427fecd9c0c4ba60cf002f2f33a5c396dd2a"><code>f563427</code></a> lint</li> <li><a href="https://github.com/rthalley/dnspython/commit/b485e460c266540a1a09ca6d8d1d7b685b1d3023"><code>b485e46</code></a> Limit decompression to a chain length of at most 16 pointers.</li> <li>Additional commits viewable in <a href="https://github.com/rthalley/dnspython/compare/v2.8.0...v2.9.0">compare view</a></li> </ul> </details> <br /> Updates `qbittorrent-api` from 2026.8.1 to 2026.10.0 <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/rmartin16/qbittorrent-api/releases">qbittorrent-api's releases</a>.</em></p> <blockquote> <h2>release-2026.10.0</h2> <h2>What's Changed</h2> <h3>Features</h3> <ul> <li>feat: add Web API v2.16.0 endpoints (qBittorrent v5.3.0) by <a href="https://github.com/rmartin16"><code>@rmartin16</code></a> in <a href="https://redirect.github.com/rmartin16/qbittorrent-api/pull/659">rmartin16/qbittorrent-api#659</a></li> <li>feat: add Web API v2.16.2 endpoints (qBittorrent v5.3.0beta1) by <a href="https://github.com/rmartin16"><code>@rmartin16</code></a> in <a href="https://redirect.github.com/rmartin16/qbittorrent-api/pull/678">rmartin16/qbittorrent-api#678</a></li> <li>feat: support qBittorrent v5.2.4 and v5.3.0rc1 by <a href="https://github.com/rmartin16"><code>@rmartin16</code></a> in <a href="https://redirect.github.com/rmartin16/qbittorrent-api/pull/686">rmartin16/qbittorrent-api#686</a></li> </ul> <h3>Chores</h3> <ul> <li>Bump pre-commit hook for mirrors-mypy from v2.3.0 to v2.3.1 by <a href="https://github.com/rmartin16"><code>@rmartin16</code></a> in <a href="https://redirect.github.com/rmartin16/qbittorrent-api/pull/677">rmartin16/qbittorrent-api#677</a></li> <li>Bump the github-actions group with 2 updates by <a href="https://github.com/dependabot"><code>@dependabot</code></a>[bot] in <a href="https://redirect.github.com/rmartin16/qbittorrent-api/pull/674">rmartin16/qbittorrent-api#674</a></li> <li>Bump the uv group with 6 updates by <a href="https://github.com/dependabot"><code>@dependabot</code></a>[bot] in <a href="https://redirect.github.com/rmartin16/qbittorrent-api/pull/675">rmartin16/qbittorrent-api#675</a></li> <li>Bump pre-commit hook for ruff-pre-commit from v0.16.1 to v0.16.5 by <a href="https://github.com/rmartin16"><code>@rmartin16</code></a> in <a href="https://redirect.github.com/rmartin16/qbittorrent-api/pull/676">rmartin16/qbittorrent-api#676</a></li> <li>Bump soupsieve from 2.8.4 to 2.9 by <a href="https://github.com/dependabot"><code>@dependabot</code></a>[bot] in <a href="https://redirect.github.com/rmartin16/qbittorrent-api/pull/679">rmartin16/qbittorrent-api#679</a></li> <li>Bump anyio from 4.13.0 to 4.14.2 by <a href="https://github.com/dependabot"><code>@dependabot</code></a>[bot] in <a href="https://redirect.github.com/rmartin16/qbittorrent-api/pull/680">rmartin16/qbittorrent-api#680</a></li> <li>Bump pre-commit hook for ruff-pre-commit from v0.16.5 to v0.16.9 by <a href="https://github.com/rmartin16"><code>@rmartin16</code></a> in <a href="https://redirect.github.com/rmartin16/qbittorrent-api/pull/683">rmartin16/qbittorrent-api#683</a></li> <li>Bump the github-actions group with 3 updates by <a href="https://github.com/dependabot"><code>@dependabot</code></a>[bot] in <a href="https://redirect.github.com/rmartin16/qbittorrent-api/pull/681">rmartin16/qbittorrent-api#681</a></li> <li>Bump the uv group with 5 updates by <a href="https://github.com/dependabot"><code>@dependabot</code></a>[bot] in <a href="https://redirect.github.com/rmartin16/qbittorrent-api/pull/682">rmartin16/qbittorrent-api#682</a></li> <li>build(deps): bump virtualenv from 21.4.2 to 21.7.13 by <a href="https://github.com/dependabot"><code>@dependabot</code></a>[bot] in <a href="https://redirect.github.com/rmartin16/qbittorrent-api/pull/685">rmartin16/qbittorrent-api#685</a></li> </ul> <h3>CI</h3> <ul> <li>refactor(tests): parametrize test_add_delete and fix dead assertions by <a href="https://github.com/rmartin16"><code>@rmartin16</code></a> in <a href="https://redirect.github.com/rmartin16/qbittorrent-api/pull/662">rmartin16/qbittorrent-api#662</a></li> <li>refactor(tests): derive an endpoint catalog and test the API surface from it by <a href="https://github.com/rmartin16"><code>@rmartin16</code></a> in <a href="https://redirect.github.com/rmartin16/qbittorrent-api/pull/663">rmartin16/qbittorrent-api#663</a></li> <li>docs(tests): explain how the test suite works by <a href="https://github.com/rmartin16"><code>@rmartin16</code></a> in <a href="https://redirect.github.com/rmartin16/qbittorrent-api/pull/664">rmartin16/qbittorrent-api#664</a></li> <li>refactor(tests): stop testing each camelCase alias over the network by <a href="https://github.com/rmartin16"><code>@rmartin16</code></a> in <a href="https://redirect.github.com/rmartin16/qbittorrent-api/pull/665">rmartin16/qbittorrent-api#665</a></li> <li>fix(tests): make webseed checks survive a busy qBittorrent by <a href="https://github.com/rmartin16"><code>@rmartin16</code></a> in <a href="https://redirect.github.com/rmartin16/qbittorrent-api/pull/667">rmartin16/qbittorrent-api#667</a></li> <li>refactor(tests): extend the catalog to interface spellings by <a href="https://github.com/rmartin16"><code>@rmartin16</code></a> in <a href="https://redirect.github.com/rmartin16/qbittorrent-api/pull/666">rmartin16/qbittorrent-api#666</a></li> <li>refactor(tests): remove the gate twins the catalog now covers by <a href="https://github.com/rmartin16"><code>@rmartin16</code></a> in <a href="https://redirect.github.com/rmartin16/qbittorrent-api/pull/669">rmartin16/qbittorrent-api#669</a></li> <li>refactor(tests): catalog torrent objects and drop the last gate twins by <a href="https://github.com/rmartin16"><code>@rmartin16</code></a> in <a href="https://redirect.github.com/rmartin16/qbittorrent-api/pull/670">rmartin16/qbittorrent-api#670</a></li> <li>refactor(tests): add eventually() and migrate test_search to it by <a href="https://github.com/rmartin16"><code>@rmartin16</code></a> in <a href="https://redirect.github.com/rmartin16/qbittorrent-api/pull/671">rmartin16/qbittorrent-api#671</a></li> <li>refactor(tests): finish the eventually() migration and delete check() by <a href="https://github.com/rmartin16"><code>@rmartin16</code></a> in <a href="https://redirect.github.com/rmartin16/qbittorrent-api/pull/672">rmartin16/qbittorrent-api#672</a></li> <li>test(tests): fail any test that leaves state behind in qBittorrent by <a href="https://github.com/rmartin16"><code>@rmartin16</code></a> in <a href="https://redirect.github.com/rmartin16/qbittorrent-api/pull/673">rmartin16/qbittorrent-api#673</a></li> </ul> <p><strong>Full Changelog</strong>: <a href="https://github.com/rmartin16/qbittorrent-api/compare/v2026.8.1...v2026.10.0">https://github.com/rmartin16/qbittorrent-api/compare/v2026.8.1...v2026.10.0</a></p> </blockquote> </details> <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/rmartin16/qbittorrent-api/blob/main/CHANGELOG.md">qbittorrent-api's changelog</a>.</em></p> <blockquote> <h3>v2026.10.0 (03 oct 2026)</h3> <ul> <li>Advertise support for qBittorrent v5.2.4 (<a href="https://redirect.github.com/rmartin16/qbittorrent-api/issues/686">#686</a>)</li> </ul> </blockquote> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/rmartin16/qbittorrent-api/commit/6580e6caf21a2b3360645e7605e35c47106db833"><code>6580e6c</code></a> bump to v2026.10.0</li> <li><a href="https://github.com/rmartin16/qbittorrent-api/commit/59b64b0d7b451a5d1ef6b2a4136f4368e0a9fd1b"><code>59b64b0</code></a> feat: support qBittorrent v5.2.4 and v5.3.0rc1 (<a href="https://redirect.github.com/rmartin16/qbittorrent-api/issues/686">#686</a>)</li> <li><a href="https://github.com/rmartin16/qbittorrent-api/commit/9016912a7c448cb85d19620301fcacd2023e310d"><code>9016912</code></a> build(deps): bump virtualenv from 21.4.2 to 21.7.13 (<a href="https://redirect.github.com/rmartin16/qbittorrent-api/issues/685">#685</a>)</li> <li><a href="https://github.com/rmartin16/qbittorrent-api/commit/e37548189948ef2feff614c646b4e88f24a023ab"><code>e375481</code></a> Bump the uv group with 5 updates (<a href="https://redirect.github.com/rmartin16/qbittorrent-api/issues/682">#682</a>)</li> <li><a href="https://github.com/rmartin16/qbittorrent-api/commit/6a9f89e98a74a63c5fbadd39face86963af2e027"><code>6a9f89e</code></a> Bump the github-actions group with 3 updates (<a href="https://redirect.github.com/rmartin16/qbittorrent-api/issues/681">#681</a>)</li> <li><a href="https://github.com/rmartin16/qbittorrent-api/commit/b08a1c8d7cafba855cc3b8158add4f2f32014a1c"><code>b08a1c8</code></a> Bumped pre-commit hook for ruff-pre-commit from v0.16.5 to v0.16.9 (<a href="https://redirect.github.com/rmartin16/qbittorrent-api/issues/683">#683</a>)</li> <li><a href="https://github.com/rmartin16/qbittorrent-api/commit/13fcfb9a6867f3889c180e173f7be1b2806de747"><code>13fcfb9</code></a> Bump anyio from 4.13.0 to 4.14.2 (<a href="https://redirect.github.com/rmartin16/qbittorrent-api/issues/680">#680</a>)</li> <li><a href="https://github.com/rmartin16/qbittorrent-api/commit/ea53fb27df0bb3108868def3a453003d2b2ab97a"><code>ea53fb2</code></a> Bump soupsieve from 2.8.4 to 2.9 (<a href="https://redirect.github.com/rmartin16/qbittorrent-api/issues/679">#679</a>)</li> <li><a href="https://github.com/rmartin16/qbittorrent-api/commit/9972fbb319c4570f1548c88faa7316d624cec8cc"><code>9972fbb</code></a> feat: add Web API v2.16.2 endpoints (qBittorrent v5.3.0beta1) (<a href="https://redirect.github.com/rmartin16/qbittorrent-api/issues/678">#678</a>)</li> <li><a href="https://github.com/rmartin16/qbittorrent-api/commit/9457fc5b45a6e49ded846887ffd202557c061e48"><code>9457fc5</code></a> Bumped pre-commit hook for ruff-pre-commit from v0.16.1 to v0.16.5 (<a href="https://redirect.github.com/rmartin16/qbittorrent-api/issues/676">#676</a>)</li> <li>Additional commits viewable in <a href="https://github.com/rmartin16/qbittorrent-api/compare/v2026.8.1...v2026.10.0">compare view</a></li> </ul> </details> <br /> Updates `authlib` from 1.8.0 to 1.9.1 <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/authlib/authlib/releases">authlib's releases</a>.</em></p> <blockquote> <h2>v1.9.1</h2> <p>Changelog: <a href="https://docs.authlib.org/en/stable/upgrades/changelog.html#changelog-1-9-1">https://docs.authlib.org/en/stable/upgrades/changelog.html#changelog-1-9-1</a></p> <h2>What's Changed</h2> <ul> <li>Use scriv to handle the changelog by <a href="https://github.com/azmeuk"><code>@azmeuk</code></a> in <a href="https://redirect.github.com/authlib/authlib/pull/954">authlib/authlib#954</a></li> </ul> <p><strong>Full Changelog</strong>: <a href="https://github.com/authlib/authlib/compare/v1.9.0...v1.9.1">https://github.com/authlib/authlib/compare/v1.9.0...v1.9.1</a></p> <h2>v1.9.0</h2> <h2>What's Changed</h2> <ul> <li>feat: add Identity Assertion JWT Authorization Grant (ID-JAG) by <a href="https://github.com/BinoyOza-okta"><code>@BinoyOza-okta</code></a> in <a href="https://redirect.github.com/authlib/authlib/pull/898">authlib/authlib#898</a></li> <li>Fix empty signatures validation in JWS JSON deserialization by <a href="https://github.com/loporto"><code>@loporto</code></a> in <a href="https://redirect.github.com/authlib/authlib/pull/938">authlib/authlib#938</a></li> <li>fix(jose): reject boolean values for NumericDate claims by <a href="https://github.com/cpruijsen"><code>@cpruijsen</code></a> in <a href="https://redirect.github.com/authlib/authlib/pull/942">authlib/authlib#942</a></li> <li>fix(client): avoid duplicated OAuth 1.0 parameters in signed requests by <a href="https://github.com/cpruijsen"><code>@cpruijsen</code></a> in <a href="https://redirect.github.com/authlib/authlib/pull/943">authlib/authlib#943</a></li> <li>OAuth2 token fetch crashes with JSONDecodeError instead of a catchable error on rate-limit responses by <a href="https://github.com/juneja-varun"><code>@juneja-varun</code></a> in <a href="https://redirect.github.com/authlib/authlib/pull/929">authlib/authlib#929</a></li> <li>docs: add i18n wrappers in conf.py and templates by <a href="https://github.com/hwhsu1231"><code>@hwhsu1231</code></a> in <a href="https://redirect.github.com/authlib/authlib/pull/901">authlib/authlib#901</a></li> <li>fix(oauth): enforce JOSE key, scope, and audience validation by <a href="https://github.com/lepture"><code>@lepture</code></a> in <a href="https://redirect.github.com/authlib/authlib/pull/945">authlib/authlib#945</a></li> <li>AsyncOpenIDMixin.parse_id_token: return None when id_token is absent, matching the sync client by <a href="https://github.com/ckarnell"><code>@ckarnell</code></a> in <a href="https://redirect.github.com/authlib/authlib/pull/924">authlib/authlib#924</a></li> <li>fix(oauth): enforce nonce and JAR request validation by <a href="https://github.com/lepture"><code>@lepture</code></a> in <a href="https://redirect.github.com/authlib/authlib/pull/949">authlib/authlib#949</a></li> <li>fix(oauth): require client authentication for ID-JAG grants by <a href="https://github.com/lepture"><code>@lepture</code></a> in <a href="https://redirect.github.com/authlib/authlib/pull/955">authlib/authlib#955</a></li> </ul> <h2>New Contributors</h2> <ul> <li><a href="https://github.com/BinoyOza-okta"><code>@BinoyOza-okta</code></a> made their first contribution in <a href="https://redirect.github.com/authlib/authlib/pull/898">authlib/authlib#898</a></li> <li><a href="https://github.com/loporto"><code>@loporto</code></a> made their first contribution in <a href="https://redirect.github.com/authlib/authlib/pull/938">authlib/authlib#938</a></li> <li><a href="https://github.com/cpruijsen"><code>@cpruijsen</code></a> made their first contribution in <a href="https://redirect.github.com/authlib/authlib/pull/942">authlib/authlib#942</a></li> <li><a href="https://github.com/juneja-varun"><code>@juneja-varun</code></a> made their first contribution in <a href="https://redirect.github.com/authlib/authlib/pull/929">authlib/authlib#929</a></li> <li><a href="https://github.com/hwhsu1231"><code>@hwhsu1231</code></a> made their first contribution in <a href="https://redirect.github.com/authlib/authlib/pull/901">authlib/authlib#901</a></li> <li><a href="https://github.com/ckarnell"><code>@ckarnell</code></a> made their first contribution in <a href="https://redirect.github.com/authlib/authlib/pull/924">authlib/authlib#924</a></li> </ul> <p><strong>Full Changelog</strong>: <a href="https://github.com/authlib/authlib/compare/v1.8.0...v1.9.0">https://github.com/authlib/authlib/compare/v1.8.0...v1.9.0</a></p> </blockquote> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/authlib/authlib/commit/46b94870d915ee77430da8fa2a358378d90b3a45"><code>46b9487</code></a> chore: release 1.9.1</li> <li><a href="https://github.com/authlib/authlib/commit/abb3f49dd97b086ade807942957ffdf4949d9f30"><code>abb3f49</code></a> docs: use the issuer identifier as ID-JAG audience and fix broken links</li> <li><a href="https://github.com/authlib/authlib/commit/1bd2a313492ce0a4d0571c150730907aa3fc91ff"><code>1bd2a31</code></a> Merge commit from fork</li> <li><a href="https://github.com/authlib/authlib/commit/311da11e41ae44fac570ac5224a45e0fec993939"><code>311da11</code></a> docs: more detailed PKCE instructions</li> <li><a href="https://github.com/authlib/authlib/commit/873f72c0345a6fc9b303b2e686bab29cab90f4ac"><code>873f72c</code></a> docs: rpinitiated instructions</li> <li><a href="https://github.com/authlib/authlib/commit/4ff30db442c70e29486e1982cb0ad37c037f5f4b"><code>4ff30db</code></a> Merge commit from fork</li> <li><a href="https://github.com/authlib/authlib/commit/9a86ff3e54e3c87d419d425c105f03fd84f3fe39"><code>9a86ff3</code></a> docs: rpinitiated sequence chart</li> <li><a href="https://github.com/authlib/authlib/commit/1c357571408cad6c9a3cc08ea6df96df5e4edaf7"><code>1c35757</code></a> docs: RFC 9101 sequence chart</li> <li><a href="https://github.com/authlib/authlib/commit/a755e2869f07710a5077784d04807bbe9bfd8026"><code>a755e28</code></a> docs: add a sequence diagram to the token introspection page</li> <li><a href="https://github.com/authlib/authlib/commit/1996c567ed325c5e328f3c00dc7452ff79a89bd2"><code>1996c56</code></a> docs: PKCE flow chart illustration</li> <li>Additional commits viewable in <a href="https://github.com/authlib/authlib/compare/v1.8.0...v1.9.1">compare view</a></li> </ul> </details> <br /> Updates `apprise` from 2.0.0 to 2.0.1 <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/caronc/apprise/releases">apprise's releases</a>.</em></p> <blockquote> <h2>Apprise v2.0.1</h2> <h2>What's Changed</h2> <p>Since the release of v2.0.0 there were some issues raised that I feel were major enough to to warrant a small update release. The big one is the handlng of markdown text.</p> <p>I had merged a few enhancements too; so they're thrown in this mini release as well.</p> <h3>🐞 Bugfixes</h3> <ul> <li>Escape unmatched markup characters for Telegram Markdown v1 by <a href="https://github.com/SulimanAbdulrazzaq"><code>@SulimanAbdulrazzaq</code></a> in <a href="https://redirect.github.com/caronc/apprise/pull/1751">caronc/apprise#1751</a></li> <li>fix(matrix): accept HTTP 202 Accepted status code for Matrix responses by <a href="https://github.com/szhu25"><code>@szhu25</code></a> in <a href="https://redirect.github.com/caronc/apprise/pull/1754">caronc/apprise#1754</a></li> <li>fix(matrix): preserve title/body separation in rich notifications by <a href="https://github.com/coder6955"><code>@coder6955</code></a> in <a href="https://redirect.github.com/caronc/apprise/pull/1756">caronc/apprise#1756</a></li> <li>fixed html issue with flock in <a href="https://redirect.github.com/caronc/apprise/pull/1757">caronc/apprise#1757</a></li> <li>v2 Format Conversion Regression in <a href="https://redirect.github.com/caronc/apprise/pull/1761">caronc/apprise#1761</a></li> </ul> <h3>💡 Features</h3> <ul> <li>Rewrite spush:// for the new Simplepush API with tasks, attachments, ... by <a href="https://github.com/tymm"><code>@tymm</code></a> in <a href="https://redirect.github.com/caronc/apprise/pull/1759">caronc/apprise#1759</a></li> <li>feat: support Nextcloud Talk bot authentication by <a href="https://github.com/beemines"><code>@beemines</code></a> in <a href="https://redirect.github.com/caronc/apprise/pull/1758">caronc/apprise#1758</a></li> <li>Telegram photo and video album support in <a href="https://redirect.github.com/caronc/apprise/pull/1762">caronc/apprise#1762</a></li> </ul> <h3>❤️ Life-Cycle Support</h3> <ul> <li>BulkSMS reference updates user -> token, pass -> secret in <a href="https://redirect.github.com/caronc/apprise/pull/1766">caronc/apprise#1766</a></li> <li>Update LoC badge by <a href="https://github.com/github-actions"><code>@github-actions</code></a>[bot] in <a href="https://redirect.github.com/caronc/apprise/pull/1752">caronc/apprise#1752</a></li> <li>Run the test suite in parallel with pytest-xdist in <a href="https://redirect.github.com/caronc/apprise/pull/1763">caronc/apprise#1763</a></li> <li>Only load PyYAML when YAML configuration is used in <a href="https://redirect.github.com/caronc/apprise/pull/1765">caronc/apprise#1765</a></li> </ul> <h2>Installation</h2> <p>Apprise is available <a href="https://pypi.org/project/apprise/">on PyPI</a> through <em>pip</em>:</p> <pre lang="bash"><code># Install Apprise v2.0.1 from PyPI pip install apprise==2.0.1 </code></pre> <p>If you use <a href="https://docs.astral.sh/uv/">uv</a>:</p> <pre lang="bash"><code># Install the apprise command uv tool install apprise==2.0.1 </code></pre> <h2>New Contributors</h2> <ul> <li><a href="https://github.com/szhu25"><code>@szhu25</code></a> made their first contribution in <a href="https://redirect.github.com/caronc/apprise/pull/1754">caronc/apprise#1754</a></li> <li><a href="https://github.com/coder6955"><code>@coder6955</code></a> made their first contribution in <a href="https://redirect.github.com/caronc/apprise/pull/1756">caronc/apprise#1756</a></li> <li><a href="https://github.com/tymm"><code>@tymm</code></a> made their first contribution in <a href="https://redirect.github.com/caronc/apprise/pull/1759">caronc/apprise#1759</a></li> <li><a href="https://github.com/beemines"><code>@beemines</code></a> made their first contribution in <a href="https://redirect.github.com/caronc/apprise/pull/1758">caronc/apprise#1758</a></li> </ul> <p><strong>Full Changelog</strong>: <a href="https://github.com/caronc/apprise/compare/v2.0.0...v2.0.1">https://github.com/caronc/apprise/compare/v2.0.0...v2.0.1</a></p> </blockquote> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/caronc/apprise/commit/81739e9a1187f986a09281b5d0c25c806e8152e0"><code>81739e9</code></a> bumped version to v2.0.1</li> <li><a href="https://github.com/caronc/apprise/commit/6f5802654f02fb0513db6d31ba1738c4be39750d"><code>6f58026</code></a> Only load PyYAML when YAML configuration is used (<a href="https://redirect.github.com/caronc/apprise/issues/1765">#1765</a>)</li> <li><a href="https://github.com/caronc/apprise/commit/b7d5d31c9f5f482af8d316a00e344b059f148f6c"><code>b7d5d31</code></a> BulkSMS reference updates user -> token, pass -> secret (<a href="https://redirect.github.com/caronc/apprise/issues/1766">#1766</a>)</li> <li><a href="https://github.com/caronc/apprise/commit/c6817afb1bf3449e4d2cbbe0c5c731accba1ea4c"><code>c6817af</code></a> Run the test suite in parallel with pytest-xdist (<a href="https://redirect.github.com/caronc/apprise/issues/1763">#1763</a>)</li> <li><a href="https://github.com/caronc/apprise/commit/5203e93971bd03f13b3e930709399093aae88368"><code>5203e93</code></a> v2 Format Conversion Regression (<a href="https://redirect.github.com/caronc/apprise/issues/1761">#1761</a>)</li> <li><a href="https://github.com/caronc/apprise/commit/fb472569430a06131e28b854ba87941ebb21b8b3"><code>fb47256</code></a> Telegram photo and video album support (<a href="https://redirect.github.com/caronc/apprise/issues/1762">#1762</a>)</li> <li><a href="https://github.com/caronc/apprise/commit/57f05eeeabe1eba11571892b4a9a37698a39c7b8"><code>57f05ee</code></a> Support Nextcloud Talk bot authentication (<a href="https://redirect.github.com/caronc/apprise/issues/1758">#1758</a>)</li> <li><a href="https://github.com/caronc/apprise/commit/fe93b0d6ff443ab6c30561b56ca56ff78ed3e3d3"><code>fe93b0d</code></a> Updates to spush:// for the new Simplepush API with tasks + attachments (<a href="https://redirect.github.com/caronc/apprise/issues/1759">#1759</a>)</li> <li><a href="https://github.com/caronc/apprise/commit/bfbf6590ee9dc1f76a8e3f4e49fb9fba8d77ba9d"><code>bfbf659</code></a> fixed html issue with flock (<a href="https://redirect.github.com/caronc/apprise/issues/1757">#1757</a>)</li> <li><a href="https://github.com/caronc/apprise/commit/ab9e23fae137b6542b24d9106c21121f3f482b96"><code>ab9e23f</code></a> fix(matrix): preserve title/body separation in rich notifications (<a href="https://redirect.github.com/caronc/apprise/issues/1756">#1756</a>)</li> <li>Additional commits viewable in <a href="https://github.com/caronc/apprise/compare/v2.0.0...v2.0.1">compare view</a></li> </ul> </details> <br /> Updates `publicsuffixlist` from 1.0.2.20260925 to 1.1.0.20261010 <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/ko-zu/psl/blob/master/CHANGES.md">publicsuffixlist's changelog</a>.</em></p> <blockquote> <h3>1.1.0 (2026-10-10)</h3> <p>This version drops support for Python 3.5, 3.6 and 3.7, and now requires Python 3.8 or later.</p> <p>Packaging has been migrated to PEP 621 metadata in <code>pyproject.toml</code> using hatchling, replacing <code>setup.py</code>, <code>setup.cfg</code> and <code>MANIFEST.in</code>. The version is now read from <code>publicsuffixlist.__version__</code>, and development dependencies are locked with uv.</p> <ul> <li>Add PEP 561 <code>py.typed</code> marker and complete type annotations for the public API, including <code>compat</code> and the update script.</li> <li>Add an <code>accept_unknown</code> keyword argument to <code>is_private()</code> and <code>is_public()</code>.</li> <li>Fix <code>subdomain()</code> to honor the per-call <code>accept_unknown</code> argument, and to return <code>None</code> for invalid domains instead of raising <code>TypeError</code>.</li> <li>Correct the <code>subdomain()</code> and <code>privateparts()</code> overload signatures.</li> <li>Handle a malformed <code>Last-Modified</code> response header in the update script.</li> <li>Run tests with uv on Python 3.8 and 3.14, and update CI actions.</li> </ul> <h3>1.0.2 (2024-07-13)</h3> <ul> <li>Use <a href="https://github.com/typing"><code>@typing</code></a>.overload to indicate str-to-str domain input/output. <a href="https://redirect.github.com/ko-zu/psl/issues/32">#32</a>.</li> <li>Address deprecation of ByteString in python 3.14.</li> </ul> <h3>1.0.1 (2024-06-22)</h3> <p>Fix internal logic where domain name passed as a tuple of bytes, that contains UTF-8 encoded non-ascii chars, unintentionally matched PSL. Fixes <a href="https://redirect.github.com/ko-zu/psl/issues/31">#31</a>.</p> <h3>1.0.0 (2024-06-20)</h3> <p>This version drops support for Python 2.x and 3.4.</p> <p>The internal logic has been slightly changed to address conflicting evaluation rules between the PSL wiki and the test data. As with versions before 1.0.0, this module assumes that wildcards have implicit public declarations on the wildcard root.</p> <p>With the minimum Python version changed to 3.5, type annotations have been added to exposed API methods to clarify expected input types. For example, psl.publicsuffix() now accepts <code>str</code> or <code>Tuple[bytes, ...]</code>.</p> <ul> <li>Add tuple of bytes style input</li> <li>Add keep_case keyword argument</li> <li>Accept trailing dot</li> <li>Migrate CI to GitHub Actions</li> </ul> <h3>0.10.0 (2023-04-29)</h3> <p>The last version works on Python 2.7</p> </blockquote> </details> <details> <summary>Commits</summary> <ul> <li>See full diff in <a href="https://github.com/ko-zu/psl/commits">compare view</a></li> </ul> </details> <br /> Updates `seleniumbase` from 4.54.12 to 4.56.2 <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/seleniumbase/SeleniumBase/releases">seleniumbase's releases</a>.</em></p> <blockquote> <h2>4.56.2 - Update decorators and dependencies</h2> <h2>Update decorators and dependencies</h2> <ul> <li><a href="https://github.com/seleniumbase/SeleniumBase/commit/d3ab07e8434d417bd47f989dddfbe5de78c1e3a7">Update the print_runtime() decorator</a> --> This resolves <a href="https://redirect.github.com/seleniumbase/SeleniumBase/issues/4527">seleniumbase/SeleniumBase#4527</a></li> <li><a href="https://github.com/seleniumbase/SeleniumBase/commit/68bb983dd81eec140e0531ec03edc7075ac314ec">Refresh Python dependencies</a></li> <li><a href="https://github.com/seleniumbase/SeleniumBase/commit/59a9ef3a51c6489d2edad14be4947ca2df7e3f98">Update CDP Mode examples</a></li> </ul> <h2>What's Changed</h2> <ul> <li>Update decorators and dependencies by <a href="https://github.com/mdmintz"><code>@mdmintz</code></a> in <a href="https://redirect.github.com/seleniumbase/SeleniumBase/pull/4528">seleniumbase/SeleniumBase#4528</a></li> </ul> <p><strong>Full Changelog</strong>: <a href="https://github.com/seleniumbase/SeleniumBase/compare/v4.56.1...v4.56.2">https://github.com/seleniumbase/SeleniumBase/compare/v4.56.1...v4.56.2</a></p> <h2>4.56.1 - Fix dependency issue caused by a yank</h2> <h2>Fix dependency issue caused by a yank</h2> <ul> <li><a href="https://github.com/seleniumbase/SeleniumBase/commit/5b340211db401cce84b95ef58a937a3b88d9cd6d">Refresh Python dependencies</a> --> This resolves <a href="https://redirect.github.com/seleniumbase/SeleniumBase/issues/4525">seleniumbase/SeleniumBase#4525</a></li> <li><a href="https://redirect.github.com/seleniumbase/SeleniumBase/pull/4526/commits/98e5aa2b4eb30f1be74c7d827bdc45b86a97ce72">Refresh a Python dependency</a> --> Update a dependency that dropped a version of Python.</li> </ul> <h2>4.56.0 - Full Python 3.15 Support</h2> <h2>Full Python 3.15 Support</h2> <ul> <li><a href="https://github.com/seleniumbase/SeleniumBase/commit/55b294c8263eef3ac03df107de289ed295ecdb2f">Refresh Python dependencies</a> --> This resolves <a href="https://redirect.github.com/seleniumbase/SeleniumBase/issues/4523">seleniumbase/SeleniumBase#4523</a></li> <li><a href="https://github.com/seleniumbase/SeleniumBase/commit/7d8ea74d25255c7195d56606b035fadb2d0b86ed">Update driver methods</a></li> <li><a href="https://github.com/seleniumbase/SeleniumBase/commit/ce8281135cb717cc5a628651f88c6bfe1a58b179">Update versioning for the MCP server</a></li> </ul> <h2>What's Changed</h2> <ul> <li>Full Python 3.15 Support by <a href="https://github.com/mdmintz"><code>@mdmintz</code></a> in <a href="https://redirect.github.com/seleniumbase/SeleniumBase/pull/4524">seleniumbase/SeleniumBase#4524</a></li> </ul> <p><strong>Full Changelog</strong>: <a href="https://github.com/seleniumbase/SeleniumBase/compare/v4.55.2...v4.56.0">https://github.com/seleniumbase/SeleniumBase/compare/v4.55.2...v4.56.0</a></p> <h2>4.55.2 - Refresh Dependencies and Examples</h2> <h2>Refresh Dependencies and Examples</h2> <ul> <li><a href="https://github.com/seleniumbase/SeleniumBase/commit/de21ad5ebc8690d7d9f8a16d775a7fb36fd4545a">Refresh Python dependencies</a></li> <li><a href="https://github.com/seleniumbase/SeleniumBase/commit/e22408ee9193189143d68088d18759c59b734fd7">Update CDP Mode examples</a></li> <li><a href="https://github.com/seleniumbase/SeleniumBase/commit/1ab5d04ade3c05807b2e75fc1e3acddbaab389d5">Update Stealthy Playwright Mode examples</a></li> <li><a href="https://github.com/seleniumbase/SeleniumBase/commit/0adae72339390d9f24bd38c9633dffe415953a45">Update the ReadMe</a></li> </ul> <h2>What's Changed</h2> <ul> <li>Refresh Dependencies and Examples by <a href="https://github.com/mdmintz"><code>@mdmintz</code></a> in <a href="https://redirect.github.com/seleniumbase/SeleniumBase/pull/4522">seleniumbase/SeleniumBase#4522</a></li> </ul> <p><strong>Full Changelog</strong>: <a href="https://github.com/seleniumbase/SeleniumBase/compare/v4.55.1...v4.55.2">https://github.com/seleniumbase/SeleniumBase/compare/v4.55.1...v4.55.2</a></p> <h2>4.55.1 - Fast Mode for CDP Mode</h2> <h2>Fast Mode for CDP Mode</h2> <ul> <li><a href="https://redirect.github.com/seleniumbase/SeleniumBase/pull/4520/commits/f1613ea974f16631739d9301cd31dcef65dce32b">Add Fast Mode to CDP Mode</a> --> This resolves <a href="https://redirect.github.com/seleniumbase/SeleniumBase/issues/4519">seleniumbase/SeleniumBase#4519</a></li> </ul> <!-- raw HTML omitted --> </blockquote> <p>... (truncated)</p> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/seleniumbase/SeleniumBase/commit/c4524941fea728ad45033ab4084bf55566e609c0"><code>c452494</code></a> Merge pull request <a href="https://redirect.github.com/seleniumbase/SeleniumBase/issues/4528">#4528</a> from seleniumbase/decorators-and-dependencies</li> <li><a href="https://github.com/seleniumbase/SeleniumBase/commit/8738b091c4bc9ff6172b46264b7054f3e111d264"><code>8738b09</code></a> Version 4.56.2</li> <li><a href="https://github.com/seleniumbase/SeleniumBase/commit/ed62dcb9eab24e60500f46cd3f9770454276603e"><code>ed62dcb</code></a> Update MCP server versioning</li> <li><a href="https://github.com/seleniumbase/SeleniumBase/commit/59a9ef3a51c6489d2edad14be4947ca2df7e3f98"><code>59a9ef3</code></a> Update CDP Mode examples</li> <li><a href="https://github.com/seleniumbase/SeleniumBase/commit/68bb983dd81eec140e0531ec03edc7075ac314ec"><code>68bb983</code></a> Refresh Python dependencies</li> <li><a href="https://github.com/seleniumbase/SeleniumBase/commit/d3ab07e8434d417bd47f989dddfbe5de78c1e3a7"><code>d3ab07e</code></a> Update the <code>print_runtime()</code> decorator</li> <li><a href="https://github.com/seleniumbase/SeleniumBase/commit/6c09b0b828fba8ce9a1c2a947f410b6943045593"><code>6c09b0b</code></a> Update ReadMe files</li> <li><a href="https://github.com/seleniumbase/SeleniumBase/commit/ce0493bd99148f8c30a98525ef9c14a3b44977a5"><code>ce0493b</code></a> Update the ReadMe</li> <li><a href="https://github.com/seleniumbase/SeleniumBase/commit/ac18d10f63c7bfb295c6aff7c138905581af09c3"><code>ac18d10</code></a> Update the UC Mode ReadMe</li> <li><a href="https://github.com/seleniumbase/SeleniumBase/commit/86de26f2d0f475e79b0e0a751f4286e60250e8ef"><code>86de26f</code></a> Refresh mkdocs dependencies</li> <li>Additional commits viewable in <a href="https://github.com/seleniumbase/SeleniumBase/compare/v4.54.12...v4.56.2">compare view</a></li> </ul> </details> <br /> Updates `basedpyright` from 1.40.1 to 1.40.2 <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/detachhead/basedpyright/releases">basedpyright's releases</a>.</em></p> <blockquote> <h2>v1.40.2 (pyright 1.1.414)</h2> <h2>What's Changed</h2> <ul> <li>Fix typeshed packaging for the <code>browser-basedpyright</code> npm package by <a href="https://github.com/BertalanD"><code>@BertalanD</code></a> in <a href="https://redirect.github.com/DetachHead/basedpyright/pull/1890">DetachHead/basedpyright#1890</a></li> <li>generate builtin docstrings for python 3.15 by <a href="https://github.com/DetachHead"><code>@DetachHead</code></a> in <a href="https://redirect.github.com/DetachHead/basedpyright/pull/1895">DetachHead/basedpyright#1895</a></li> </ul> <p><strong>Full Changelog</strong>: <a href="https://github.com/DetachHead/basedpyright/compare/v1.40.1...v1.40.2">https://github.com/DetachHead/basedpyright/compare/v1.40.1...v1.40.2</a></p> </blockquote> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/DetachHead/basedpyright/commit/344759687c2fff3bd0a7d6a83a9d1847f806b795"><code>3447596</code></a> asdf</li> <li><a href="https://github.com/DetachHead/basedpyright/commit/9c403f159a9680775b34c6925e6fa33bc675323e"><code>9c403f1</code></a> retry vscode publish because vs marketplace was down</li> <li><a href="https://github.com/DetachHead/basedpyright/commit/fa4b52d9428c0f355c95af2056cfd4edd4e6e5da"><code>fa4b52d</code></a> 1.40.2</li> <li><a href="https://github.com/DetachHead/basedpyright/commit/3ca944f19614eabc8c610cee44cede8d3ea9fa0c"><code>3ca944f</code></a> pin python version to 3.15</li> <li><a href="https://github.com/DetachHead/basedpyright/commit/1f4822c168019322a88d90aa0d09a2ae54e25215"><code>1f4822c</code></a> add python 3.15 builtin docstrings</li> <li><a href="https://github.com/DetachHead/basedpyright/commit/77cfb2da66a34388fc940670895c9a963731ed25"><code>77cfb2d</code></a> bump python dependencies & pnpm (<a href="https://redirect.github.com/detachhead/basedpyright/issues/1877">#1877</a>)</li> <li><a href="https://github.com/DetachHead/basedpyright/commit/a8a92cd35f7b1f683ebed3ad573c4aacefa79bc6"><code>a8a92cd</code></a> formatting</li> <li><a href="https://github.com/DetachHead/basedpyright/commit/d55e86a451ec338a902140c51d48bdb21cfb1102"><code>d55e86a</code></a> Fix typeshed packaging for browser-basedpyright</li> <li><a href="https://github.com/DetachHead/basedpyright/commit/c63390c33f0877ee27c085820e1a24ec41e7def2"><code>c63390c</code></a> delete dependabot config. too much of a pain in the ass to configure it to no...</li> <li><a href="https://github.com/DetachHead/basedpyright/commit/278e99c2f2594187cc56cafba97a0265c3dfce67"><code>278e99c</code></a> delete weekly typechecker benchmark workflow</li> <li>Additional commits viewable in <a href="https://github.com/detachhead/basedpyright/compare/v1.40.1...v1.40.2">compare view</a></li> </ul> </details> <br /> Updates `prek` from 0.5.4 to 0.5.5 <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/j178/prek/releases">prek's releases</a>.</em></p> <blockquote> <h2>0.5.5</h2> <h2>Release Notes</h2> <p>Released on 2026-10-05.</p> <h3>Enhancements</h3> <ul> <li>Add Nushell completion generation (<a href="https://redirect.github.com/j178/prek/pull/2785">#2785</a>)</li> <li>Add <code>ppc64le</code> wheel and binary builds (<a href="https://redirect.github.com/j178/prek/pull/2809">#2809</a>)</li> </ul> <h3>Performance</h3> <ul> <li>Avoid JSON imports when querying Python interpreters (<a href="https://redirect.github.com/j178/prek/pull/2790">#2790</a>)</li> <li>Avoid duplicate diffs after hooks rewrite files (<a href="https://redirect.github.com/j178/prek/pull/2815">#2815</a>)</li> <li>Batch file reads in shebang checks (<a href="https://redirect.github.com/j178/prek/pull/2793">#2793</a>)</li> <li>Check cached hook environments concurrently (<a href="https://redirect.github.com/j178/prek/pull/2797">#2797</a>)</li> <li>Overlap Git discovery with worktree status checks (<a href="https://redirect.github.com/j178/prek/pull/2821">#2821</a>)</li> <li>Query staged additions only for case conflicts (<a href="https://redirect.github.com/j178/prek/pull/2802">#2802</a>)</li> <li>Reduce worker overhead in XML and pygrep checks (<a href="https://redirect.github.com/j178/prek/pull/2789">#2789</a>)</li> <li>Reuse Git worktree state during hook startup (<a href="https://redirect.github.com/j178/prek/pull/2787">#2787</a>)</li> <li>Reuse intent-to-add paths when saving unstaged changes (<a href="https://redirect.github.com/j178/prek/pull/2788">#2788</a>)</li> <li>Run Git queries concurrently for case-conflict checks (<a href="https://redirect.github.com/j178/prek/pull/2792">#2792</a>)</li> <li>Share Bun and Deno version queries across environments (<a href="https://redirect.github.com/j178/prek/pull/2795">#2795</a>)</li> <li>Share Lua runtime probes across hook environments (<a href="https://redirect.github.com/j178/prek/pull/2796">#2796</a>)</li> <li>Share Ruby version queries across hook environments (<a href="https://redirect.github.com/j178/prek/pull/2794">#2794</a>)</li> <li>Share mise version queries across hook environments (<a href="https://redirect.github.com/j178/prek/pull/2798">#2798</a>)</li> <li>Skip site initialization in Python interpreter probes (<a href="https://redirect.github.com/j178/prek/pull/2822">#2822</a>)</li> <li>Skip untracked files in destroyed symlink checks (<a href="https://redirect.github.com/j178/prek/pull/2799">#2799</a>)</li> <li>Skip unused file input for always-run hooks (<a href="https://redirect.github.com/j178/prek/pull/2813">#2813</a>)</li> </ul> <h3>Bug fixes</h3> <ul> <li>Preserve staged and unstaged changes on conflicted stash restore (<a href="https://redirect.github.com/j178/prek/pull/2803">#2803</a>)</li> <li>Default missing <code>core.fileMode</code> in shebang checks (<a href="https://redirect.github.com/j178/prek/pull/2832">#2832</a>)</li> <li>Match protected branch patterns from the start (<a href="https://redirect.github.com/j178/prek/pull/2829">#2829</a>)</li> <li>Normalize explicit paths in shebang index checks (<a href="https://redirect.github.com/j178/prek/pull/2831">#2831</a>)</li> <li>Preserve empty <code>trailing-whitespace</code> character sets (<a href="https://redirect.github.com/j178/prek/pull/2830">#2830</a>)</li> <li>Reject empty files in <code>check-json</code> (<a href="https://redirect.github.com/j178/prek/pull/2826">#2826</a>)</li> <li>Reject trailing data in <code>check-json</code> (<a href="https://redirect.github.com/j178/prek/pull/2828">#2828</a>)</li> <li>Round up file sizes in <code>check-added-large-files</code> (<a href="https://redirect.github.com/j178/prek/pull/2827">#2827</a>)</li> </ul> <h3>Documentation</h3> <ul> <li>Redesign the prek badge and refresh logo details (<a href="https://redirect.github.com/j178/prek/pull/2818">#2818</a>)</li> </ul> <h3>Contributors</h3> <ul> <li><a href="https://github.com/imphil"><code>@imphil</code></a></li> <li><a href="https://github.com/j178"><code>@j178</code></a></li> </ul> <!-- raw HTML omitted --> </blockquote> <p>... (truncated)</p> </details> <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/j178/prek/blob/master/CHANGELOG.md">prek's changelog</a>.</em></p> <blockquote> <h2>0.5.5</h2> <p>Released on 2026-10-05.</p> <h3>Enhancements</h3> <ul> <li>Add Nushell completion generation (<a href="https://redirect.github.com/j178/prek/pull/2785">#2785</a>)</li> <li>Add <code>ppc64le</code> wheel and binary builds (<a href="https://redirect.github.com/j178/prek/pull/2809">#2809</a>)</li> </ul> <h3>Performance</h3> <ul> <li>Avoid JSON imports when querying Python interpreters (<a href="https://redirect.github.com/j178/prek/pull/2790">#2790</a>)</li> <li>Avoid duplicate diffs after hooks rewrite files (<a href="https://redirect.github.com/j178/prek/pull/2815">#2815</a>)</li> <li>Batch file reads in shebang checks (<a href="https://redirect.github.com/j178/prek/pull/2793">#2793</a>)</li> <li>Check cached hook environments concurrently (<a href="https://redirect.github.com/j178/prek/pull/2797">#2797</a>)</li> <li>Overlap Git discovery with worktree status checks (<a href="https://redirect.github.com/j178/prek/pull/2821">#2821</a>)</li> <li>Query staged additions only for case conflicts (<a href="https://redirect.github.com/j178/prek/pull/2802">#2802</a>)</li> <li>Reduce worker overhead in XML and pygrep checks (<a href="https://redirect.github.com/j178/prek/pull/2789">#2789</a>)</li> <li>Reuse Git worktree state during hook startup (<a href="https://redirect.github.com/j178/prek/pull/2787">#2787</a>)</li> <li>Reuse intent-to-add paths when saving unstaged changes (<a href="https://redirect.github.com/j178/prek/pull/2788">#2788</a>)</li> <li>Run Git queries concurrently for case-conflict checks (<a href="https://redirect.github.com/j178/prek/pull/2792">#2792</a>)</li> <li>Share Bun and Deno version queries across environments (<a href="https://redirect.github.com/j178/prek/pull/2795">#2795</a>)</li> <li>Share Lua runtime probes across hook environments (<a href="https://redirect.github.com/j178/prek/pull/2796">#2796</a>)</li> <li>Share Ruby version queries across hook environments (<a href="https://redirect.github.com/j178/prek/pull/2794">#2794</a>)</li> <li>Share mise version queries across hook environments (<a href="https://redirect.github.com/j178/prek/pull/2798">#2798</a>)</li> <li>Skip site initialization in Python interpreter probes (<a href="https://redirect.github.com/j178/prek/pull/2822">#2822</a>)</li> <li>Skip untracked files in destroyed symlink checks (<a href="https://redirect.github.com/j178/prek/pull/2799">#2799</a>)</li> <li>Skip unused file input for always-run hooks (<a href="https://redirect.github.com/j178/prek/pull/2813">#2813</a>)</li> </ul> <h3>Bug fixes</h3> <ul> <li>Preserve staged and unstaged changes on conflicted stash restore (<a href="https://redirect.github.com/j178/prek/pull/2803">#2803</a>)</li> <li>Default missing <code>core.fileMode</code> in shebang checks (<a href="https://redirect.github.com/j178/prek/pull/2832">#2832</a>)</li> <li>Match protected branch patterns from the start (<a href="https://redirect.github.com/j178/prek/pull/2829">#2829</a>)</li> <li>Normalize explicit paths in shebang index checks (<a href="https://redirect.github.com/j178/prek/pull/2831">#2831</a>)</li> <li>Preserve empty <code>trailing-whitespace</code> character sets (<a href="https://redirect.github.com/j178/prek/pull/2830">#2830</a>)</li> <li>Reject empty files in <code>check-json</code> (<a href="https://redirect.github.com/j178/prek/pull/2826">#2826</a>)</li> <li>Reject trailing data in <code>check-json</code> (<a href="https://redirect.github.com/j178/prek/pull/2828">#2828</a>)</li> <li>Round up file sizes in <code>check-added-large-files</code> (<a href="https://redirect.github.com/j178/prek/pull/2827">#2827</a>)</li> </ul> <h3>Documentation</h3> <ul> <li>Redesign the prek badge and refresh logo details (<a href="https://redirect.github.com/j178/prek/pull/2818">#2818</a>)</li> </ul> <h3>Contributors</h3> <ul> <li><a href="https://github.com/imphil"><code>@imphil</code></a></li> <li><a href="https://github.com/j178"><code>@j178</code></a></li> </ul> </blockquote> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/j178/prek/commit/77cca6719ea8e3d9cc7a973e2c9e7648f4b0381d"><code>77cca67</code></a> Bump version to 0.5.5 (<a href="https://redirect.github.com/j178/prek/issues/2839">#2839</a>)</li> <li><a href="https://github.com/j178/prek/commit/f4e26958292ae25403f40300050cf943e67132c3"><code>f4e2695</code></a> Update Rust crate jsonc-parser to 0.34.0 (<a href="https://redirect.github.com/j178/prek/issues/2838">#2838</a>)</li> <li><a href="https://github.com/j178/prek/commit/399e9d1158fa0377073ddd9db49e01e4b8fba49b"><code>399e9d1</code></a> Update GitHub Actions (<a href="https://redirect.github.com/j178/prek/issues/2837">#2837</a>)</li> <li><a href="https://github.com/j178/prek/commit/19e77d12b34f51c2d296eeeed3cc470c31372c1a"><code>19e77d1</code></a> Update prek hooks (<a href="https://redirect.github.com/j178/prek/issues/2771">#2771</a>)</li> <li><a href="https://github.com/j178/prek/commit/e261e0cce1aac6625960397cf513254e2e72bdf1"><code>e261e0c</code></a> Update dependency uv to v0.12.19 (<a href="https://redirect.github.com/j178/prek/issues/2835">#2835</a>)</li> <li><a href="https://github.com/j178/prek/commit/bc53e2ce2041d70d1c19c9063cbc1b1c570b2422"><code>bc53e2c</code></a> Update Rust crate thiserror to v2.0.21 (<a href="https://redirect.github.com/j178/prek/issues/2836">#2836</a>)</li> <li><a href="https://github.com/j178/prek/commit/4a981d25ecd2b6f43aa0c3525d589428c5a0de29"><code>4a981d2</code></a> Default missing core.fileMode in shebang checks (<a href="https://redirect.github.com/j178/prek/issues/2832">#2832</a>)</li> <li><a href="https://github.com/j178/prek/commit/e0310220a5d428d2fb49878c538a61458a0ed62f"><code>e031022</code></a> Preserve empty trailing-whitespace character sets (<a href="https://redirect.github.com/j178/prek/issues/2830">#2830</a>)</li> <li><a href="https://github.com/j178/prek/commit/0b1871acd9164b566e6e9c10aff0123a68e0352c"><code>0b1871a</code></a> Normalize explicit paths in shebang index checks (<a href="https://redirect.github.com/j178/prek/issues/2831">#2831</a>)</li> <li><a href="https://github.com/j178/prek/commit/9d4aedefcc3c152e87954b19d847df7f4662db06"><code>9d4aede</code></a> Match protected branch patterns from the start (<a href="https://redirect.github.com/j178/prek/issues/2829">#2829</a>)</li> <li>Additional commits viewable in <a href="https://github.com/j178/prek/compare/v0.5.4...v0.5.5">compare view</a></li> </ul> </details> <br /> Updates `ruff` from 0.16.9 to 0.17.1 <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/astral-sh/ruff/releases">ruff's releases</a>.</em></p> <blockquote> <h2>0.17.1</h2> <h2>Release Notes</h2> <p>Released on 2026-10-15.</p> <h3>Preview features</h3> <ul> <li>[<code>pycodestyle</code>] Don't treat <code>None</code>, <code>True</code>, or <code>False</code> as keywords (<code>E271</code>-<code>E274</code>) (<a href="https://redirect.github.com/astral-sh/ruff/pull/29322">#29322</a>)</li> </ul> <h3>Bug fixes</h3> <ul> <li>Fix dedent with multiple leading comments (<a href="https://redirect.github.com/astral-sh/ruff/pull/29382">#29382</a>)</li> <li>[<code>flake8-pyi</code>] Detect legacy positional-only parameters in <code>__new__</code> methods (<code>PYI063</code>) (<a href="https://redirect.github.com/astral-sh/ruff/pull/28502">#28502</a>)</li> <li>[<code>flake8-pyi</code>] Fix false positives on quoted annotations (<code>PYI036</code>) (<a href="https://redirect.github.com/astral-sh/ruff/pull/29274">#29274</a>)</li> <li>[<code>perflint</code>] Avoid invalid comprehension suggestions (<code>PERF401</code>, <code>PERF403</code>) (<a href="https://redirect.github.com/astral-sh/ruff/pull/29366">#29366</a>)</li> </ul> <h3>Rule changes</h3> <ul> <li>Treat more <code>collections</code> and <code>weakref</code> containers as mutable (<a href="https://redirect.github.com/astral-sh/ruff/pull/29213">#29213</a>)</li> </ul> <h3>Documentation</h3> <ul> <li>[<code>flake8-import-conventions</code>] Update default and example <code>aliases</code> (<a href="https://redirect.github.com/astral-sh/ruff/pull/29333">#29333</a>)</li> </ul> <h3>Contributors</h3> <ul> <li><a href="https://github.com/fixfon"><code>@fixfon</code></a></li> <li><a href="https://github.com/mmaxjr"><code>@mmaxjr</code></a></li> <li><a href="https://github.com/joshuavetos"><code>@joshuavetos</code></a></li> <li><a href="https://github.com/nekomario28"><code>@nekomario28</code></a></li> <li><a href="https://github.com/ntBre"><code>@ntBre</code></a></li> <li><a href="https://github.com/shan3520"><code>@shan3520</code></a></li> </ul> <h2>Install ruff 0.17.1</h2> <h3>Install prebuilt binaries via shell script</h3> <pre lang="sh"><code>curl --proto '=https' --tlsv1.2 -LsSf https://releases.astral.sh/github/ruff/releases/download/0.17.1/ruff-installer.sh | sh </code></pre> <h3>Install prebuilt binaries via powershell script</h3> <pre lang="sh"><code>powershell -ExecutionPolicy Bypass -c "irm https://releases.astral.sh/github/ruff/releases/download/0.17.1/ruff-installer.ps1 | iex" </code></pre> <h2>Download ruff 0.17.1</h2> <p>| File | Platform | Checksum |</p> <!-- raw HTML omitted --> </blockquote> <p>... (truncated)</p> </details> <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md">ruff's changelog</a>.</em></p> <blockquote> <h2>0.17.1</h2> <p>Released on 2026-10-15.</p> <h3>Preview features</h3> <ul> <li>[<code>pycodestyle</code>] Don't treat <code>None</code>, <code>True</code>, or <code>False</code> as keywords (<code>E271</code>-<code>E274</code>) (<a href="https://redirect.github.com/astral-sh/ruff/pull/29322">#29322</a>)</li> </ul> <h3>Bug fixes</h3> <ul> <li>Fix dedent with multiple leading comments (<a href="https://redirect.github.com/astral-sh/ruff/pull/29382">#29382</a>)</li> <li>[<code>flake8-pyi</code>] Detect legacy positional-only parameters in <code>__new__</code> methods (<code>PYI063</code>) (<a href="https://redirect.github.com/astral-sh/ruff/pull/28502">#28502</a>)</li> <li>[<code>flake8-pyi</code>] Fix false positives on quoted annotations (<code>PYI036</code>) (<a href="https://redirect.github.com/astral-sh/ruff/pull/29274">#29274</a>)</li> <li>[<code>perflint</code>] Avoid invalid comprehension suggestions (<code>PERF401</code>, <code>PERF403</code>) (<a href="https://redirect.github.com/astral-sh/ruff/pull/29366">#29366</a>)</li> </ul> <h3>Rule changes</h3> <ul> <li>Treat more <code>collections</code> and <code>weakref</code> containers as mutable (<a href="https://redirect.github.com/astral-sh/ruff/pull/29213">#29213</a>)</li> </ul> <h3>Documentation</h3> <ul> <li>[<code>flake8-import-conventions</code>] Update default and example <code>aliases</code> (<a href="https://redirect.github.com/astral-sh/ruff/pull/29333">#29333</a>)</li> </ul> <h3>Contributors</h3> <ul> <li><a href="https://github.com/fixfon"><code>@fixfon</code></a></li> <li><a href="https://github.com/mmaxjr"><code>@mmaxjr</code></a></li> <li><a href="https://github.com/joshuavetos"><code>@joshuavetos</code></a></li> <li><a href="https://github.com/nekomario28"><code>@nekomario28</code></a></li> <li><a href="https://github.com/ntBre"><code>@ntBre</code></a></li> <li><a href="https://github.com/shan3520"><code>@shan3520</code></a></li> </ul> <h2>0.17.0</h2> <p>Released on 2026-10-09.</p> <p>The executables in our macOS and Windows release archives and <code>ruff</code> wheels are now code-signed. macOS executables are signed with an Apple Developer ID certificate and notarized by Apple. Windows executables have timestamped Authenticode signatures from Azure Artifact Signing. This enables verification of the release publisher and binary integrity, supports publisher-based allowlisting, and should reduce security warnings and antivirus false positives.</p> <h3>Breaking changes</h3> <ul> <li> <p>Update the default and latest Python versions for 3.15 (<a href="https://redirect.github.com/astral-sh/ruff/pull/28792">#28792</a>)</p> <p>Ruff now defaults to Python 3.11 instead of 3.10 when no Python version is configured through <a href="https://docs.astral.sh/ruff/settings/#target-version"><code>target-version</code></a> or <a href="https://docs.astral.sh/ruff/configuration/#inferring-the-python-version"><code>requires-python</code></a>. When checking for syntax errors without a configured Python version, Ruff now defaults to Python 3.15</p> </li> </ul> <!-- raw HTML omitted --> </blockquote> <p>... (truncated)</p> </details> <details> <summary>Commits</summary> <ul> <li><a href="https://github.com/astral-sh/ruff/commit/4683270c69cbdaf6ad64d3f983fc458d5a43b41f"><code>4683270</code></a> Bump version to 0.17.1 (<a href="https://redirect.github.com/astral-sh/ruff/issues/29420">#29420</a>)</li> <li><a href="https://github.com/astral-sh/ruff/commit/3514027edb659bbc3c787d355be9d130e5587f15"><code>3514027</code></a> [ty] Update typing conformance suite pin (<a href="https://redirect.github.com/astral-sh/ruff/issues/29417">#29417</a>)</li> <li><a href="https://github.com/astral-sh/ruff/commit/829455624d78f2e89669e4b4b14af2b96abdb1ae"><code>8294556</code></a> Update referenced PR security-review workflow (<a href="https://redirect.github.com/astral-sh/ruff/issues/29237">#29237</a>)</li> <li><a href="https://github.com/astral-sh/ruff/commit/d1e1b1f69b511df4385f64b510eeec4da01c1a0e"><code>d1e1b1f</code></a> [ty] Preserve recursive aliases when rebuilding intersections (<a href="https://redirect.github.com/astral-sh/ruff/issues/29057">#29057</a>)</li> <li><a href="https://github.com/astral-sh/ruff/commit/93526150df078af7dd8fc4226cdcc469539d2001"><code>9352615</code></a> [<code>perflint</code>] Avoid invalid comprehension suggestions (<code>PERF401</code>, <code>PERF403</code>) (...</li> <li><a href="https://github.com/astral-sh/ruff/commit/83a3afc3156d73ae4296f3fa74ede28e4c72bfcd"><code>83a3afc</code></a> Fix dedent with multiple leading comments (<a href="https://redirect.github.com/astral-sh/ruff/issues/29382">#29382</a>)</li> <li><a href="https://github.com/astral-sh/ruff/commit/b42a8734410230f4529151782cae951b99bed858"><code>b42a873</code></a> [ty] Clarify object attribute write-contract rationale (<a href="https://redirect.github.com/astral-sh/ruff/issues/29384">#29384</a>)</li> <li><a href="https://github.com/astral-sh/ruff/commit/d01678ebf594c97a7767d4372061c1f80ae5b5bb"><code>d01678e</code></a> [ty] Clarify object attribute write-contract rationale (<a href="https://redirect.github.com/astral-sh/ruff/issues/29384">#29384</a>)</li> <li><a href="https://github.com/astral-sh/ruff/commit/355b42a7719d8a555e3ee50c89848b42d8a11eb5"><code>355b42a</code></a> [ty] Avoid writable override contracts from object (<a href="https://redirect.github.com/astral-sh/ruff/issues/29373">#29373</a>)</li> <li><a href="https://github.com/astral-sh/ruff/commit/e26e6d2a54ac2c5e1f5b1945042de3ff3885bf8e"><code>e26e6d2</code></a> [ty] Collect intersection inference through constraint relations (<a href="https://redirect.github.com/astral-sh/ruff/issues/28677">#28677</a>)</li> <li>Additional commits viewable in <a href="https://github.com/astral-sh/ruff/compare/0.16.9...0.17.1">compare view</a></li> </ul> </details> <br /> Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) --- <details> <summary>Dependabot commands and options</summary> <br /> You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot show <dependency name> ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore <dependency name> major version` will close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself) - `@dependabot ignore <dependency name> minor version` will close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself) - `@dependabot ignore <dependency name>` will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself) - `@dependabot unignore <dependency name>` will remove all of the ignore conditions of the specified dependency - `@dependabot unignore <dependency name> <ignore condition>` will remove the ignore condition of the specified dependency and ignore conditions </details> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: CaliBrain <calibrain@l4n.xyz>
📚 Shelfmark: Book Search & Request Tool
Note
Shelfmark is feature stable and maintained on a best-effort basis. Bug fixes, security updates, and small quality-of-life improvements are still shipped, and pull requests are reviewed — including new features. There is no roadmap for new features for now.
Shelfmark is a self-hosted web interface for searching and requesting books and audiobooks across multiple sources. Bring your own sources, metadata providers, and download clients to build a single hub for your digital library. Supports multiple users with a built-in request system, so you can share your instance with others and let them browse and request books on their own.
Works great alongside the following library tools, with support for automatic imports:
✨ Features
- One-Stop Interface - A clean, modern UI to search, browse, and download from multiple configured sources in one place
- Multiple Sources - Configurable web, torrent, usenet, IRC, and Soulseek (slskd) source support
- Audiobook Support - Full audiobook search and download with dedicated processing
- Flexible Search - Search metadata providers (Hardcover, Open Library, Google Books) for rich book and audiobook discovery, or query configured sources directly
- Multi-User & Requests - Share your instance with others, let users browse and request books, and manage approvals with configurable notifications
- Authentication - Built-in login, OIDC single sign-on, proxy auth, and Calibre-Web database support
- Real-Time Progress - Unified download queue with live status updates across all sources
- Network Flexibility - Configurable proxy support, DNS settings, and optional Cloudflare handling for protected sources
🖼️ Screenshots
🚀 Quick Start
Prerequisites
- Docker & Docker Compose
- At least 2 GB of RAM available to the container when using the standard image — see Memory Requirements
Installation
-
Download the docker-compose file:
curl -O https://raw.githubusercontent.com/calibrain/shelfmark/main/compose/docker-compose.yml -
Start the service:
docker compose up -d -
Open
http://localhost:8084
Open the web interface, then configure the sources and settings you want to use.
Volume Setup
volumes:
- /your/config/path:/config # Config, database, and artwork cache directory
- /your/download/path:/books # Downloaded books
- /client/path:/client/path # Optional: For Torrent/Usenet downloads, match your client directory exactly.
Tip
: Point the download volume to your CWA or Grimmory ingest folder for automatic import.
Note
: CIFS shares require
nobrlmount option to avoid database lock errors.
Non-root container mode
- Start the container as
1000:1000with Dockeruser: "1000:1000"ordocker run --user 1000:1000. - For Kubernetes, set
runAsUser: 1000,runAsGroup: 1000, andrunAsNonRoot: truetogether. PUID/PGIDkeep the default root startup flow.- Mounted paths must already be writable by
1000:1000. USING_TOR=truerequires root startup.
⚙️ Configuration
Search Modes
Direct
- Queries configured sources directly
Universal (recommended)
- Search via metadata providers (Hardcover, Open Library, Google Books) for richer results
- Aggregates releases from multiple configured sources
- Full audiobook support
Hardcover API Key
Hardcover powers metadata search in Universal mode. Create a token at
hardcover.app/account/api — current keys start with hc_pat_
and are far shorter than the JWTs Hardcover issued before August 2026.
Tick these seven scopes on the token screen:
| Scope | Used for |
|---|---|
read:catalog |
Metadata search, plus book, edition, author and series lookups |
read:library |
Your reading status and shelf counts |
read:lists |
Your lists and the books on them |
read:me:content |
Test Connection and the "Connected as" label |
read:users |
Usernames shown alongside lists |
write:library |
Setting a book's reading status from Shelfmark |
write:lists |
Adding and removing books from lists, including auto-remove on download |
The two write: scopes matter only if you set reading status from Shelfmark or leave
Auto-Remove from List on Download enabled (it is on by default) — without them those actions
fail silently. Everything else Hardcover offers (journal, goals, reviews, prompts, notifications,
account) can stay unticked. The all scope works too, but it grants full account access including
deletion, so prefer the list above.
Environment Variables
Environment variables work for initial setup and Docker deployments. They serve as defaults that can be overridden in the web interface.
| Variable | Description | Default |
|---|---|---|
FLASK_PORT |
Web interface port | 8084 |
INGEST_DIR |
Book download directory | /books |
TZ |
Container timezone | UTC |
PUID / PGID |
Runtime user/group for the default root-startup flow (also supports legacy UID/GID) |
1000 / 1000 |
SEARCH_MODE |
direct or universal |
universal |
USING_TOR |
Enable Tor routing (requires root startup) | false |
USING_WIREGUARD |
Enable WireGuard VPN egress with kill-switch (requires root startup) | false |
WIREGUARD_CONFIG |
Path to the mounted wg-quick config | /config/wg0.conf |
WIREGUARD_INTERFACE |
WireGuard interface name | wg0 |
LAN_NETWORK |
Comma-separated CIDRs kept off the tunnel so the WebUI / internal clients stay reachable | 127.0.0.0/8,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16 |
WIREGUARD_ENFORCE_DNS |
Pin the resolver (via WIREGUARD_DNS, else the config's DNS =) so DNS can't silently fall back to an off-tunnel path. Designed for a trusted LAN resolver kept reachable via LAN_NETWORK (query leaves over the LAN; download still egresses via the tunnel) — it does not force queries through the tunnel. Docker's embedded resolver (127.0.0.11) is preserved when present so container-name resolution keeps working; pin its upstream via the container's dns: list. Fails closed if no resolver is available or /etc/resolv.conf is not writable. |
true |
WIREGUARD_DNS |
Explicit resolver(s) to pin (comma/space separated). Use when the VPN's pushed DNS filters domains you need; point at a resolver reachable via the tunnel or an allowed LAN resolver. | (unset; uses config DNS =) |
WIREGUARD_DISABLE_IPV6 |
Strip IPv6 from the tunnel config (many container kernels lack the ip6tables raw table wg-quick needs) and remove IPv6 as a leak surface. |
true |
WIREGUARD_ALLOW_IPV6_LEAK |
Escape hatch: continue even when an IPv6 kill-switch can't be installed AND IPv6 can't be disabled. Only set if the container has no IPv6 connectivity. | false |
WIREGUARD_ALLOW_WEBUI_OFFTUNNEL |
Opt-in off-tunnel WebUI reachability. Default (false) keeps the kill-switch strictly fail-closed: the only off-tunnel egress is loopback, the tunnel device and the LAN allowlist. Set true only if a non-LAN client (e.g. a public reverse proxy on another segment) must reach the WebUI; it permits app-server replies (--sport FLASK_PORT, conntrack REPLY) off-tunnel — server replies only, never client-initiated egress. LAN clients never need it (covered by LAN_NETWORK). |
false |
WIREGUARD_STALE_AFTER |
Seconds since the last handshake before the healthcheck bounces the tunnel. | 180 |
See the full Environment Variables Reference for all available options.
Some of the additional options available in Settings:
- Prowlarr - Configure indexers and download clients to download books and audiobooks
- Additional audiobook sources - Configure additional sources for audiobook discovery
- Direct Download mirrors - Supply your own Anna's Archive mirror URLs; Auto mode tries them in the order listed. The
annas-archive.isdomain does not currently work as a source — useannas-archive.glinstead (checked August 2026; mirror availability changes) - IRC - Add details for IRC book sources and download directly from the UI. Most networks serve audiobooks from the same channel as ebooks (on
irc.irchighway.netthat's#ebooks, while#bookzis effectively inactive), so leave the separate audiobook channel blank unless your network actually indexes one. IRC audiobooks usually arrive as ZIP/RAR archives — keep those enabled under Supported Audiobook Formats or the releases are filtered out of results - Soulseek (slskd) - Search the Soulseek network and download through a slskd instance. Point Shelfmark at slskd's URL with an API key (
web.authentication.api_keysinslskd.yml, rolereadwrite), and mount slskd's downloads folder into the Shelfmark container. If the folder sits at a different path inside Shelfmark, set Downloads Path in the slskd settings or add a Remote Path Mapping for clientslskd. Ebook results are single files; audiobook results group a peer's folder of audio files into one release - Library Link - Add a link to your Calibre-Web or Grimmory instance in the UI header
- File processing - Customiseable download paths, file renaming and directory creation with template-based renaming
- Network Settings - Custom proxy support (SOCKS5 + HTTP/S) and configurable DNS
- Format & Language - Filter downloads by preferred formats, languages and sorting order
- Metadata Providers - Configure API keys for Hardcover, Open Library, etc.
🐳 Docker Variants
Standard
docker compose up -d
The full-featured image with all network capabilities included.
Memory Requirements
The standard image ships a real Chromium browser, which it launches to solve Cloudflare challenges for Direct Download. Chromium needs room to run:
- 2 GB of RAM available to the container is a safe minimum; 1 GB or less is where problems usually start
- Only relevant if you use Direct Download. Prowlarr, IRC and audiobook sources don't start the browser
When the container is starved of memory, Chromium fails to start and every Direct Download fails with unrelated-looking errors — repeated 403 detected; switching to bypasser followed by No download URL found, and downloads that never complete. If you're seeing that, check the container's memory limit and the host's free memory before suspecting your ISP or DNS.
If you can't spare the memory, use the Lite image with an external resolver (e.g. FlareSolverr) running elsewhere.
Tor Routing
Optional Tor support for network privacy:
curl -O https://raw.githubusercontent.com/calibrain/shelfmark/main/compose/docker-compose.tor.yml
docker compose -f docker-compose.tor.yml up -d
Notes:
- Requires root startup
- Requires
NET_ADMINandNET_RAWcapabilities - Timezone is auto-detected from Tor exit node
- Custom DNS/proxy settings are ignored when Tor is active
WireGuard VPN Routing
Optional WireGuard support to route all external egress through a VPN tunnel with a fail-closed kill-switch:
curl -O https://raw.githubusercontent.com/calibrain/shelfmark/main/compose/docker-compose.wireguard.yml
# place your wg-quick config where the compose mounts /config, as wg0.conf
docker compose -f docker-compose.wireguard.yml up -d
Notes:
- Requires root startup
- Requires
NET_ADMINandNET_RAWcapabilities - Mount a standard wg-quick config at
WIREGUARD_CONFIG(default/config/wg0.conf) - All non-LAN egress is forced through the tunnel; if the tunnel drops, external traffic fails closed while LAN ranges (WebUI, Prowlarr, qBittorrent) stay reachable
- IPv4 and IPv6 both fail closed. On kernels without a usable
ip6tables, disable IPv6 for the container (sysctls: net.ipv6.conf.all.disable_ipv6=1, as in the compose example) or the container refuses to start rather than risk an IPv6 leak - A supervised healthcheck bounces the tunnel if the handshake goes stale, and refreshes the endpoint allow rules so a roaming/rotated peer endpoint can reconnect
- Mutually exclusive with
USING_TOR - DNS trust:
WIREGUARD_DNSmust be a resolver you trust on a trusted network segment. When it is a LAN resolver (kept reachable off-tunnel byLAN_NETWORK), the query to that resolver leaves as plaintext UDP/53 on the LAN — the resolver is responsible for encrypting upstream. Two resolver paths exist: (1) when Docker's embedded resolver (127.0.0.11) is present it is preserved so container names (Prowlarr, qBittorrent) resolve — you MUST pin its upstream to a trusted resolver via the container's composedns:list, sinceWIREGUARD_DNScannot repoint the embedded resolver from inside the container; (2) otherwiseWIREGUARD_DNS/the configDNS =line is written to/etc/resolv.conf. SettingWIREGUARD_ENFORCE_DNS=falseis a foot-gun: with no embedded resolver present the container then uses its inherited resolver, which forwards to the Docker daemon's upstream off-tunnel, leaking your DNS. Leave enforcement on unless you have pinned the resolver another way.
Lite
A lighter image without the built-in browser automation. Ideal for:
- External services - Already running FlareSolverr or similar for other applications
- Alternative sources - Using Prowlarr, IRC, or other configured sources
- Audiobooks - Using Shelfmark primarily for audiobooks
- Constrained hosts - No bundled browser, so it runs comfortably below the standard image's memory requirements
curl -O https://raw.githubusercontent.com/calibrain/shelfmark/main/compose/docker-compose.lite.yml
docker compose -f docker-compose.lite.yml up -d
If you need browser-based access with the Lite image, configure an external resolver in Settings.
🔐 Authentication
Authentication is optional but recommended for shared or exposed instances. Multiple authentication methods are available in Settings:
1. Single Username/Password
2. Proxy (Forward) Authentication
Proxy auth trusts headers set by your reverse proxy (e.g. X-Auth-User). Ensure Shelfmark is not directly exposed, and configure your proxy to strip/overwrite these headers for all inbound requests.
3. OIDC (OpenID Connect)
Integrate with your identity provider (Authelia, Authentik, Keycloak, etc.) for single sign-on. Supports PKCE flow, auto-discovery, group-based admin mapping, and auto-provisioning of new users.
4. Calibre-Web Database
If you're running Calibre-Web, you can reuse its user database by mounting it:
volumes:
- /path/to/calibre-web/app.db:/auth/app.db:ro
Multi-User Support
With any authentication method enabled, Shelfmark supports multi-user management with admin/user roles. Users can have per-user settings for download destinations, email recipients, and notification preferences. Non-admin users only see their own downloads and can submit book requests for admin review. Admins can configure request policies per source to control whether users can download directly, must submit a request, or are blocked entirely.
See API Access to call the API with a static key from scripts and integrations.
Project Scope
Shelfmark is a manual search and download tool, the entry point to your book library, not a library manager. It finds books, downloads them, and sends them to a configured destination. That's the full scope.
Shelfmark intentionally does not:
- Track or manage your library - it doesn't know or care what you already own
- Integrate with library software - what happens after delivery is up to your library tool
- Monitor authors, series, or new releases - there is no background automation
- Queue future downloads - if a book isn't available now, Shelfmark won't watch for it
These are non-goals, not missing features.
Contributing
Shelfmark's core feature set is complete.
Pull requests are welcome and all of them get reviewed, new features included. If you want a feature, the fastest path is to send a PR for it rather than to file a request.
Feature requests that fall outside the project scope (library integration, automation, collection management) will be closed, and PRs implementing them won't be merged. If you're unsure whether something fits, open a discussion first.
Health Monitoring
The application exposes a health endpoint at /api/health (no authentication required). Add a health check to your compose:
healthcheck:
test: ["CMD", "curl", "-sf", "http://localhost:8084/api/health"]
interval: 30s
timeout: 30s
retries: 3
Logging
Logs are available via:
docker logs <container-name>/var/log/shelfmark/inside the container (whenENABLE_LOGGING=true)
Log level is configurable under Settings → Advanced or via the LOG_LEVEL environment
variable (DEBUG, INFO, WARNING, ERROR, CRITICAL; case-insensitive, defaults to
INFO). The environment variable wins over the setting, and DEBUG=true forces DEBUG
regardless of either. Changes take effect on restart.
Development
# Quality checks
make checks # Run ALL static analysis (frontend + Python)
make python-checks # Run Ruff, BasedPyright, and Vulture
make install-python-dev # Sync Python runtime + dev tools with uv
# Frontend development
make install # Install dependencies
make dev # Start Vite dev server (localhost:5173)
make build # Production build
make frontend-typecheck # TypeScript checks
# Backend (Docker)
make up # Start backend via docker-compose.dev.yml
make down # Stop services
make refresh # Rebuild and restart
make restart # Restart container
The frontend dev server proxies to the backend on port 8084.
License
MIT License - see LICENSE for details.
⚠️ Disclaimer
Shelfmark is a search interface that displays results from external metadata providers and sources. It does not host, store, or distribute any content. The developers are not responsible for how the tool is used or what is accessed through it.
Users are solely responsible for:
- Ensuring they have the legal right to download any material they access
- Complying with copyright laws and intellectual property rights in their jurisdiction
- Understanding and accepting the terms of any sources they configure
Use of this tool is entirely at your own risk.
Support
For issues or questions, please file an issue on GitHub.



