harp_apps.http_cache.storages

Inheritance diagram of harp_apps.http_cache.storages

class AsyncStorage[source]

Bases: AsyncBaseStorage

HARP’s AsyncBaseStorage implementation using blob storage backend.

This implementation adapts hishel 1.0’s Entry-based API to work with HARP’s blob storage system. We store a single entry per cache key, maintaining backward compatibility with existing cached data.

hishel addresses entries by UUID while this store addresses blobs by cache key, so a bounded index of recently seen ids bridges the two. See KEY_INDEX_SIZE for why a small bound is sufficient, and _key_for() for what happens when it is not.

__init__(storage, ttl=None, check_ttl_every=60, allow_heuristics=False)[source]
Parameters:
async close()[source]

Close the storage (required by AsyncBaseStorage interface).

Return type:

None

async create_entry(request, response, key, id_=None)[source]

Create and store a new cache entry.

Args:

request: The HTTP request response: The HTTP response key: The cache key id_: Optional UUID for the entry (generated if not provided)

Returns:

The created Entry

Parameters:
  • request (Request)

  • response (Response)

  • key (str)

  • id_ (UUID | None)

Return type:

Entry

async get_entries(key)[source]

Retrieve all entries for a given cache key.

Note: Our implementation stores only one entry per key, so this returns a list with at most one element.

Args:

key: The cache key

Returns:

List of Entry objects (empty if not found, single element if found)

Parameters:

key (str)

Return type:

List[Entry]

async remove_entry(id)[source]

Remove an entry by its ID.

hishel invalidates the stored entries a revalidation did not match, which only arises where several entries share a cache key. This store holds one entry per key, so hishel does not currently reach this method: the lists it builds for invalidation (revalidating_entries[:-1], and the non-matching entries after a 304) are always empty here. It is implemented rather than left inert because that is a property of the storage shape today and not of the contract, and it changes the moment one key can hold several variants. See https://github.com/msqd/harp/issues/910.

Args:

id: The entry UUID

Parameters:

id (UUID)

Return type:

None

async update_entry(id, new_entry)[source]

Update an existing entry by its ID.

hishel calls this to write a 304’s refreshed headers back onto the stored entry. If it does nothing, the entry stays exactly as stale as it was and every subsequent request revalidates again, without end.

Args:

id: The entry UUID new_entry: Either a new Entry object or a callable that transforms the existing entry

Returns:

The updated Entry, or None if it could not be resolved

Parameters:
Return type:

Entry | None

has_explicit_freshness(response)[source]

Whether the origin stated how long its response stays fresh.

Mirrors the first three rules of RFC 9111 §4.2.1 (s-maxage, max-age, Expires) and deliberately stops before the fourth, which is the Last-Modified heuristic.

Parameters:

response (Response)

Return type:

bool