Files
searxng/_modules/searx/cache.html
T
2026-05-07 14:21:13 +00:00

1002 lines
107 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!doctype html>
<html class="no-js" lang="en" data-content_root="../../">
<head><meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<meta name="color-scheme" content="light dark"><link rel="index" title="Index" href="../../genindex.html"><link rel="search" title="Search" href="../../search.html">
<link rel="prefetch" href="../../_static/searxng-wordmark.svg" as="image">
<!-- Generated with Sphinx 9.1.0 and Furo 2025.12.19 -->
<title>searx.cache - SearXNG Documentation (2026.5.7+ef6290c8c)</title>
<link rel="stylesheet" type="text/css" href="../../_static/pygments.css?v=d111a655" />
<link rel="stylesheet" type="text/css" href="../../_static/styles/furo.css?v=7bdb33bb" />
<link rel="stylesheet" type="text/css" href="../../_static/styles/furo-extensions.css?v=8dab3a3b" />
<link rel="stylesheet" type="text/css" href="../../_static/searxng.css?v=4b1b1f10" />
<style>
body {
--color-code-background: #f2f2f2;
--color-code-foreground: #1e1e1e;
}
@media not print {
body[data-theme="dark"] {
--color-code-background: #202020;
--color-code-foreground: #d0d0d0;
}
@media (prefers-color-scheme: dark) {
body:not([data-theme="light"]) {
--color-code-background: #202020;
--color-code-foreground: #d0d0d0;
}
}
}
</style></head>
<body>
<script>
document.body.dataset.theme = localStorage.getItem("theme") || "auto";
</script>
<svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
<symbol id="svg-toc" viewBox="0 0 24 24">
<title>Contents</title>
<svg stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 1024 1024">
<path d="M408 442h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8zm-8 204c0 4.4 3.6 8 8 8h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56zm504-486H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zm0 632H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zM115.4 518.9L271.7 642c5.8 4.6 14.4.5 14.4-6.9V388.9c0-7.4-8.5-11.5-14.4-6.9L115.4 505.1a8.74 8.74 0 0 0 0 13.8z"/>
</svg>
</symbol>
<symbol id="svg-menu" viewBox="0 0 24 24">
<title>Menu</title>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor"
stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather-menu">
<line x1="3" y1="12" x2="21" y2="12"></line>
<line x1="3" y1="6" x2="21" y2="6"></line>
<line x1="3" y1="18" x2="21" y2="18"></line>
</svg>
</symbol>
<symbol id="svg-arrow-right" viewBox="0 0 24 24">
<title>Expand</title>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor"
stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather-chevron-right">
<polyline points="9 18 15 12 9 6"></polyline>
</svg>
</symbol>
<symbol id="svg-sun" viewBox="0 0 24 24">
<title>Light mode</title>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor"
stroke-width="1" stroke-linecap="round" stroke-linejoin="round" class="feather-sun">
<circle cx="12" cy="12" r="5"></circle>
<line x1="12" y1="1" x2="12" y2="3"></line>
<line x1="12" y1="21" x2="12" y2="23"></line>
<line x1="4.22" y1="4.22" x2="5.64" y2="5.64"></line>
<line x1="18.36" y1="18.36" x2="19.78" y2="19.78"></line>
<line x1="1" y1="12" x2="3" y2="12"></line>
<line x1="21" y1="12" x2="23" y2="12"></line>
<line x1="4.22" y1="19.78" x2="5.64" y2="18.36"></line>
<line x1="18.36" y1="5.64" x2="19.78" y2="4.22"></line>
</svg>
</symbol>
<symbol id="svg-moon" viewBox="0 0 24 24">
<title>Dark mode</title>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor"
stroke-width="1" stroke-linecap="round" stroke-linejoin="round" class="icon-tabler-moon">
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
<path d="M12 3c.132 0 .263 0 .393 0a7.5 7.5 0 0 0 7.92 12.446a9 9 0 1 1 -8.313 -12.454z" />
</svg>
</symbol>
<symbol id="svg-sun-with-moon" viewBox="0 0 24 24">
<title>Auto light/dark, in light mode</title>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor"
stroke-width="1" stroke-linecap="round" stroke-linejoin="round"
class="icon-custom-derived-from-feather-sun-and-tabler-moon">
<path style="opacity: 50%" d="M 5.411 14.504 C 5.471 14.504 5.532 14.504 5.591 14.504 C 3.639 16.319 4.383 19.569 6.931 20.352 C 7.693 20.586 8.512 20.551 9.25 20.252 C 8.023 23.207 4.056 23.725 2.11 21.184 C 0.166 18.642 1.702 14.949 4.874 14.536 C 5.051 14.512 5.231 14.5 5.411 14.5 L 5.411 14.504 Z"/>
<line x1="14.5" y1="3.25" x2="14.5" y2="1.25"/>
<line x1="14.5" y1="15.85" x2="14.5" y2="17.85"/>
<line x1="10.044" y1="5.094" x2="8.63" y2="3.68"/>
<line x1="19" y1="14.05" x2="20.414" y2="15.464"/>
<line x1="8.2" y1="9.55" x2="6.2" y2="9.55"/>
<line x1="20.8" y1="9.55" x2="22.8" y2="9.55"/>
<line x1="10.044" y1="14.006" x2="8.63" y2="15.42"/>
<line x1="19" y1="5.05" x2="20.414" y2="3.636"/>
<circle cx="14.5" cy="9.55" r="3.6"/>
</svg>
</symbol>
<symbol id="svg-moon-with-sun" viewBox="0 0 24 24">
<title>Auto light/dark, in dark mode</title>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor"
stroke-width="1" stroke-linecap="round" stroke-linejoin="round"
class="icon-custom-derived-from-feather-sun-and-tabler-moon">
<path d="M 8.282 7.007 C 8.385 7.007 8.494 7.007 8.595 7.007 C 5.18 10.184 6.481 15.869 10.942 17.24 C 12.275 17.648 13.706 17.589 15 17.066 C 12.851 22.236 5.91 23.143 2.505 18.696 C -0.897 14.249 1.791 7.786 7.342 7.063 C 7.652 7.021 7.965 7 8.282 7 L 8.282 7.007 Z"/>
<line style="opacity: 50%" x1="18" y1="3.705" x2="18" y2="2.5"/>
<line style="opacity: 50%" x1="18" y1="11.295" x2="18" y2="12.5"/>
<line style="opacity: 50%" x1="15.316" y1="4.816" x2="14.464" y2="3.964"/>
<line style="opacity: 50%" x1="20.711" y1="10.212" x2="21.563" y2="11.063"/>
<line style="opacity: 50%" x1="14.205" y1="7.5" x2="13.001" y2="7.5"/>
<line style="opacity: 50%" x1="21.795" y1="7.5" x2="23" y2="7.5"/>
<line style="opacity: 50%" x1="15.316" y1="10.184" x2="14.464" y2="11.036"/>
<line style="opacity: 50%" x1="20.711" y1="4.789" x2="21.563" y2="3.937"/>
<circle style="opacity: 50%" cx="18" cy="7.5" r="2.169"/>
</svg>
</symbol>
<symbol id="svg-pencil" viewBox="0 0 24 24">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor"
stroke-width="1" stroke-linecap="round" stroke-linejoin="round" class="icon-tabler-pencil-code">
<path d="M4 20h4l10.5 -10.5a2.828 2.828 0 1 0 -4 -4l-10.5 10.5v4" />
<path d="M13.5 6.5l4 4" />
<path d="M20 21l2 -2l-2 -2" />
<path d="M17 17l-2 2l2 2" />
</svg>
</symbol>
<symbol id="svg-eye" viewBox="0 0 24 24">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor"
stroke-width="1" stroke-linecap="round" stroke-linejoin="round" class="icon-tabler-eye-code">
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
<path d="M10 12a2 2 0 1 0 4 0a2 2 0 0 0 -4 0" />
<path
d="M11.11 17.958c-3.209 -.307 -5.91 -2.293 -8.11 -5.958c2.4 -4 5.4 -6 9 -6c3.6 0 6.6 2 9 6c-.21 .352 -.427 .688 -.647 1.008" />
<path d="M20 21l2 -2l-2 -2" />
<path d="M17 17l-2 2l2 2" />
</svg>
</symbol>
</svg>
<input type="checkbox" class="sidebar-toggle" name="__navigation" id="__navigation" aria-label="Toggle site navigation sidebar">
<input type="checkbox" class="sidebar-toggle" name="__toc" id="__toc" aria-label="Toggle table of contents sidebar">
<label class="overlay sidebar-overlay" for="__navigation"></label>
<label class="overlay toc-overlay" for="__toc"></label>
<a class="skip-to-content muted-link" href="#furo-main-content">Skip to content</a>
<div class="page">
<header class="mobile-header">
<div class="header-left">
<label class="nav-overlay-icon" for="__navigation">
<span class="icon"><svg><use href="#svg-menu"></use></svg></span>
</label>
</div>
<div class="header-center">
<a href="../../index.html"><div class="brand">SearXNG Documentation (2026.5.7+ef6290c8c)</div></a>
</div>
<div class="header-right">
<div class="theme-toggle-container theme-toggle-header">
<button class="theme-toggle" aria-label="Toggle Light / Dark / Auto color theme">
<svg class="theme-icon-when-auto-light"><use href="#svg-sun-with-moon"></use></svg>
<svg class="theme-icon-when-auto-dark"><use href="#svg-moon-with-sun"></use></svg>
<svg class="theme-icon-when-dark"><use href="#svg-moon"></use></svg>
<svg class="theme-icon-when-light"><use href="#svg-sun"></use></svg>
</button>
</div>
<label class="toc-overlay-icon toc-header-icon no-toc" for="__toc">
<span class="icon"><svg><use href="#svg-toc"></use></svg></span>
</label>
</div>
</header>
<aside class="sidebar-drawer">
<div class="sidebar-container">
<div class="sidebar-sticky"><div class="sidebar-scroll"><a class="sidebar-brand" href="../../index.html">
<div class="sidebar-logo-container">
<img class="sidebar-logo" src="../../_static/searxng-wordmark.svg" alt="Logo"/>
</div>
<span class="sidebar-brand-text">SearXNG Documentation (2026.5.7+ef6290c8c)</span>
</a><form class="sidebar-search-container" method="get" action="../../search.html" role="search">
<input class="sidebar-search" placeholder="Search" name="q" aria-label="Search">
<input type="hidden" name="check_keywords" value="yes">
<input type="hidden" name="area" value="default">
</form>
<div id="searchbox"></div><div class="sidebar-tree">
<ul>
<li class="toctree-l1 has-children"><a class="reference internal" href="../../user/index.html">User information</a><input aria-label="Toggle navigation of User information" class="toctree-checkbox" id="toctree-checkbox-1" name="toctree-checkbox-1" role="switch" type="checkbox"/><label for="toctree-checkbox-1"><span class="icon"><svg><use href="#svg-arrow-right"></use></svg></span></label><ul>
<li class="toctree-l2"><a class="reference internal" href="../../user/search-syntax.html">Search syntax</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../user/configured_engines.html">Configured Engines</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../user/about.html">About SearXNG</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="../../own-instance.html">Why use a private instance?</a></li>
<li class="toctree-l1 has-children"><a class="reference internal" href="../../admin/index.html">Administrator documentation</a><input aria-label="Toggle navigation of Administrator documentation" class="toctree-checkbox" id="toctree-checkbox-2" name="toctree-checkbox-2" role="switch" type="checkbox"/><label for="toctree-checkbox-2"><span class="icon"><svg><use href="#svg-arrow-right"></use></svg></span></label><ul>
<li class="toctree-l2 has-children"><a class="reference internal" href="../../admin/settings/index.html">Settings</a><input aria-label="Toggle navigation of Settings" class="toctree-checkbox" id="toctree-checkbox-3" name="toctree-checkbox-3" role="switch" type="checkbox"/><label for="toctree-checkbox-3"><span class="icon"><svg><use href="#svg-arrow-right"></use></svg></span></label><ul>
<li class="toctree-l3"><a class="reference internal" href="../../admin/settings/settings.html"><code class="docutils literal notranslate"><span class="pre">settings.yml</span></code></a></li>
<li class="toctree-l3"><a class="reference internal" href="../../admin/settings/settings_engines.html"><code class="docutils literal notranslate"><span class="pre">engines:</span></code></a></li>
<li class="toctree-l3"><a class="reference internal" href="../../admin/settings/settings_brand.html"><code class="docutils literal notranslate"><span class="pre">brand:</span></code></a></li>
<li class="toctree-l3"><a class="reference internal" href="../../admin/settings/settings_general.html"><code class="docutils literal notranslate"><span class="pre">general:</span></code></a></li>
<li class="toctree-l3"><a class="reference internal" href="../../admin/settings/settings_search.html"><code class="docutils literal notranslate"><span class="pre">search:</span></code></a></li>
<li class="toctree-l3"><a class="reference internal" href="../../admin/settings/settings_server.html"><code class="docutils literal notranslate"><span class="pre">server:</span></code></a></li>
<li class="toctree-l3"><a class="reference internal" href="../../admin/settings/settings_ui.html"><code class="docutils literal notranslate"><span class="pre">ui:</span></code></a></li>
<li class="toctree-l3"><a class="reference internal" href="../../admin/settings/settings_redis.html"><code class="docutils literal notranslate"><span class="pre">redis:</span></code></a></li>
<li class="toctree-l3"><a class="reference internal" href="../../admin/settings/settings_valkey.html"><code class="docutils literal notranslate"><span class="pre">valkey:</span></code></a></li>
<li class="toctree-l3"><a class="reference internal" href="../../admin/settings/settings_outgoing.html"><code class="docutils literal notranslate"><span class="pre">outgoing:</span></code></a></li>
<li class="toctree-l3"><a class="reference internal" href="../../admin/settings/settings_categories_as_tabs.html"><code class="docutils literal notranslate"><span class="pre">categories_as_tabs:</span></code></a></li>
<li class="toctree-l3"><a class="reference internal" href="../../admin/settings/settings_plugins.html"><code class="docutils literal notranslate"><span class="pre">plugins:</span></code></a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="../../admin/installation.html">Installation</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../admin/installation-docker.html">Installation container</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../admin/installation-scripts.html">Installation Script</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../admin/installation-searxng.html">Step by step installation</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../admin/installation-granian.html">Granian</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../admin/installation-uwsgi.html">uWSGI</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../admin/installation-nginx.html">NGINX</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../admin/installation-apache.html">Apache</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../admin/update-searxng.html">SearXNG maintenance</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../admin/answer-captcha.html">Answer CAPTCHA from servers IP</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../admin/searx.favicons.html">Favicons</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../admin/searx.limiter.html">Limiter</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../admin/api.html">Administration API</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../admin/architecture.html">Architecture</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../admin/plugins.html">List of plugins</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../admin/buildhosts.html">Buildhosts</a></li>
</ul>
</li>
<li class="toctree-l1 has-children"><a class="reference internal" href="../../dev/index.html">Developer documentation</a><input aria-label="Toggle navigation of Developer documentation" class="toctree-checkbox" id="toctree-checkbox-4" name="toctree-checkbox-4" role="switch" type="checkbox"/><label for="toctree-checkbox-4"><span class="icon"><svg><use href="#svg-arrow-right"></use></svg></span></label><ul>
<li class="toctree-l2"><a class="reference internal" href="../../dev/quickstart.html">Development Quickstart</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../dev/commits.html">Git Commits &amp; Change Management</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../dev/contribution_guide.html">How to contribute</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../dev/extended_types.html">Extended Types</a></li>
<li class="toctree-l2 has-children"><a class="reference internal" href="../../dev/engines/index.html">Engine Implementations</a><input aria-label="Toggle navigation of Engine Implementations" class="toctree-checkbox" id="toctree-checkbox-5" name="toctree-checkbox-5" role="switch" type="checkbox"/><label for="toctree-checkbox-5"><span class="icon"><svg><use href="#svg-arrow-right"></use></svg></span></label><ul>
<li class="toctree-l3"><a class="reference internal" href="../../dev/engines/enginelib.html">Engine Library</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../dev/engines/engines.html">SearXNGs engines loader</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../dev/engines/engine_overview.html">Engine Overview</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../dev/engines/demo/demo_online.html">Demo Online Engine</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../dev/engines/xpath.html">XPath Engine</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../dev/engines/mediawiki.html">MediaWiki Engine</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../dev/engines/json_engine.html">JSON Engine</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../dev/engines/online/adobe_stock.html">Adobe Stock</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../dev/engines/online/alpinelinux.html">Alpine Linux Packages</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../dev/engines/online/annas_archive.html">Annas Archive</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../dev/engines/online/aol.html">AOL</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../dev/engines/online/archlinux.html">Arch Linux</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../dev/engines/online/arxiv.html">arXiv</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../dev/engines/online/astrophysics_data_system.html">Astrophysics Data System (ADS)</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../dev/engines/online/azure.html">Azure Resources</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../dev/engines/online/bing.html">Bing Engines</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../dev/engines/online/bpb.html">Bpb</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../dev/engines/online/brave.html">Brave Engines</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../dev/engines/online/bt4g.html">BT4G</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../dev/engines/online/chinaso.html">ChinaSo</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../dev/engines/online/core.html">CORE</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../dev/engines/online/crossref.html">Crossref</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../dev/engines/online/dailymotion.html">Dailymotion</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../dev/engines/online/discourse.html">Discourse Forums</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../dev/engines/online/duckduckgo.html">DuckDuckGo Engines</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../dev/engines/online/geizhals.html">Geizhals</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../dev/engines/online/gitea.html">Gitea</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../dev/engines/online/github_code.html">Github Code</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../dev/engines/online/gitlab.html">GitLab</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../dev/engines/online/google.html">Google Engines</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../dev/engines/online/huggingface.html">Hugging Face</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../dev/engines/online/karmasearch.html">Karmasearch</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../dev/engines/online/lemmy.html">Lemmy</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../dev/engines/online/loc.html">Library of Congress</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../dev/engines/online/marginalia.html">Marginalia Search</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../dev/engines/online/mastodon.html">Mastodon</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../dev/engines/online/moviepilot.html">Moviepilot</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../dev/engines/online/mrs.html">Matrix Rooms Search (MRS)</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../dev/engines/online/mwmbl.html">Mwmbl Engine</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../dev/engines/online/odysee.html">Odysee</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../dev/engines/online/openalex.html">OpenAlex</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../dev/engines/online/openlibrary.html">Open Library</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../dev/engines/online/peertube.html">Peertube Engines</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../dev/engines/online/piped.html">Piped</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../dev/engines/online/presearch.html">Presearch Engine</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../dev/engines/online/pubmed.html">PubMed</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../dev/engines/online/qwant.html">Qwant</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../dev/engines/online/radio_browser.html">RadioBrowser</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../dev/engines/online/recoll.html">Recoll Engine</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../dev/engines/online/repology.html">Repology</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../dev/engines/online/reuters.html">Reuters</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../dev/engines/online/semantic_scholar.html">Semantic Scholar</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../dev/engines/online/soundcloud.html">Soundcloud</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../dev/engines/online/sourcehut.html">Sourcehut</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../dev/engines/online/springer.html">Springer Nature</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../dev/engines/online/startpage.html">Startpage Engines</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../dev/engines/online/tagesschau.html">Tagesschau API</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../dev/engines/online/torznab.html">Torznab WebAPI</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../dev/engines/online/tubearchivist.html">Tube Archivist</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../dev/engines/online/void.html">Void Linux binary packages</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../dev/engines/online/wallhaven.html">Wallhaven</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../dev/engines/online/wikipedia.html">Wikimedia</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../dev/engines/online/yacy.html">Yacy</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../dev/engines/online/yahoo.html">Yahoo Engine</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../dev/engines/online/zlibrary.html">Z-Library</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../dev/engines/offline_concept.html">Offline Concept</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../dev/engines/demo/demo_offline.html">Demo Offline Engine</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../dev/engines/offline/command-line-engines.html">Command Line Engines</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../dev/engines/offline/nosql-engines.html">NoSQL databases</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../dev/engines/offline/search-indexer-engines.html">Local Search APIs</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../dev/engines/offline/sql-engines.html">SQL Engines</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../dev/engines/online_url_search/tineye.html">Tineye</a></li>
</ul>
</li>
<li class="toctree-l2 has-children"><a class="reference internal" href="../../dev/result_types/index.html">Result Types</a><input aria-label="Toggle navigation of Result Types" class="toctree-checkbox" id="toctree-checkbox-6" name="toctree-checkbox-6" role="switch" type="checkbox"/><label for="toctree-checkbox-6"><span class="icon"><svg><use href="#svg-arrow-right"></use></svg></span></label><ul>
<li class="toctree-l3"><a class="reference internal" href="../../dev/result_types/base_result.html">Result</a></li>
<li class="toctree-l3 has-children"><a class="reference internal" href="../../dev/result_types/main_result.html">Main Search Results</a><input aria-label="Toggle navigation of Main Search Results" class="toctree-checkbox" id="toctree-checkbox-7" name="toctree-checkbox-7" role="switch" type="checkbox"/><label for="toctree-checkbox-7"><span class="icon"><svg><use href="#svg-arrow-right"></use></svg></span></label><ul>
<li class="toctree-l4"><a class="reference internal" href="../../dev/result_types/main/mainresult.html"><code class="docutils literal notranslate"><span class="pre">MainResult</span></code></a></li>
<li class="toctree-l4"><a class="reference internal" href="../../dev/result_types/main/keyvalue.html">Key-Value Results</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../dev/result_types/main/code.html">Code Results</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../dev/result_types/main/paper.html">Paper Results</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../dev/result_types/main/file.html">File Results</a></li>
</ul>
</li>
<li class="toctree-l3"><a class="reference internal" href="../../dev/result_types/answer.html">Answer Results</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../dev/result_types/correction.html">Correction Results</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../dev/result_types/suggestion.html">Suggestion Results</a></li>
<li class="toctree-l3"><a class="reference internal" href="../../dev/result_types/infobox.html">Infobox Results</a></li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="../../dev/templates.html">Simple Theme Templates</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../dev/search_api.html">Search API</a></li>
<li class="toctree-l2 has-children"><a class="reference internal" href="../../dev/plugins/index.html">Plugins</a><input aria-label="Toggle navigation of Plugins" class="toctree-checkbox" id="toctree-checkbox-8" name="toctree-checkbox-8" role="switch" type="checkbox"/><label for="toctree-checkbox-8"><span class="icon"><svg><use href="#svg-arrow-right"></use></svg></span></label><ul>
<li class="toctree-l3"><a class="reference internal" href="../../dev/plugins/development.html">Plugin Development</a></li>
<li class="toctree-l3 has-children"><a class="reference internal" href="../../dev/plugins/builtins.html">Built-in Plugins</a><input aria-label="Toggle navigation of Built-in Plugins" class="toctree-checkbox" id="toctree-checkbox-9" name="toctree-checkbox-9" role="switch" type="checkbox"/><label for="toctree-checkbox-9"><span class="icon"><svg><use href="#svg-arrow-right"></use></svg></span></label><ul>
<li class="toctree-l4"><a class="reference internal" href="../../dev/plugins/calculator.html">Calculator</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../dev/plugins/hash_plugin.html">Hash Values</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../dev/plugins/hostnames.html">Hostnames</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../dev/plugins/infinite_scroll.html">Infinite scroll</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../dev/plugins/self_info.html">Self-Info</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../dev/plugins/tor_check.html">Tor check</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../dev/plugins/unit_converter.html">Unit Converter</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../dev/plugins/time_zone.html">Time Zone</a></li>
</ul>
</li>
</ul>
</li>
<li class="toctree-l2 has-children"><a class="reference internal" href="../../dev/answerers/index.html">Answerers</a><input aria-label="Toggle navigation of Answerers" class="toctree-checkbox" id="toctree-checkbox-10" name="toctree-checkbox-10" role="switch" type="checkbox"/><label for="toctree-checkbox-10"><span class="icon"><svg><use href="#svg-arrow-right"></use></svg></span></label><ul>
<li class="toctree-l3"><a class="reference internal" href="../../dev/answerers/development.html">Answerer Development</a></li>
<li class="toctree-l3 has-children"><a class="reference internal" href="../../dev/answerers/builtins.html">Built-in Answerers</a><input aria-label="Toggle navigation of Built-in Answerers" class="toctree-checkbox" id="toctree-checkbox-11" name="toctree-checkbox-11" role="switch" type="checkbox"/><label for="toctree-checkbox-11"><span class="icon"><svg><use href="#svg-arrow-right"></use></svg></span></label><ul>
<li class="toctree-l4"><a class="reference internal" href="../../dev/answerers/random.html">Random</a></li>
<li class="toctree-l4"><a class="reference internal" href="../../dev/answerers/statistics.html">Statistics</a></li>
</ul>
</li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="../../dev/translation.html">Translation</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../dev/makefile.html">Makefile &amp; <code class="docutils literal notranslate"><span class="pre">./manage</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="../../dev/reST.html">reST primer</a></li>
<li class="toctree-l2 has-children"><a class="reference internal" href="../../dev/searxng_extra/index.html">Tooling box <code class="docutils literal notranslate"><span class="pre">searxng_extra</span></code></a><input aria-label="Toggle navigation of Tooling box searxng_extra" class="toctree-checkbox" id="toctree-checkbox-12" name="toctree-checkbox-12" role="switch" type="checkbox"/><label for="toctree-checkbox-12"><span class="icon"><svg><use href="#svg-arrow-right"></use></svg></span></label><ul>
<li class="toctree-l3"><a class="reference internal" href="../../dev/searxng_extra/update.html"><code class="docutils literal notranslate"><span class="pre">searxng_extra/update/</span></code></a></li>
</ul>
</li>
</ul>
</li>
<li class="toctree-l1 has-children"><a class="reference internal" href="../../utils/index.html">DevOps tooling box</a><input aria-label="Toggle navigation of DevOps tooling box" class="toctree-checkbox" id="toctree-checkbox-13" name="toctree-checkbox-13" role="switch" type="checkbox"/><label for="toctree-checkbox-13"><span class="icon"><svg><use href="#svg-arrow-right"></use></svg></span></label><ul>
<li class="toctree-l2"><a class="reference internal" href="../../utils/searxng.sh.html"><code class="docutils literal notranslate"><span class="pre">utils/searxng.sh</span></code></a></li>
</ul>
</li>
<li class="toctree-l1 has-children"><a class="reference internal" href="../../src/index.html">Source-Code</a><input aria-label="Toggle navigation of Source-Code" class="toctree-checkbox" id="toctree-checkbox-14" name="toctree-checkbox-14" role="switch" type="checkbox"/><label for="toctree-checkbox-14"><span class="icon"><svg><use href="#svg-arrow-right"></use></svg></span></label><ul>
<li class="toctree-l2"><a class="reference internal" href="../../src/searx.babel_extract.html">Custom message extractor (i18n)</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../src/searx.botdetection.html">Bot Detection</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../src/searx.cache.html">Caches</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../src/searx.exceptions.html">SearXNG Exceptions</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../src/searx.favicons.html">Favicons (source)</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../src/searx.infopage.html">Online <code class="docutils literal notranslate"><span class="pre">/info</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="../../src/searx.locales.html">Locales</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../src/searx.search.html">Search</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../src/searx.search.processors.html">Search processors</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../src/searx.settings.html">Settings Loader</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../src/searx.sqlitedb.html">SQLite DB</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../src/searx.utils.html">Utility functions for the engines</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../src/searx.valkeydb.html">Valkey DB</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../src/searx.valkeylib.html">Valkey Library</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../src/searx.weather.html">Weather</a></li>
</ul>
</li>
</ul>
</div>
</div>
</div>
</div>
</aside>
<div class="main">
<div class="content">
<div class="article-container">
<a href="#" class="back-to-top muted-link">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<path d="M13 20h-2V8l-5.5 5.5-1.42-1.42L12 4.16l7.92 7.92-1.42 1.42L13 8v12z"></path>
</svg>
<span>Back to top</span>
</a>
<div class="content-icon-container">
<div class="theme-toggle-container theme-toggle-content">
<button class="theme-toggle" aria-label="Toggle Light / Dark / Auto color theme">
<svg class="theme-icon-when-auto-light"><use href="#svg-sun-with-moon"></use></svg>
<svg class="theme-icon-when-auto-dark"><use href="#svg-moon-with-sun"></use></svg>
<svg class="theme-icon-when-dark"><use href="#svg-moon"></use></svg>
<svg class="theme-icon-when-light"><use href="#svg-sun"></use></svg>
</button>
</div>
<label class="toc-overlay-icon toc-content-icon no-toc" for="__toc">
<span class="icon"><svg><use href="#svg-toc"></use></svg></span>
</label>
</div>
<article role="main" id="furo-main-content">
<h1>Source code for searx.cache</h1><div class="highlight"><pre>
<span></span><span class="sd">&quot;&quot;&quot;Implementation of caching solutions.</span>
<span class="sd">- :py:obj:`searx.cache.ExpireCache` and its :py:obj:`searx.cache.ExpireCacheCfg`</span>
<span class="sd">----</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="n">__all__</span> <span class="o">=</span> <span class="p">[</span><span class="s2">&quot;ExpireCacheCfg&quot;</span><span class="p">,</span> <span class="s2">&quot;ExpireCacheStats&quot;</span><span class="p">,</span> <span class="s2">&quot;ExpireCache&quot;</span><span class="p">,</span> <span class="s2">&quot;ExpireCacheSQLite&quot;</span><span class="p">]</span>
<span class="kn">import</span><span class="w"> </span><span class="nn">abc</span>
<span class="kn">from</span><span class="w"> </span><span class="nn">collections.abc</span><span class="w"> </span><span class="kn">import</span> <span class="n">Iterator</span>
<span class="kn">import</span><span class="w"> </span><span class="nn">dataclasses</span>
<span class="kn">import</span><span class="w"> </span><span class="nn">datetime</span>
<span class="kn">import</span><span class="w"> </span><span class="nn">hashlib</span>
<span class="kn">import</span><span class="w"> </span><span class="nn">hmac</span>
<span class="kn">import</span><span class="w"> </span><span class="nn">os</span>
<span class="kn">import</span><span class="w"> </span><span class="nn">pickle</span>
<span class="kn">import</span><span class="w"> </span><span class="nn">sqlite3</span>
<span class="kn">import</span><span class="w"> </span><span class="nn">string</span>
<span class="kn">import</span><span class="w"> </span><span class="nn">tempfile</span>
<span class="kn">import</span><span class="w"> </span><span class="nn">time</span>
<span class="kn">import</span><span class="w"> </span><span class="nn">typing</span>
<span class="kn">import</span><span class="w"> </span><span class="nn">msgspec</span>
<span class="kn">from</span><span class="w"> </span><span class="nn">searx</span><span class="w"> </span><span class="kn">import</span> <span class="n">sqlitedb</span>
<span class="kn">from</span><span class="w"> </span><span class="nn">searx</span><span class="w"> </span><span class="kn">import</span> <span class="n">logger</span>
<span class="kn">from</span><span class="w"> </span><span class="nn">searx</span><span class="w"> </span><span class="kn">import</span> <span class="n">get_setting</span>
<span class="n">log</span> <span class="o">=</span> <span class="n">logger</span><span class="o">.</span><span class="n">getChild</span><span class="p">(</span><span class="s2">&quot;cache&quot;</span><span class="p">)</span>
<span class="n">CacheRowType</span><span class="p">:</span> <span class="n">typing</span><span class="o">.</span><span class="n">TypeAlias</span> <span class="o">=</span> <span class="nb">tuple</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">typing</span><span class="o">.</span><span class="n">Any</span><span class="p">,</span> <span class="nb">int</span> <span class="o">|</span> <span class="kc">None</span><span class="p">]</span>
<div class="viewcode-block" id="ExpireCacheCfg">
<a class="viewcode-back" href="../../src/searx.cache.html#searx.cache.ExpireCacheCfg">[docs]</a>
<span class="k">class</span><span class="w"> </span><span class="nc">ExpireCacheCfg</span><span class="p">(</span><span class="n">msgspec</span><span class="o">.</span><span class="n">Struct</span><span class="p">):</span> <span class="c1"># pylint: disable=too-few-public-methods</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;Configuration of a :py:obj:`ExpireCache` cache.&quot;&quot;&quot;</span>
<span class="n">name</span><span class="p">:</span> <span class="nb">str</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;Name of the cache.&quot;&quot;&quot;</span>
<span class="n">db_url</span><span class="p">:</span> <span class="nb">str</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;URL of the SQLite DB, the path to the database file. If unset a default</span>
<span class="sd"> DB will be created in `/tmp/sxng_cache_{self.name}.db`&quot;&quot;&quot;</span>
<span class="n">MAX_VALUE_LEN</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">1024</span> <span class="o">*</span> <span class="mi">10</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;Max length of a *serialized* value.&quot;&quot;&quot;</span>
<span class="n">MAXHOLD_TIME</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">60</span> <span class="o">*</span> <span class="mi">60</span> <span class="o">*</span> <span class="mi">24</span> <span class="o">*</span> <span class="mi">7</span> <span class="c1"># 7 days</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;Hold time (default in sec.), after which a value is removed from the cache.&quot;&quot;&quot;</span>
<span class="n">MAINTENANCE_PERIOD</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">60</span> <span class="o">*</span> <span class="mi">60</span> <span class="c1"># 2h</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;Maintenance period in seconds / when :py:obj:`MAINTENANCE_MODE` is set to</span>
<span class="sd"> ``auto``.&quot;&quot;&quot;</span>
<span class="n">MAINTENANCE_MODE</span><span class="p">:</span> <span class="n">typing</span><span class="o">.</span><span class="n">Literal</span><span class="p">[</span><span class="s2">&quot;auto&quot;</span><span class="p">,</span> <span class="s2">&quot;off&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="s2">&quot;auto&quot;</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;Type of maintenance mode</span>
<span class="sd"> ``auto``:</span>
<span class="sd"> Maintenance is carried out automatically as part of the maintenance</span>
<span class="sd"> intervals (:py:obj:`MAINTENANCE_PERIOD`); no external process is required.</span>
<span class="sd"> ``off``:</span>
<span class="sd"> Maintenance is switched off and must be carried out by an external process</span>
<span class="sd"> if required.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">password</span><span class="p">:</span> <span class="nb">bytes</span> <span class="o">=</span> <span class="n">get_setting</span><span class="p">(</span><span class="s2">&quot;server.secret_key&quot;</span><span class="p">)</span><span class="o">.</span><span class="n">encode</span><span class="p">()</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;Password used by :py:obj:`ExpireCache.secret_hash`.</span>
<span class="sd"> The default password is taken from :ref:`secret_key &lt;server.secret_key&gt;`.</span>
<span class="sd"> When the password is changed, the hashed keys in the cache can no longer be</span>
<span class="sd"> used, which is why all values in the cache are deleted when the password is</span>
<span class="sd"> changed.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">def</span><span class="w"> </span><span class="nf">__post_init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="c1"># if db_url is unset, use a default DB in /tmp/sxng_cache_{name}.db</span>
<span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">db_url</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">db_url</span> <span class="o">=</span> <span class="n">tempfile</span><span class="o">.</span><span class="n">gettempdir</span><span class="p">()</span> <span class="o">+</span> <span class="n">os</span><span class="o">.</span><span class="n">sep</span> <span class="o">+</span> <span class="sa">f</span><span class="s2">&quot;sxng_cache_</span><span class="si">{</span><span class="n">ExpireCache</span><span class="o">.</span><span class="n">normalize_name</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">name</span><span class="p">)</span><span class="si">}</span><span class="s2">.db&quot;</span></div>
<div class="viewcode-block" id="ExpireCacheStats">
<a class="viewcode-back" href="../../src/searx.cache.html#searx.cache.ExpireCacheStats">[docs]</a>
<span class="nd">@dataclasses</span><span class="o">.</span><span class="n">dataclass</span>
<span class="k">class</span><span class="w"> </span><span class="nc">ExpireCacheStats</span><span class="p">:</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;Dataclass which provides information on the status of the cache.&quot;&quot;&quot;</span>
<span class="n">cached_items</span><span class="p">:</span> <span class="nb">dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="nb">list</span><span class="p">[</span><span class="n">CacheRowType</span><span class="p">]]</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;Values in the cache mapped by context name.</span>
<span class="sd"> .. code: python</span>
<span class="sd"> {</span>
<span class="sd"> &quot;context name&quot;: [</span>
<span class="sd"> (&quot;foo key&quot;: &quot;foo value&quot;, &lt;expire&gt;),</span>
<span class="sd"> (&quot;bar key&quot;: &quot;bar value&quot;, &lt;expire&gt;),</span>
<span class="sd"> # ...</span>
<span class="sd"> ],</span>
<span class="sd"> # ...</span>
<span class="sd"> }</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">def</span><span class="w"> </span><span class="nf">report</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<span class="n">c_ctx</span> <span class="o">=</span> <span class="mi">0</span>
<span class="n">c_kv</span> <span class="o">=</span> <span class="mi">0</span>
<span class="n">lines</span><span class="p">:</span> <span class="nb">list</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">for</span> <span class="n">ctx_name</span><span class="p">,</span> <span class="n">kv_list</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">cached_items</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
<span class="n">c_ctx</span> <span class="o">+=</span> <span class="mi">1</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">kv_list</span><span class="p">:</span>
<span class="n">lines</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;[</span><span class="si">{</span><span class="n">ctx_name</span><span class="si">:</span><span class="s2">20s</span><span class="si">}</span><span class="s2">] empty&quot;</span><span class="p">)</span>
<span class="k">continue</span>
<span class="k">for</span> <span class="n">key</span><span class="p">,</span> <span class="n">value</span><span class="p">,</span> <span class="n">expire</span> <span class="ow">in</span> <span class="n">kv_list</span><span class="p">:</span>
<span class="n">valid_until</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span>
<span class="k">if</span> <span class="n">expire</span><span class="p">:</span>
<span class="n">valid_until</span> <span class="o">=</span> <span class="n">datetime</span><span class="o">.</span><span class="n">datetime</span><span class="o">.</span><span class="n">fromtimestamp</span><span class="p">(</span><span class="n">expire</span><span class="p">)</span><span class="o">.</span><span class="n">strftime</span><span class="p">(</span><span class="s2">&quot;%Y-%m-</span><span class="si">%d</span><span class="s2"> %H:%M:%S&quot;</span><span class="p">)</span>
<span class="n">c_kv</span> <span class="o">+=</span> <span class="mi">1</span>
<span class="n">lines</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;[</span><span class="si">{</span><span class="n">ctx_name</span><span class="si">:</span><span class="s2">20s</span><span class="si">}</span><span class="s2">] </span><span class="si">{</span><span class="n">valid_until</span><span class="si">}</span><span class="s2"> </span><span class="si">{</span><span class="n">key</span><span class="si">:</span><span class="s2">12</span><span class="si">}</span><span class="s2">&quot;</span> <span class="sa">f</span><span class="s2">&quot; --&gt; (</span><span class="si">{</span><span class="nb">type</span><span class="p">(</span><span class="n">value</span><span class="p">)</span><span class="o">.</span><span class="vm">__name__</span><span class="si">}</span><span class="s2">) </span><span class="si">{</span><span class="n">value</span><span class="si">}</span><span class="s2"> &quot;</span><span class="p">)</span>
<span class="n">lines</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;Number of contexts: </span><span class="si">{</span><span class="n">c_ctx</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
<span class="n">lines</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;number of key/value pairs: </span><span class="si">{</span><span class="n">c_kv</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
<span class="k">return</span> <span class="s2">&quot;</span><span class="se">\n</span><span class="s2">&quot;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">lines</span><span class="p">)</span></div>
<div class="viewcode-block" id="ExpireCache">
<a class="viewcode-back" href="../../src/searx.cache.html#searx.cache.ExpireCache">[docs]</a>
<span class="k">class</span><span class="w"> </span><span class="nc">ExpireCache</span><span class="p">(</span><span class="n">abc</span><span class="o">.</span><span class="n">ABC</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;Abstract base class for the implementation of a key/value cache</span>
<span class="sd"> with expire date.&quot;&quot;&quot;</span>
<span class="n">cfg</span><span class="p">:</span> <span class="n">ExpireCacheCfg</span>
<span class="n">hash_token</span><span class="p">:</span> <span class="nb">str</span> <span class="o">=</span> <span class="s2">&quot;hash_token&quot;</span>
<div class="viewcode-block" id="ExpireCache.set">
<a class="viewcode-back" href="../../src/searx.cache.html#searx.cache.ExpireCache.set">[docs]</a>
<span class="nd">@abc</span><span class="o">.</span><span class="n">abstractmethod</span>
<span class="k">def</span><span class="w"> </span><span class="nf">set</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">key</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">value</span><span class="p">:</span> <span class="n">typing</span><span class="o">.</span><span class="n">Any</span><span class="p">,</span> <span class="n">expire</span><span class="p">:</span> <span class="nb">int</span> <span class="o">|</span> <span class="kc">None</span><span class="p">,</span> <span class="n">ctx</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">bool</span><span class="p">:</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;Set *key* to *value*. To set a timeout on key use argument</span>
<span class="sd"> ``expire`` (in sec.). If expire is unset the default is taken from</span>
<span class="sd"> :py:obj:`ExpireCacheCfg.MAXHOLD_TIME`. After the timeout has expired,</span>
<span class="sd"> the key will automatically be deleted.</span>
<span class="sd"> The ``ctx`` argument specifies the context of the ``key``. A key is</span>
<span class="sd"> only unique in its context.</span>
<span class="sd"> The concrete implementations of this abstraction determine how the</span>
<span class="sd"> context is mapped in the connected database. In SQL databases, for</span>
<span class="sd"> example, the context is a DB table or in a Key/Value DB it could be</span>
<span class="sd"> a prefix for the key.</span>
<span class="sd"> If the context is not specified (the default is ``None``) then a</span>
<span class="sd"> default context should be used, e.g. a default table for SQL databases</span>
<span class="sd"> or a default prefix in a Key/Value DB.</span>
<span class="sd"> &quot;&quot;&quot;</span></div>
<div class="viewcode-block" id="ExpireCache.get">
<a class="viewcode-back" href="../../src/searx.cache.html#searx.cache.ExpireCache.get">[docs]</a>
<span class="nd">@abc</span><span class="o">.</span><span class="n">abstractmethod</span>
<span class="k">def</span><span class="w"> </span><span class="nf">get</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">key</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">default</span><span class="p">:</span> <span class="n">typing</span><span class="o">.</span><span class="n">Any</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span> <span class="n">ctx</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">typing</span><span class="o">.</span><span class="n">Any</span><span class="p">:</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;Return *value* of *key*. If key is unset, ``None`` is returned.&quot;&quot;&quot;</span></div>
<div class="viewcode-block" id="ExpireCache.maintenance">
<a class="viewcode-back" href="../../src/searx.cache.html#searx.cache.ExpireCache.maintenance">[docs]</a>
<span class="nd">@abc</span><span class="o">.</span><span class="n">abstractmethod</span>
<span class="k">def</span><span class="w"> </span><span class="nf">maintenance</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">force</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">False</span><span class="p">,</span> <span class="n">truncate</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">False</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">bool</span><span class="p">:</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;Performs maintenance on the cache.</span>
<span class="sd"> ``force``:</span>
<span class="sd"> Maintenance should be carried out even if the maintenance interval has</span>
<span class="sd"> not yet been reached.</span>
<span class="sd"> ``truncate``:</span>
<span class="sd"> Truncate the entire cache, which is necessary, for example, if the</span>
<span class="sd"> password has changed.</span>
<span class="sd"> &quot;&quot;&quot;</span></div>
<div class="viewcode-block" id="ExpireCache.state">
<a class="viewcode-back" href="../../src/searx.cache.html#searx.cache.ExpireCache.state">[docs]</a>
<span class="nd">@abc</span><span class="o">.</span><span class="n">abstractmethod</span>
<span class="k">def</span><span class="w"> </span><span class="nf">state</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">ExpireCacheStats</span><span class="p">:</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;Returns a :py:obj:`ExpireCacheStats`, which provides information</span>
<span class="sd"> about the status of the cache.&quot;&quot;&quot;</span></div>
<div class="viewcode-block" id="ExpireCache.build_cache">
<a class="viewcode-back" href="../../src/searx.cache.html#searx.cache.ExpireCache.build_cache">[docs]</a>
<span class="nd">@staticmethod</span>
<span class="k">def</span><span class="w"> </span><span class="nf">build_cache</span><span class="p">(</span><span class="n">cfg</span><span class="p">:</span> <span class="n">ExpireCacheCfg</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="s2">&quot;ExpireCacheSQLite&quot;</span><span class="p">:</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;Factory to build a caching instance.</span>
<span class="sd"> .. note::</span>
<span class="sd"> Currently, only the SQLite adapter is available, but other database</span>
<span class="sd"> types could be implemented in the future, e.g. a Valkey (Redis)</span>
<span class="sd"> adapter.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">return</span> <span class="n">ExpireCacheSQLite</span><span class="p">(</span><span class="n">cfg</span><span class="p">)</span></div>
<div class="viewcode-block" id="ExpireCache.normalize_name">
<a class="viewcode-back" href="../../src/searx.cache.html#searx.cache.ExpireCache.normalize_name">[docs]</a>
<span class="nd">@staticmethod</span>
<span class="k">def</span><span class="w"> </span><span class="nf">normalize_name</span><span class="p">(</span><span class="n">name</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">str</span><span class="p">:</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;Returns a normalized name that can be used as a file name or as a SQL</span>
<span class="sd"> table name (is used, for example, to normalize the context name).&quot;&quot;&quot;</span>
<span class="n">_valid</span> <span class="o">=</span> <span class="s2">&quot;-_.&quot;</span> <span class="o">+</span> <span class="n">string</span><span class="o">.</span><span class="n">ascii_letters</span> <span class="o">+</span> <span class="n">string</span><span class="o">.</span><span class="n">digits</span>
<span class="k">return</span> <span class="s2">&quot;&quot;</span><span class="o">.</span><span class="n">join</span><span class="p">([</span><span class="n">c</span> <span class="k">for</span> <span class="n">c</span> <span class="ow">in</span> <span class="n">name</span> <span class="k">if</span> <span class="n">c</span> <span class="ow">in</span> <span class="n">_valid</span><span class="p">])</span></div>
<span class="k">def</span><span class="w"> </span><span class="nf">serialize</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">value</span><span class="p">:</span> <span class="n">typing</span><span class="o">.</span><span class="n">Any</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">bytes</span><span class="p">:</span>
<span class="n">dump</span><span class="p">:</span> <span class="nb">bytes</span> <span class="o">=</span> <span class="n">pickle</span><span class="o">.</span><span class="n">dumps</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
<span class="k">return</span> <span class="n">dump</span>
<span class="k">def</span><span class="w"> </span><span class="nf">deserialize</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">value</span><span class="p">:</span> <span class="nb">bytes</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">typing</span><span class="o">.</span><span class="n">Any</span><span class="p">:</span>
<span class="n">obj</span> <span class="o">=</span> <span class="n">pickle</span><span class="o">.</span><span class="n">loads</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>
<span class="k">return</span> <span class="n">obj</span>
<div class="viewcode-block" id="ExpireCache.secret_hash">
<a class="viewcode-back" href="../../src/searx.cache.html#searx.cache.ExpireCache.secret_hash">[docs]</a>
<span class="k">def</span><span class="w"> </span><span class="nf">secret_hash</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">name</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="nb">bytes</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">str</span><span class="p">:</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;Creates a hash of the argument ``name``. The hash value is formed</span>
<span class="sd"> from the ``name`` combined with the :py:obj:`password</span>
<span class="sd"> &lt;ExpireCacheCfg.password&gt;`. Can be used, for example, to make the</span>
<span class="sd"> ``key`` stored in the DB unreadable for third parties.&quot;&quot;&quot;</span>
<span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="nb">str</span><span class="p">):</span>
<span class="n">name</span> <span class="o">=</span> <span class="nb">bytes</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">encoding</span><span class="o">=</span><span class="s1">&#39;utf-8&#39;</span><span class="p">)</span>
<span class="n">m</span> <span class="o">=</span> <span class="n">hmac</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="n">name</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">cfg</span><span class="o">.</span><span class="n">password</span><span class="p">,</span> <span class="n">digestmod</span><span class="o">=</span><span class="s1">&#39;sha256&#39;</span><span class="p">)</span>
<span class="k">return</span> <span class="n">m</span><span class="o">.</span><span class="n">hexdigest</span><span class="p">()</span></div>
</div>
<div class="viewcode-block" id="ExpireCacheSQLite">
<a class="viewcode-back" href="../../src/searx.cache.html#searx.cache.ExpireCacheSQLite">[docs]</a>
<span class="k">class</span><span class="w"> </span><span class="nc">ExpireCacheSQLite</span><span class="p">(</span><span class="n">sqlitedb</span><span class="o">.</span><span class="n">SQLiteAppl</span><span class="p">,</span> <span class="n">ExpireCache</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;Cache that manages key/value pairs in a SQLite DB. The DB model in the</span>
<span class="sd"> SQLite DB is implemented in abstract class :py:obj:`SQLiteAppl</span>
<span class="sd"> &lt;searx.sqlitedb.SQLiteAppl&gt;`.</span>
<span class="sd"> The following configurations are required / supported:</span>
<span class="sd"> - :py:obj:`ExpireCacheCfg.db_url`</span>
<span class="sd"> - :py:obj:`ExpireCacheCfg.MAXHOLD_TIME`</span>
<span class="sd"> - :py:obj:`ExpireCacheCfg.MAINTENANCE_PERIOD`</span>
<span class="sd"> - :py:obj:`ExpireCacheCfg.MAINTENANCE_MODE`</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">DB_SCHEMA</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">1</span>
<span class="c1"># The key/value tables will be created on demand by self.create_table</span>
<span class="n">DDL_CREATE_TABLES</span><span class="p">:</span> <span class="nb">dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="nb">str</span><span class="p">]</span> <span class="o">=</span> <span class="p">{}</span>
<span class="n">CACHE_TABLE_PREFIX</span><span class="p">:</span> <span class="nb">str</span> <span class="o">=</span> <span class="s2">&quot;CACHE-TABLE&quot;</span>
<span class="k">def</span><span class="w"> </span><span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">cfg</span><span class="p">:</span> <span class="n">ExpireCacheCfg</span><span class="p">):</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;An instance of the SQLite expire cache is build up from a</span>
<span class="sd"> :py:obj:`config &lt;ExpireCacheCfg&gt;`.&quot;&quot;&quot;</span>
<span class="bp">self</span><span class="o">.</span><span class="n">cfg</span><span class="p">:</span> <span class="n">ExpireCacheCfg</span> <span class="o">=</span> <span class="n">cfg</span>
<span class="k">if</span> <span class="n">cfg</span><span class="o">.</span><span class="n">db_url</span> <span class="o">==</span> <span class="s2">&quot;:memory:&quot;</span><span class="p">:</span>
<span class="n">log</span><span class="o">.</span><span class="n">critical</span><span class="p">(</span><span class="s2">&quot;don&#39;t use SQLite DB in :memory: in production!!&quot;</span><span class="p">)</span>
<span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="n">cfg</span><span class="o">.</span><span class="n">db_url</span><span class="p">)</span>
<div class="viewcode-block" id="ExpireCacheSQLite.init">
<a class="viewcode-back" href="../../src/searx.cache.html#searx.cache.ExpireCacheSQLite.init">[docs]</a>
<span class="k">def</span><span class="w"> </span><span class="nf">init</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">conn</span><span class="p">:</span> <span class="n">sqlite3</span><span class="o">.</span><span class="n">Connection</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">bool</span><span class="p">:</span>
<span class="n">ret_val</span> <span class="o">=</span> <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="n">init</span><span class="p">(</span><span class="n">conn</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">ret_val</span><span class="p">:</span>
<span class="k">return</span> <span class="kc">False</span>
<span class="n">new</span> <span class="o">=</span> <span class="n">hashlib</span><span class="o">.</span><span class="n">sha256</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">cfg</span><span class="o">.</span><span class="n">password</span><span class="p">)</span><span class="o">.</span><span class="n">hexdigest</span><span class="p">()</span>
<span class="n">old</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">properties</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">hash_token</span><span class="p">)</span>
<span class="k">if</span> <span class="n">old</span> <span class="o">!=</span> <span class="n">new</span><span class="p">:</span>
<span class="k">if</span> <span class="n">old</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
<span class="n">log</span><span class="o">.</span><span class="n">warning</span><span class="p">(</span><span class="s2">&quot;[</span><span class="si">%s</span><span class="s2">] hash token changed: truncate all cache tables&quot;</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">cfg</span><span class="o">.</span><span class="n">name</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">maintenance</span><span class="p">(</span><span class="n">force</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span> <span class="n">truncate</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">properties</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">hash_token</span><span class="p">,</span> <span class="n">new</span><span class="p">)</span>
<span class="k">return</span> <span class="kc">True</span></div>
<div class="viewcode-block" id="ExpireCacheSQLite.maintenance">
<a class="viewcode-back" href="../../src/searx.cache.html#searx.cache.ExpireCacheSQLite.maintenance">[docs]</a>
<span class="k">def</span><span class="w"> </span><span class="nf">maintenance</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">force</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">False</span><span class="p">,</span> <span class="n">truncate</span><span class="p">:</span> <span class="nb">bool</span> <span class="o">=</span> <span class="kc">False</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">bool</span><span class="p">:</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">force</span> <span class="ow">and</span> <span class="nb">int</span><span class="p">(</span><span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">())</span> <span class="o">&lt;</span> <span class="bp">self</span><span class="o">.</span><span class="n">next_maintenance_time</span><span class="p">:</span>
<span class="c1"># log.debug(&quot;no maintenance required yet, next maintenance interval is in the future&quot;)</span>
<span class="k">return</span> <span class="kc">False</span>
<span class="c1"># Prevent parallel DB maintenance cycles from other DB connections</span>
<span class="c1"># (e.g. in multi thread or process environments).</span>
<span class="bp">self</span><span class="o">.</span><span class="n">properties</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="s2">&quot;LAST_MAINTENANCE&quot;</span><span class="p">,</span> <span class="s2">&quot;&quot;</span><span class="p">)</span> <span class="c1"># hint: this (also) sets the m_time of the property!</span>
<span class="k">if</span> <span class="n">truncate</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">truncate_tables</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">table_names</span><span class="p">)</span>
<span class="k">return</span> <span class="kc">True</span>
<span class="c1"># drop items by expire time stamp ..</span>
<span class="n">expire</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">())</span>
<span class="k">with</span> <span class="bp">self</span><span class="o">.</span><span class="n">connect</span><span class="p">()</span> <span class="k">as</span> <span class="n">conn</span><span class="p">:</span>
<span class="k">for</span> <span class="n">table</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">table_names</span><span class="p">:</span>
<span class="n">res</span> <span class="o">=</span> <span class="n">conn</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;DELETE FROM </span><span class="si">{</span><span class="n">table</span><span class="si">}</span><span class="s2"> WHERE expire &lt; ?&quot;</span><span class="p">,</span> <span class="p">(</span><span class="n">expire</span><span class="p">,))</span>
<span class="n">log</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s2">&quot;deleted </span><span class="si">%s</span><span class="s2"> keys from table </span><span class="si">%s</span><span class="s2"> (expire date reached)&quot;</span><span class="p">,</span> <span class="n">res</span><span class="o">.</span><span class="n">rowcount</span><span class="p">,</span> <span class="n">table</span><span class="p">)</span>
<span class="c1"># Vacuuming the WALs</span>
<span class="c1"># https://www.theunterminatedstring.com/sqlite-vacuuming/</span>
<span class="n">conn</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s2">&quot;PRAGMA wal_checkpoint(TRUNCATE)&quot;</span><span class="p">)</span>
<span class="n">conn</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
<span class="k">return</span> <span class="kc">True</span></div>
<div class="viewcode-block" id="ExpireCacheSQLite.create_table">
<a class="viewcode-back" href="../../src/searx.cache.html#searx.cache.ExpireCacheSQLite.create_table">[docs]</a>
<span class="k">def</span><span class="w"> </span><span class="nf">create_table</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">table</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">bool</span><span class="p">:</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;Create DB ``table`` if it has not yet been created, no recreates are</span>
<span class="sd"> initiated if the table already exists.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="k">if</span> <span class="n">table</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">table_names</span><span class="p">:</span>
<span class="c1"># log.debug(&quot;key/value table %s exists in DB (no need to recreate)&quot;, table)</span>
<span class="k">return</span> <span class="kc">False</span>
<span class="n">log</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s2">&quot;key/value table &#39;</span><span class="si">%s</span><span class="s2">&#39; NOT exists in DB -&gt; create DB table ..&quot;</span><span class="p">,</span> <span class="n">table</span><span class="p">)</span>
<span class="n">sql_table</span> <span class="o">=</span> <span class="s2">&quot;</span><span class="se">\n</span><span class="s2">&quot;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span>
<span class="p">[</span>
<span class="sa">f</span><span class="s2">&quot;CREATE TABLE IF NOT EXISTS </span><span class="si">{</span><span class="n">table</span><span class="si">}</span><span class="s2"> (&quot;</span><span class="p">,</span>
<span class="s2">&quot; key TEXT,&quot;</span><span class="p">,</span>
<span class="s2">&quot; value BLOB,&quot;</span><span class="p">,</span>
<span class="sa">f</span><span class="s2">&quot; expire INTEGER DEFAULT (strftime(&#39;%s&#39;, &#39;now&#39;) + </span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">cfg</span><span class="o">.</span><span class="n">MAXHOLD_TIME</span><span class="si">}</span><span class="s2">),&quot;</span><span class="p">,</span>
<span class="s2">&quot;PRIMARY KEY (key))&quot;</span><span class="p">,</span>
<span class="p">]</span>
<span class="p">)</span>
<span class="n">sql_index</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">&quot;CREATE INDEX IF NOT EXISTS index_expire_</span><span class="si">{</span><span class="n">table</span><span class="si">}</span><span class="s2"> ON </span><span class="si">{</span><span class="n">table</span><span class="si">}</span><span class="s2">(expire);&quot;</span>
<span class="k">with</span> <span class="bp">self</span><span class="o">.</span><span class="n">connect</span><span class="p">()</span> <span class="k">as</span> <span class="n">conn</span><span class="p">:</span>
<span class="n">conn</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="n">sql_table</span><span class="p">)</span>
<span class="n">conn</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="n">sql_index</span><span class="p">)</span>
<span class="n">conn</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
<span class="bp">self</span><span class="o">.</span><span class="n">properties</span><span class="o">.</span><span class="n">set</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">CACHE_TABLE_PREFIX</span><span class="si">}</span><span class="s2">-</span><span class="si">{</span><span class="n">table</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">,</span> <span class="n">table</span><span class="p">)</span>
<span class="k">return</span> <span class="kc">True</span></div>
<span class="nd">@property</span>
<span class="k">def</span><span class="w"> </span><span class="nf">table_names</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">list</span><span class="p">[</span><span class="nb">str</span><span class="p">]:</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;List of key/value tables already created in the DB.&quot;&quot;&quot;</span>
<span class="n">sql</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">&quot;SELECT value FROM properties WHERE name LIKE &#39;</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">CACHE_TABLE_PREFIX</span><span class="si">}</span><span class="s2">%%&#39;&quot;</span>
<span class="n">rows</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">DB</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="n">sql</span><span class="p">)</span><span class="o">.</span><span class="n">fetchall</span><span class="p">()</span> <span class="ow">or</span> <span class="p">[]</span>
<span class="k">return</span> <span class="p">[</span><span class="n">r</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="k">for</span> <span class="n">r</span> <span class="ow">in</span> <span class="n">rows</span><span class="p">]</span>
<span class="k">def</span><span class="w"> </span><span class="nf">truncate_tables</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">table_names</span><span class="p">:</span> <span class="nb">list</span><span class="p">[</span><span class="nb">str</span><span class="p">]):</span>
<span class="n">log</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s2">&quot;truncate table: </span><span class="si">%s</span><span class="s2">&quot;</span><span class="p">,</span> <span class="s2">&quot;,&quot;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">table_names</span><span class="p">))</span>
<span class="k">with</span> <span class="bp">self</span><span class="o">.</span><span class="n">connect</span><span class="p">()</span> <span class="k">as</span> <span class="n">conn</span><span class="p">:</span>
<span class="k">for</span> <span class="n">table</span> <span class="ow">in</span> <span class="n">table_names</span><span class="p">:</span>
<span class="n">conn</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;DELETE FROM </span><span class="si">{</span><span class="n">table</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span>
<span class="n">conn</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
<span class="k">return</span> <span class="kc">True</span>
<span class="nd">@property</span>
<span class="k">def</span><span class="w"> </span><span class="nf">next_maintenance_time</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">int</span><span class="p">:</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;Returns (unix epoch) time of the next maintenance.&quot;&quot;&quot;</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">cfg</span><span class="o">.</span><span class="n">MAINTENANCE_PERIOD</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">properties</span><span class="o">.</span><span class="n">m_time</span><span class="p">(</span><span class="s2">&quot;LAST_MAINTENANCE&quot;</span><span class="p">,</span> <span class="nb">int</span><span class="p">(</span><span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">()))</span>
<span class="c1"># implement ABC methods of ExpireCache</span>
<div class="viewcode-block" id="ExpireCacheSQLite.set">
<a class="viewcode-back" href="../../src/searx.cache.html#searx.cache.ExpireCacheSQLite.set">[docs]</a>
<span class="k">def</span><span class="w"> </span><span class="nf">set</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">key</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">value</span><span class="p">:</span> <span class="n">typing</span><span class="o">.</span><span class="n">Any</span><span class="p">,</span> <span class="n">expire</span><span class="p">:</span> <span class="nb">int</span> <span class="o">|</span> <span class="kc">None</span><span class="p">,</span> <span class="n">ctx</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">bool</span><span class="p">:</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;Set key/value in DB table given by argument ``ctx``. If expire is</span>
<span class="sd"> unset the default is taken from :py:obj:`ExpireCacheCfg.MAXHOLD_TIME`.</span>
<span class="sd"> If ``ctx`` argument is ``None`` (the default), a table name is</span>
<span class="sd"> generated from the :py:obj:`ExpireCacheCfg.name`. If DB table does not</span>
<span class="sd"> exists, it will be created (on demand) by :py:obj:`self.create_table</span>
<span class="sd"> &lt;ExpireCacheSQLite.create_table&gt;`.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">c</span><span class="p">,</span> <span class="n">err_msg_list</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_setmany</span><span class="p">([(</span><span class="n">key</span><span class="p">,</span> <span class="n">value</span><span class="p">,</span> <span class="n">expire</span><span class="p">)],</span> <span class="n">ctx</span><span class="o">=</span><span class="n">ctx</span><span class="p">)</span>
<span class="k">if</span> <span class="n">c</span><span class="p">:</span>
<span class="n">log</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span><span class="s2">&quot;</span><span class="si">%s</span><span class="s2"> -- </span><span class="si">%s</span><span class="s2">: key &#39;</span><span class="si">%s</span><span class="s2">&#39; updated or inserted (</span><span class="si">%s</span><span class="s2"> errors)&quot;</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">cfg</span><span class="o">.</span><span class="n">name</span><span class="p">,</span> <span class="n">ctx</span><span class="p">,</span> <span class="n">key</span><span class="p">,</span> <span class="nb">len</span><span class="p">(</span><span class="n">err_msg_list</span><span class="p">))</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">for</span> <span class="n">msg</span> <span class="ow">in</span> <span class="n">err_msg_list</span><span class="p">:</span>
<span class="n">log</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="s2">&quot;</span><span class="si">%s</span><span class="s2"> -- </span><span class="si">%s</span><span class="s2">: </span><span class="si">%s</span><span class="s2">&quot;</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">cfg</span><span class="o">.</span><span class="n">name</span><span class="p">,</span> <span class="n">ctx</span><span class="p">,</span> <span class="n">msg</span><span class="p">)</span>
<span class="k">return</span> <span class="nb">bool</span><span class="p">(</span><span class="n">c</span><span class="p">)</span></div>
<div class="viewcode-block" id="ExpireCacheSQLite.setmany">
<a class="viewcode-back" href="../../src/searx.cache.html#searx.cache.ExpireCacheSQLite.setmany">[docs]</a>
<span class="k">def</span><span class="w"> </span><span class="nf">setmany</span><span class="p">(</span>
<span class="bp">self</span><span class="p">,</span>
<span class="n">opt_list</span><span class="p">:</span> <span class="nb">list</span><span class="p">[</span><span class="n">CacheRowType</span><span class="p">],</span>
<span class="n">ctx</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">int</span><span class="p">:</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;Efficient bootload of the cache from a list of options. The list</span>
<span class="sd"> contains tuples with the arguments described in</span>
<span class="sd"> :py:obj:`ExpireCacheSQLite.set`.&quot;&quot;&quot;</span>
<span class="n">_start</span> <span class="o">=</span> <span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">()</span>
<span class="n">c</span><span class="p">,</span> <span class="n">err_msg_list</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_setmany</span><span class="p">(</span><span class="n">opt_list</span><span class="o">=</span><span class="n">opt_list</span><span class="p">,</span> <span class="n">ctx</span><span class="o">=</span><span class="n">ctx</span><span class="p">)</span>
<span class="n">_end</span> <span class="o">=</span> <span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">()</span>
<span class="k">for</span> <span class="n">msg</span> <span class="ow">in</span> <span class="n">err_msg_list</span><span class="p">:</span>
<span class="n">log</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="s2">&quot;</span><span class="si">%s</span><span class="s2"> -- </span><span class="si">%s</span><span class="s2">: </span><span class="si">%s</span><span class="s2">&quot;</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">cfg</span><span class="o">.</span><span class="n">name</span><span class="p">,</span> <span class="n">ctx</span><span class="p">,</span> <span class="n">msg</span><span class="p">)</span>
<span class="n">log</span><span class="o">.</span><span class="n">debug</span><span class="p">(</span>
<span class="s2">&quot;</span><span class="si">%s</span><span class="s2"> -- </span><span class="si">%s</span><span class="s2">: </span><span class="si">%s</span><span class="s2">/</span><span class="si">%s</span><span class="s2"> key/value pairs updated or inserted in </span><span class="si">%s</span><span class="s2"> sec (</span><span class="si">%s</span><span class="s2"> errors)&quot;</span><span class="p">,</span>
<span class="bp">self</span><span class="o">.</span><span class="n">cfg</span><span class="o">.</span><span class="n">name</span><span class="p">,</span>
<span class="n">ctx</span><span class="p">,</span>
<span class="n">c</span><span class="p">,</span>
<span class="nb">len</span><span class="p">(</span><span class="n">opt_list</span><span class="p">),</span>
<span class="n">_end</span> <span class="o">-</span> <span class="n">_start</span><span class="p">,</span>
<span class="nb">len</span><span class="p">(</span><span class="n">err_msg_list</span><span class="p">),</span>
<span class="p">)</span>
<span class="k">return</span> <span class="n">c</span></div>
<span class="k">def</span><span class="w"> </span><span class="nf">_setmany</span><span class="p">(</span>
<span class="bp">self</span><span class="p">,</span>
<span class="n">opt_list</span><span class="p">:</span> <span class="nb">list</span><span class="p">[</span><span class="n">CacheRowType</span><span class="p">],</span>
<span class="n">ctx</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span>
<span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">tuple</span><span class="p">[</span><span class="nb">int</span><span class="p">,</span> <span class="nb">list</span><span class="p">[</span><span class="nb">str</span><span class="p">]]:</span>
<span class="n">table</span> <span class="o">=</span> <span class="n">ctx</span>
<span class="bp">self</span><span class="o">.</span><span class="n">maintenance</span><span class="p">()</span>
<span class="n">table_name</span> <span class="o">=</span> <span class="n">table</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">table_name</span><span class="p">:</span>
<span class="n">table_name</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">normalize_name</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">cfg</span><span class="o">.</span><span class="n">name</span><span class="p">)</span>
<span class="bp">self</span><span class="o">.</span><span class="n">create_table</span><span class="p">(</span><span class="n">table_name</span><span class="p">)</span>
<span class="n">sql_str</span> <span class="o">=</span> <span class="p">(</span>
<span class="sa">f</span><span class="s2">&quot;INSERT INTO </span><span class="si">{</span><span class="n">table_name</span><span class="si">}</span><span class="s2"> (key, value, expire) VALUES (?, ?, ?)&quot;</span>
<span class="sa">f</span><span class="s2">&quot; ON CONFLICT DO &quot;</span>
<span class="sa">f</span><span class="s2">&quot;UPDATE SET value=?, expire=?&quot;</span>
<span class="p">)</span>
<span class="n">sql_rows</span><span class="p">:</span> <span class="nb">list</span><span class="p">[</span>
<span class="nb">tuple</span><span class="p">[</span>
<span class="nb">str</span><span class="p">,</span> <span class="c1"># key</span>
<span class="n">typing</span><span class="o">.</span><span class="n">Any</span><span class="p">,</span> <span class="c1"># value</span>
<span class="nb">int</span> <span class="o">|</span> <span class="kc">None</span><span class="p">,</span> <span class="c1"># expire</span>
<span class="n">typing</span><span class="o">.</span><span class="n">Any</span><span class="p">,</span> <span class="c1"># value</span>
<span class="nb">int</span> <span class="o">|</span> <span class="kc">None</span><span class="p">,</span> <span class="c1"># expire</span>
<span class="p">]</span>
<span class="p">]</span> <span class="o">=</span> <span class="p">[]</span>
<span class="n">err_msg_list</span><span class="p">:</span> <span class="nb">list</span><span class="p">[</span><span class="nb">str</span><span class="p">]</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">for</span> <span class="n">key</span><span class="p">,</span> <span class="n">_val</span><span class="p">,</span> <span class="n">expire</span> <span class="ow">in</span> <span class="n">opt_list</span><span class="p">:</span>
<span class="n">value</span><span class="p">:</span> <span class="nb">bytes</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">serialize</span><span class="p">(</span><span class="n">value</span><span class="o">=</span><span class="n">_val</span><span class="p">)</span>
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">value</span><span class="p">)</span> <span class="o">&gt;</span> <span class="bp">self</span><span class="o">.</span><span class="n">cfg</span><span class="o">.</span><span class="n">MAX_VALUE_LEN</span><span class="p">:</span>
<span class="n">err_msg_list</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="n">table</span><span class="si">}</span><span class="s2">.key=&#39;</span><span class="si">{</span><span class="n">key</span><span class="si">}</span><span class="s2">&#39; - serialized value too big to cache (len: </span><span class="si">{</span><span class="nb">len</span><span class="p">(</span><span class="n">value</span><span class="p">)</span><span class="si">}</span><span class="s2">) &quot;</span><span class="p">)</span>
<span class="k">continue</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">expire</span><span class="p">:</span>
<span class="n">expire</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">cfg</span><span class="o">.</span><span class="n">MAXHOLD_TIME</span>
<span class="n">expire</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">())</span> <span class="o">+</span> <span class="n">expire</span>
<span class="c1"># positional arguments of the INSERT INTO statement</span>
<span class="n">sql_args</span> <span class="o">=</span> <span class="p">(</span><span class="n">key</span><span class="p">,</span> <span class="n">value</span><span class="p">,</span> <span class="n">expire</span><span class="p">,</span> <span class="n">value</span><span class="p">,</span> <span class="n">expire</span><span class="p">)</span>
<span class="n">sql_rows</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">sql_args</span><span class="p">)</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">sql_rows</span><span class="p">:</span>
<span class="k">return</span> <span class="mi">0</span><span class="p">,</span> <span class="n">err_msg_list</span>
<span class="k">if</span> <span class="n">table</span><span class="p">:</span>
<span class="k">with</span> <span class="bp">self</span><span class="o">.</span><span class="n">DB</span><span class="p">:</span>
<span class="bp">self</span><span class="o">.</span><span class="n">DB</span><span class="o">.</span><span class="n">executemany</span><span class="p">(</span><span class="n">sql_str</span><span class="p">,</span> <span class="n">sql_rows</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="k">with</span> <span class="bp">self</span><span class="o">.</span><span class="n">connect</span><span class="p">()</span> <span class="k">as</span> <span class="n">conn</span><span class="p">:</span>
<span class="n">conn</span><span class="o">.</span><span class="n">executemany</span><span class="p">(</span><span class="n">sql_str</span><span class="p">,</span> <span class="n">sql_rows</span><span class="p">)</span>
<span class="n">conn</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
<span class="k">return</span> <span class="nb">len</span><span class="p">(</span><span class="n">sql_rows</span><span class="p">),</span> <span class="n">err_msg_list</span>
<div class="viewcode-block" id="ExpireCacheSQLite.get">
<a class="viewcode-back" href="../../src/searx.cache.html#searx.cache.ExpireCacheSQLite.get">[docs]</a>
<span class="k">def</span><span class="w"> </span><span class="nf">get</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">key</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">default</span><span class="p">:</span> <span class="n">typing</span><span class="o">.</span><span class="n">Any</span> <span class="o">=</span> <span class="kc">None</span><span class="p">,</span> <span class="n">ctx</span><span class="p">:</span> <span class="nb">str</span> <span class="o">|</span> <span class="kc">None</span> <span class="o">=</span> <span class="kc">None</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">typing</span><span class="o">.</span><span class="n">Any</span><span class="p">:</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;Get value of ``key`` from table given by argument ``ctx``. If</span>
<span class="sd"> ``ctx`` argument is ``None`` (the default), a table name is generated</span>
<span class="sd"> from the :py:obj:`ExpireCacheCfg.name`. If ``key`` not exists (in</span>
<span class="sd"> table), the ``default`` value is returned.</span>
<span class="sd"> &quot;&quot;&quot;</span>
<span class="n">table</span> <span class="o">=</span> <span class="n">ctx</span>
<span class="bp">self</span><span class="o">.</span><span class="n">maintenance</span><span class="p">()</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">table</span><span class="p">:</span>
<span class="n">table</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">normalize_name</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">cfg</span><span class="o">.</span><span class="n">name</span><span class="p">)</span>
<span class="k">if</span> <span class="n">table</span> <span class="ow">not</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">table_names</span><span class="p">:</span>
<span class="k">return</span> <span class="n">default</span>
<span class="n">sql</span> <span class="o">=</span> <span class="sa">f</span><span class="s2">&quot;SELECT value FROM </span><span class="si">{</span><span class="n">table</span><span class="si">}</span><span class="s2"> WHERE key = ?&quot;</span>
<span class="n">row</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">DB</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="n">sql</span><span class="p">,</span> <span class="p">(</span><span class="n">key</span><span class="p">,))</span><span class="o">.</span><span class="n">fetchone</span><span class="p">()</span>
<span class="k">if</span> <span class="n">row</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
<span class="k">return</span> <span class="n">default</span>
<span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">deserialize</span><span class="p">(</span><span class="n">row</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span></div>
<div class="viewcode-block" id="ExpireCacheSQLite.pairs">
<a class="viewcode-back" href="../../src/searx.cache.html#searx.cache.ExpireCacheSQLite.pairs">[docs]</a>
<span class="k">def</span><span class="w"> </span><span class="nf">pairs</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">ctx</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">Iterator</span><span class="p">[</span><span class="nb">tuple</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="n">typing</span><span class="o">.</span><span class="n">Any</span><span class="p">]]:</span>
<span class="w"> </span><span class="sd">&quot;&quot;&quot;Iterate over key/value pairs from table given by argument ``ctx``.</span>
<span class="sd"> If ``ctx`` argument is ``None`` (the default), a table name is</span>
<span class="sd"> generated from the :py:obj:`ExpireCacheCfg.name`.&quot;&quot;&quot;</span>
<span class="n">table</span> <span class="o">=</span> <span class="n">ctx</span>
<span class="bp">self</span><span class="o">.</span><span class="n">maintenance</span><span class="p">()</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">table</span><span class="p">:</span>
<span class="n">table</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">normalize_name</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">cfg</span><span class="o">.</span><span class="n">name</span><span class="p">)</span>
<span class="k">if</span> <span class="n">table</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">table_names</span><span class="p">:</span>
<span class="k">for</span> <span class="n">row</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">DB</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;SELECT key, value FROM </span><span class="si">{</span><span class="n">table</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">):</span>
<span class="k">yield</span> <span class="n">row</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="bp">self</span><span class="o">.</span><span class="n">deserialize</span><span class="p">(</span><span class="n">row</span><span class="p">[</span><span class="mi">1</span><span class="p">])</span></div>
<div class="viewcode-block" id="ExpireCacheSQLite.state">
<a class="viewcode-back" href="../../src/searx.cache.html#searx.cache.ExpireCacheSQLite.state">[docs]</a>
<span class="k">def</span><span class="w"> </span><span class="nf">state</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="n">ExpireCacheStats</span><span class="p">:</span>
<span class="n">cached_items</span><span class="p">:</span> <span class="nb">dict</span><span class="p">[</span><span class="nb">str</span><span class="p">,</span> <span class="nb">list</span><span class="p">[</span><span class="n">CacheRowType</span><span class="p">]]</span> <span class="o">=</span> <span class="p">{}</span>
<span class="k">for</span> <span class="n">table</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">table_names</span><span class="p">:</span>
<span class="n">cached_items</span><span class="p">[</span><span class="n">table</span><span class="p">]</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">for</span> <span class="n">row</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">DB</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="sa">f</span><span class="s2">&quot;SELECT key, value, expire FROM </span><span class="si">{</span><span class="n">table</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">):</span>
<span class="n">cached_items</span><span class="p">[</span><span class="n">table</span><span class="p">]</span><span class="o">.</span><span class="n">append</span><span class="p">((</span><span class="n">row</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="bp">self</span><span class="o">.</span><span class="n">deserialize</span><span class="p">(</span><span class="n">row</span><span class="p">[</span><span class="mi">1</span><span class="p">]),</span> <span class="n">row</span><span class="p">[</span><span class="mi">2</span><span class="p">]))</span>
<span class="k">return</span> <span class="n">ExpireCacheStats</span><span class="p">(</span><span class="n">cached_items</span><span class="o">=</span><span class="n">cached_items</span><span class="p">)</span></div>
</div>
</pre></div>
</article>
</div>
<footer>
<div class="related-pages">
</div>
<div class="bottom-of-page">
<div class="left-details">
<div class="copyright">
Copyright &#169; SearXNG team
</div>
Made with
<a href="https://github.com/pradyunsg/furo">Furo</a>
</div>
<div class="right-details">
<div class="icons">
<a class="muted-link " href="https://github.com/searxng/searxng/" aria-label="GitHub">&#x1F4BE;</a>
<a class="muted-link " href="https://searx.space/" aria-label="searx.space">&#x1F310;</a>
</div>
</div>
</div>
</footer>
</div>
<aside class="toc-drawer no-toc">
</aside>
</div>
</div><script src="../../_static/documentation_options.js?v=d004a72a"></script>
<script src="../../_static/doctools.js?v=fd6eb6e6"></script>
<script src="../../_static/sphinx_highlight.js?v=6ffebe34"></script>
<script src="../../_static/scripts/furo.js?v=46bd48cc"></script>
</body>
</html>