High level key-value storage and cache tool.
pip install hilcat
Cache api is designed to determine a unique node by scope
and key
.
In some implements, scope
may be always None
and should be ignored, thus unique node determined only by key
.
create a cache based on redis
from hilcat import Cache
cache = Cache.from_uri('redis://localhost:1458')
create a cache based on sqlite
from hilcat import Cache
cache = Cache.from_uri('sqlite:///t.db')
from hilcat import MemoryCache
cache = MemoryCache()
cache text content in file
from hilcat import SimpleTextFileCache
cache = SimpleTextFileCache()
init from url
from hilcat import RedisCache
cache = RedisCache(url='redis://localhost:6379')
init from host
from hilcat import RedisCache
cache = RedisCache(host='localhost', port=6579)
from hilcat import ElasticSearchCache
cache = ElasticSearchCache(hosts=['https://localhost:9200'])
from hilcat import SqliteCache, SqliteScopeConfig
cache = SqliteCache(database=db_file, scopes=[
SqliteScopeConfig(scope='a', uniq_column='id', columns=['id', 'name', 'comment', 'count'],
column_types={'count': 'int'}),
SqliteScopeConfig(scope='b', uniq_column='eid', columns=['eid', 'name', 'comment', 'status'])
])
from hilcat import PostgresqlCache, PostgresqlScopeConfig
cache = PostgresqlCache(database="postgresql://postgres:123@localhost:5432/hilcat_test", scopes=[
PostgresqlScopeConfig(scope='a', uniq_column='id', columns=['id', 'name', 'comment', 'count'],
column_types={'count': 'int'}),
# PostgresqlScopeConfig(scope='b', uniq_column='eid', columns=['eid', 'name', 'comment', 'status'])
])
from hilcat import MysqlCache, MysqlScopeConfig
cache = MysqlCache(connection=connection, scopes=[
MysqlScopeConfig(scope='a', uniq_column='id', columns=['id', 'name', 'comment', 'count'],
column_types={'id': 'varchar(50)', 'count': 'int'}),
MysqlScopeConfig(scope='b', uniq_column='eid', columns=['eid', 'name', 'comment', 'status'],
column_types={'eid': "int"})
])
Assume there is a cache named cache
.
Test if a key exists in cache for certain scope.
If key not exists, return default value.
value = cache.fetch('one', 1, scope='a')
cache.set('one', 1, scope='a')
Same as method set
, but return value may diff in some implements.
If key exists, just return value stored in cache; else if key not exists, calculate value and store to cache, the return value.
value = cache.get('one', lambda: 1, scope='a')
Delete value of given key for certain scope.
Get all scopes in the cache.
May not supported for some implements.
Get all keys for certain scope.
May not supported for some implements.
Load scope data from persistence storage.
Some implements may have no persistence storage, thus this method do nothing.
Save scope data to persistence storage.
Some implements may have no persistence storage, thus this method do nothing.
import collections
from hilcat import SqliteCache, SqliteScopeConfig
db_file = "decorator.db"
cache = SqliteCache(database=db_file, scopes=[
SqliteScopeConfig(scope='f1', uniq_column='x', columns=['y']),
SqliteScopeConfig(scope='f3', uniq_column='key', columns=['key', 'value'])
])
c1 = collections.Counter()
@cache(scope="f1")
def f1(x: int):
c1[x] += 1
return x + 1 + c1[x]
c2 = collections.Counter()
def f2(x: int):
c2[x] += 1
return x + 1 + c2[x]
def make_key(x: int, y: int):
return '-'.join(map(str, [x, y]))
c3 = collections.Counter()
@cache(scope="f3", make_key_func=make_key)
def f3(x: int, y: int):
c3[(x, y)] += 1
return {
"key": make_key(x, y),
"value": x + y + c3[(x, y)],
}
# with cache, same result
assert f1(1) == 3
assert f1(1) == 3
# without cache, different result
assert f2(1) == 3
assert f2(1) == 4
assert f3(1, 2) == {"key": "1-2", "value": 4}
assert f3(1, 2) == {"key": "1-2", "value": 4}