score.kvcache¶
Introduction¶
This module allows storing python objects in key-value storages. It can be used, for example, to cache frequently used data to avoid calling APIs too often or to avoid exceeding the number of allowed calls to a service. It should not be used to persist data, since it cannot guarantee that data is retained, even if the specified expiration is not reached. Where and how long the data is stored depends on the configurable backend.
How it works¶
This module uses configurable cache containers to store values with different lifetimes and generators. A cache value generator is a function, that needs to be configured or registered with the container. The cache container will invoke this cache value generator to obtain the matching cache value for the requested key.
If you want to configure your generator, have a look at the
Configuration. The registration of a
cache value generator can be done by calling the container’s
ConfiguredKvCacheModule.register_generator()
method:
import score.kvcache
def greeting_generator(name):
print('Generating the value for key "%s".' % name)
return 'Hello %s!' % name
kvcache = score.kvcache.init({
'backend.variable': 'score.kvcache.backend.VariableCache',
'container.greeting.backend': 'variable',
})
kvcache.register_generator('greeting', greeting_generator)
print(kvcache['greeting']['Peter'])
print(kvcache['greeting']['Peter'])
print(kvcache['greeting']['William'])
The output will be:
Generating the value for key "Peter".
Hello Peter!
Hello Peter!
Generating the value for key "William".
Hello William!
In this scenario, the configured kvcache will operate only on one container called greeting. The container is associated with the backend called variable, which is a dummy backend storing values in a python dict.
The first time the container is accessed with the key Peter, the container
will consult its backend and catch a NotFound
Exception. Since it was
not possible to retrieve the value from cache, it will invoke the registered
generator to create the desired value (“Hello Peter!”).
The backend is then instructed to store the value, having it available the next time the container is requested to retrieve the exact same key.
If we had chosen a more elaborate backend, we could have even configured an
expiration time
for the values in
our container.
Configuration¶
-
score.kvcache.
init
(confdict)[source]¶ Initializes this module according to our module initialization guidelines with the following configuration keys:
- container
The cache container configuration. A container defines a name, a backend and optionally a generator and an expire. The configuration key for a container starts with
container
followed by the name and the configuration keys for the container.For example, the following configuration:
container.greeter.backend = score.kvcache.backend.FileCache container.greeter.backend.path = /tmp/greeter.sqlite3 container.greeter.generator = dotted.path.to.greeting_generator container.greeter.expire = 1m
The Backend config will be passed to
score.init.init_object()
. Have a look at the configurable backend’s constructor parameters for further information about the backend’s configurable keys.To make life easier for a huge set of container configurations, we serve the possibility to configure backend aliases that will replace the container’s backend config if the name matches.
For example:
backend.example_filecache = score.kvcache.backend.FileCache backend.example_filecache.path = /tmp/filecache.sqlite3 container.greeter.backend = example_filecache container.greeter.generator = dotted.path.to.greeting_generator container.greeter.expire = 1m container.counter.backend = example_filecache container.counter.generator = dotted.path.to.counting_generator container.counter.expire = 30 seconds
-
class
score.kvcache.
ConfiguredKvCacheModule
(containers)[source]¶ This module’s
configuration object
.-
containers
¶ A dictionary containing all configured
CacheContainer
. The keys of the dictionary represent the container names.
-
__getitem__
(container)[source]¶ Gets a
Cachecontainer
for given name.
-
register_generator
(container, generator)[source]¶ Registers the generator to call if the cache is invalid.
-
create_container
(container, *, exist_ok=False)[source]¶ Creates a container with given name and a
VariableCache
and adds it to the configuredcontainers
. dictionary. Will raise aContainerAlreadyConfigured
if exist_ok=False and the container is already configured.
-
-
class
score.kvcache.
CacheContainer
(name, backend, expire=None)[source]¶ A cache container to wrap key-value pairs.
-
name
¶ The container name.
-
expire
¶ The expire parsed by
score.init.parse_time_interval()
. May beNone
.
-
generator
¶ The generator registered by
ConfiguredKvCacheModule.register_generator()
. The argument of the generator represents the key of the cache item.
-
-
class
score.kvcache.backend.
Backend
[source]¶ -
store
(container, key, value, expire=None)[source]¶ Stores a value for given container name and key with given expire.
-
-
class
score.kvcache.
ContainerAlreadyConfigured
[source]¶ Thrown while trying to create a cache container that already exists.
Ready-to-use Backends¶
-
class
score.kvcache.backend.
VariableCache
[source]¶ This backend implementation caches values in a variable. Note, that the expire is restricted to the process’s lifetime.
-
class
score.kvcache.backend.
FileCache
(path)[source]¶ This backend implementation caches values in a sqlite3 database with given path.
-
class
score.kvcache.backend.
SQLAlchemyCache
(**confdict)[source]¶ This backend implementation caches values in a database supported by sqlalchemy.
-
confdict
¶ The sqlalchemy configuration dictionary. All configuration keys must start with sqlalchemy. The dictionary will be passed to
sqlalchemy.engine_from_config()
, which in turn callssqlalchemy.create_engine()
with these configuration values as keyword arguments. Usually the following is sufficient:sqlalchemy.url = postgresql://dbuser@localhost/dbname
-