From ec7e3482bb0564fa044a1338eb04caa8e75347b3 Mon Sep 17 00:00:00 2001 From: Hrachya Shaginyan Date: Sun, 21 Jun 2026 05:59:56 +0200 Subject: [PATCH] use a stable hash for the Booklore options cache key (#1079) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `_get_booklore_cache_key` returned `f"{base_url}|{username}|{hash(password)}"`. Python's built-in `hash()` is randomized per process (`PYTHONHASHSEED`), so the cache key for the same Booklore credentials changed between every worker process and every restart. If the dashboard was opened by a worker that landed on a different seed than the worker that warmed the cache, the `_BOOKLORE_OPTIONS_CACHE.get("key") == cache_key` check would miss on every lookup, forcing a fresh `booklore_login` API call each time. Switch to `hashlib.sha256(password.encode()).hexdigest()` — deterministic across processes and restarts. SHA-256 is overkill for a cache key, but matching the existing convention (`hashlib.sha1` is used elsewhere in the codebase) is what we want here. The password is already in memory (it comes from the request body / `config.get`), so this doesn't introduce a new secret-handling concern. Co-authored-by: Zo Bot --- shelfmark/config/booklore_settings.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/shelfmark/config/booklore_settings.py b/shelfmark/config/booklore_settings.py index 0f979f1..0bcd60f 100644 --- a/shelfmark/config/booklore_settings.py +++ b/shelfmark/config/booklore_settings.py @@ -3,6 +3,7 @@ from __future__ import annotations from typing import Any +import hashlib from shelfmark.core.config import config from shelfmark.core.logger import setup_logger @@ -23,7 +24,7 @@ _BOOKLORE_OPTIONS_CACHE: dict[str, Any] = { def _get_booklore_cache_key(base_url: str, username: str, password: str) -> str: - return f"{base_url}|{username}|{hash(password)}" + return f"{base_url}|{username}|{hashlib.sha256(password.encode()).hexdigest()}" def _get_booklore_select_options(