[docs]classPostgresCacheBackend(CacheBackend):"""Wrapper for higher-level cache operations. In most cases, the only thing you need to specify here is which storage class(es) to use"""def__init__(self,**kwargs:Any)->None:super().__init__(**kwargs)self.redirects=PostgresStorage(**kwargs)self.responses=PostgresStorage(**kwargs)
[docs]classPostgresStorage(BaseCache):"""interface for lower-level backend storage operations"""def__init__(self,**kwargs:Any)->None:super().__init__(**kwargs)
[docs]asyncdefcontains(self,key:str)->bool:"""Check if a key is stored in the cache"""returnawaitAioHttpCacheRow.exists().where(AioHttpCacheRow.key==key)
[docs]asyncdefclear(self)->None:"""Delete all items from the cache"""awaitAioHttpCacheRow.raw("TRUNCATE TABLE aiohttp_client_cache")
[docs]asyncdefdelete(self,key:str)->None:"""Delete an item from the cache"""awaitAioHttpCacheRow.delete().where(AioHttpCacheRow.key==key)
[docs]asyncdefkeys(self)->AsyncIterable[str]:"""Get all keys stored in the cache"""forentryinawaitAioHttpCacheRow.select(AioHttpCacheRow.key).output(load_json=True,nested=True):yieldentry["key"]
[docs]asyncdefread(self,key:str)->ResponseOrKey:"""Read an item from the cache"""response=(awaitAioHttpCacheRow.select(AioHttpCacheRow.value).where(AioHttpCacheRow.key==key).first().output(load_json=True,nested=True))returnself.deserialize(response["value"])ifresponseelseNone
[docs]asyncdefsize(self)->int:"""Get the number of items in the cache"""returnawaitAioHttpCacheRow.count()
[docs]defvalues(self)->AsyncIterable[ResponseOrKey]:"""Get all values stored in the cache"""returnself._values()
[docs]asyncdefwrite(self,key:str,item:ResponseOrKey)->None:"""Write an item to the cache"""awaitAioHttpCacheRow.insert(AioHttpCacheRow(key=key,value=self.serialize(item))).on_conflict(action="DO NOTHING",target=AioHttpCacheRow.key)
[docs]asyncdefbulk_delete(self,keys:set[str])->None:"""Delete multiple items from the cache"""awaitAioHttpCacheRow.delete().where(AioHttpCacheRow.key.is_in(list(keys)))