Caching and usage statistics¶
basef1.client.BaseF1Client caches successful JSON responses for idempotent GET requests. Each logical terminal call (get_seasons, query()....get_races(), etc.) goes through the same path: build URL and limit/offset query parameters, look up a cache entry, and only hit the network on a miss.
What gets cached¶
Only responses that become a valid top-level JSON object (
dict) after transport and parsing are stored.Failures (
basef1.exceptions.JolpicaHTTPError) are not cached.Stored values are deep copies on read and write, so mutating a response body in application code does not corrupt the cache.
Cache keys¶
Keys are produced by basef1.cache.cache_key_for_request() using the HTTP method (always GET here), full URL, and sorted query parameters. Two calls with the same URL and the same parameters hit the same entry regardless of dict iteration order in your code.
In-memory backend (default)¶
The default backend is basef1.cache.TTLCache:
Entries expire after
ttl_seconds(client default:basef1.client.DEFAULT_CACHE_TTL_SECONDS).Capacity is bounded by
max_entries(default256). When full, the oldest inserted entry is evicted first (LRU-ish insertion order).
SQLite backend¶
cache_backend="sqlite" uses basef1.cache.SQLiteCache:
Database path defaults to
basef1.cache.default_sqlite_cache_path()(~/.cache/basef1/http_cache.sqlite), unless you passcache_path=.WAL journaling is enabled. Expired rows are removed opportunistically on read and write.
Entries persist across processes until TTL expiry—useful for notebooks or repeated scripts.
Always close the client (context manager or close()) so the SQLite connection is released.
Constructor cheat sheet¶
These rules mirror basef1.client.BaseF1Client:
cache=False— disable caching (every logical request issues an HTTP GET unless you use a custom stack).cache_ttl=/cache_max_entries=/cache_backend=/cache_path=— build an internalTTLCacheorSQLiteCache. Do not combinecache_ttl=withcache=.cache=some_cache— inject your ownTTLCacheorSQLiteCache. Do not combine withcache_backend=.
Usage statistics and request log¶
The client tracks:
logical_requests — how many terminal GETs ran through
usage_snapshot()accounting (includes cache hits).http_requests — how many HTTP GETs went on the wire.
cache_hits — logical requests satisfied from cache.
Inspect programmatically:
from basef1 import BaseF1Client
with BaseF1Client() as client:
client.get_seasons(limit=30, offset=0)
client.get_seasons(limit=30, offset=0)
snap = client.usage_snapshot()
print(snap.logical_requests, snap.http_requests, snap.cache_hits)
for entry in snap.request_log:
print(entry.method, entry.url, entry.source)
Print a human-readable summary (includes approximate cache hit rate and up to 10 recent log lines):
client.stats()
Redirect output when logging:
import io
buf = io.StringIO()
client.stats(file=buf)
The in-memory request log length is capped by request_log_maxlen (default 512; None means unlimited). Each entry records method, URL, sorted params, and cache vs network.
Note: Counting happens when the client commits to a cache lookup or network fetch. Failed HTTP or invalid JSON still increments logical_requests and http_requests where those attempts occur.