import contextlib import datetime import sqlite3 class Cache: def __init__(self, db): self.db = db def get(self, key, ttl, f): now = datetime.datetime.now(datetime.timezone.utc) earliest_acceptable = now - ttl match self.db.execute( 'SELECT value FROM cache WHERE key = ? AND timestamp >= ?', (key, earliest_acceptable), ).fetchall(): case [(value,)]: return value value = f() self.db.execute( 'INSERT INTO cache (key, timestamp, value) VALUES (?, ?, ?) ' + 'ON CONFLICT(key) DO UPDATE SET timestamp = excluded.timestamp, value = excluded.value', (key, now, value), ) return value @contextlib.contextmanager def open(): with sqlite3.connect('cache.sqlite', isolation_level=None) as db: db.execute('CREATE TABLE IF NOT EXISTS cache (key TEXT PRIMARY KEY, timestamp TEXT NOT NULL, value TEXT NOT NULL)') yield Cache(db)