core.cache

This module implements a cache that can be used to serve entire requests or cache the output of any function (as long it’s result can be stored in datastore). The intended use is to wrap functions that can be called from the outside (@exposed) with the @ResponseCache decorator. This will enable the cache provided in this module for that function, intercepting all calls to this function and serve a cached response instead of calling the function if possible. Authenticated users with “root” access can always bypass this cache by sending the X-Viur-Disable-Cache http Header along with their requests. Entities in this cache will expire if

  • Their TTL is exceeded

  • They’re explicitly removed from the cache by calling viur.core.cache.flushCache() using their path

  • A Datastore entity that has been accessed using db.get() from within the cached function has been modified

  • The wrapped function has run a query over a kind in which an entity has been added/edited/deleted

..Warning: As this cache is intended to be used with exposed functions, it will not only store the result of the

wrapped function, but will also store and restore the Content-Type http header. This can cause unexpected behaviour if it’s used to cache the result of non top-level functions, as calls to these functions now may cause this header to be rewritten.

Attributes

CACHE_KINDNAME

DEFAULT_COMPRESSION

Default compression (alias for zlib.Z_DEFAULT_COMPRESSION)

DEFAULT_SETTINGS

The global instance of DefaultSettings

Classes

UserSensitive

Signals wherever the output of the wrapped method depends on the current user.

BypassCache

ResponseCache

Decorator class to cache the result of the reponse.

Functions

flushCache([prefix, key, kind])

Flushes the cache. Its possible the flush only a part of the cache by specifying

Module Contents

core.cache.CACHE_KINDNAME: Final[str] = 'viur-cache'
class core.cache.UserSensitive

Bases: enum.IntEnum

Signals wherever the output of the wrapped method depends on the current user.

Initialize self. See help(type(self)) for accurate signature.

IGNORE

independent of wherever the user is a guest or known, all will get the same content.

GUEST_ONLY

cache only for guests, no cache will be performed if the user is logged-in.

BOTH

cache in two groups, one for guests and one for all users

INDIVIDUAL

cache the result of that function for each individual users separately.

class core.cache.BypassCache

Bases: tuple

reason
core.cache.DEFAULT_COMPRESSION = -1

Default compression (alias for zlib.Z_DEFAULT_COMPRESSION)

core.cache.DEFAULT_SETTINGS

The global instance of DefaultSettings

class core.cache.ResponseCache(*, urls=None, renderer=sentinel, user_sensitive=sentinel, language_sensitive=sentinel, evaluated_args=sentinel, max_cache_time=sentinel, compression_level=sentinel)

Bases: Generic[Args, Value]

Decorator class to cache the result of the reponse.

ResponseCache caches: - Normal 200 responses, regardless of the content-type

  • Including headers changed by the wrapped function

  • Redirects 3**

Parameters can control what and how long it should be cached, see the descriptions in __init__().

Example usage:

>>> from viur.core import exposed
>>> import datetime
>>> @exposed
>>> @ResponseCache(max_cache_time=datetime.timedelta(days=1))
>>> def index(self):
>>>     return f"This result was cached at {datetime.datetime.now()}"

Create a ResponseCache instance

Parameters:
  • urls (list[str] | tuple[str, Ellipsis] | None) – A list of urls for this function, for which the cache should be enabled. A method can have several urls (e.g. /page/view, /pdf/page/view or /pdf/seite/view), and it might should not be cached under all urls (e.g. /vi/page/view). If the parameter is omitted, the URL is ignored for the check and the call is saved in the cache (unless excluded by other parameters), regardless of the path via which the method was called.

  • renderer (list[str | Type] | tuple[str | Type, Ellipsis] | None) – This parameter can be used to specify render names (such as html, json) under which the result should be cached. The parameter can be used as an alternative to the url parameter, but can also be used in addition.

  • user_sensitive (UserSensitive) – Signals wherever the output of the wrapped method depends on the current user. Look at UserSensitive for parameter descriptions.

  • language_sensitive (bool) – If True, signals that the output of the wrapped method should be cached separately for each language (because it’s translated).

  • evaluated_args (list[str] | tuple[str, Ellipsis]) – List of argument name having influence to the output generated by that wrapped method. This list must be complete! Parameters not named here are ignored! Warning: Double-check this list! F.e. if that function generates a list of entries and you miss the parameter “order” here, it would be impossible to sort the list. It would always have the ordering it had when the cache-entry was created. If the wrapped method use variable positional arguments (*args) or variable keyword arguments (**kwargs) you can include “arg” and/or “kwargs” to this list to accept all variable arguments that are passed by these. If only certain parameters of **kwargs should be considered add the key like it would be a explicit positional or keyword argument.

  • max_cache_time (datetime.timedelta | None) – Specifies the maximum time an entry stays in the cache. Note: It’s not erased from the database after that time, but it won’t be served anymore. If None, the cache stays valid forever (until manually erased by calling flushCache).

  • compression_level (int) – Large pages may be too big for the datastore (max. approx. 1 MB, but including meta data). If this parameter is activated, the page is compressed before it is saved in the entity. Possible values for setting the compression level are the numbers 0 - 9. Compression is deactivated with None. See also :param:`DEFAULT_SETTINGS.raise_too_large`.

__slots__ = ('compression_level', 'evaluated_args', 'language_sensitive', 'max_cache_time', 'renderer',...
REDIRECT_FLAG = '<<REDIRECT>>'

Flag used as content-type to signal that this is a cached redirect instead of a normal response.

urls = None
renderer: list[str | Type] | tuple[str | Type, Ellipsis] | None
user_sensitive: UserSensitive
language_sensitive: bool
evaluated_args: list[str] | tuple[str, Ellipsis]
compression_level: int | None
__call__(func)

Does the actual work of wrapping a callable @exposed method and return a internal wrapper.

Parameters:

func (Callable[Args, Value])

Return type:

Value

get_args(func, path, args, kwargs)

Create a argument dict to build the cache key.

In addition to the arguments to be considered (evaluated_args) of the request, parameters are also formed from the other options of this class.

Parameters:
  • func (Callable)

  • path (str)

  • args (tuple)

  • kwargs (dict)

Return type:

dict[str, Any] | BypassCache

get_string_from_args(args)

Create a string key for the cache entity

The parameters are sorted by key, and return as sha512 hash.

Parameters:

args (dict[str, Any] | BypassCache) – The result of get_args()

Return type:

str | BypassCache

__repr__()

Representation of this class

Return type:

str

core.cache.flushCache(prefix=None, key=None, kind=None)

Flushes the cache. Its possible the flush only a part of the cache by specifying the path-prefix. The path is equal to the url that caused it to be cached (eg /page/view) and must be one listed in the ‘url’ param of ResponseCache.

Parameters:
  • prefix (str) – Path or prefix that should be flushed.

  • key (viur.core.db.Key | None) – Flush all cache entries which may contain this key. Also flushes entries which executed a query over that kind.

  • kind (str | None) – Flush all cache entries which executed a query over that kind.

Examples:
  • “/” would flush the main page (and only that),

  • “/” everything from the cache, “/page/” everything from the page-module (default render),

  • and “/page/view/*” only that specific subset of the page-module.