blackbull.middleware.cache¶
blackbull.middleware.cache
¶
Response caching middleware (RFC 9111 — HTTP Caching).
Caches successful GET/HEAD responses in a per-worker, in-memory LRU. Subsequent matching requests are served directly from the cache without running the handler. Supports:
- TTL — server-side
max_age(default 300 s), overridable by the response'sCache-Control: max-age=…directive (or, when present,s-maxage=…which takes precedence for shared caches). - ETag — auto-generated as
W/"<sha256-prefix>"over the response body when the application does not supply one. The client'sIf-None-Matchheader is honoured: a match yields a 304 Not Modified with no body, regardless of the cached entry's TTL. - Cache-Control respect — responses carrying
no-store,private, orno-cacheare passed through and not stored. Requests carryingno-storeskip the cache lookup too. - Authorization header — by default, requests with an
Authorizationheader are NOT served from cache and their responses are NOT stored (RFC 9111 §3.5). Override withcache_authenticated=True.
What it doesn't do (yet):
- No
Varyheader support beyond identity matching. A request that differs only byAccept-EncodingorAccept-Languagewill get the first variant cached. - No server-side invalidation API. Restart the worker (or wait for TTL) to clear.
- No cross-worker sharing. The cache is per-process — each worker has its own. Documented limitation.
The cache key is (method, path, query_string).
Usage::
from blackbull.middleware import Cache
app.use(Cache(max_age=600)) # 10-minute TTL
@app.route(path='/feed')
async def feed(scope, receive, send):
... # served from cache for 10 min after first hit
Cache
¶
Per-worker in-memory response cache.