import contextlib import datetime import sqlite3 class Cache: def __init__(self, db): self.db = db def get(self, key, timeout, f): now = datetime.datetime.now() earliest_acceptable = now - timeout match self.db.execute( 'SELECT value FROM cache WHERE key = ? AND timestamp >= ?', (key, earliest_acceptable.isoformat()), ).fetchall(): case [(value,)]: self.db.commit() 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.isoformat(), 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)