Skip to main content

Caching results of functions in Python

Project description

https://travis-ci.com/scidam/cachepy.svg?branch=master

A caching toolset for Python. It is tested for both Python 2.7.x and 3.4+ (<3.10).

Features

  • Memory-based and file-based caches;

  • Ability to set the TTL (time-to-live) and NOC (the number of calls) on caches;

  • Encryption of the cached data (symmetric encryption algorithm (RSA) is used);

  • LFU (least frequently used) and MFU (most frequently used) cache-clearing strategies;

  • caches of limited size;

Notes

  • Encryption functionality requires the PyCryptodome package to be installed;

  • File-based caches save the cached data in a file; files with cached data should be cleaned up manually, if needed.

Examples

from cachepy import *

mycache = Cache()
# save the cached data to memory without encryption

@mycache
def my_heavy_function(x):
    '''Performs heavy computations'''

    print('Hi, I was invoked...')
    return x**2

my_heavy_function(2)
# "Hi, I was invoked..." will be printed to stdout only once
# return 4

my_heavy_function(2)
# return 4

To store data to a file, one needs to initialize a decorator, as follows:

# create cache-to-file decorator
filecache = FileCache('mycache')  # mycache.dat file will be created;
# `.dat` extension is appended automatically to the filename
# (depends on the shelve module implementation);

Its behavior is the same as a memory-based one, but all cached data is stored in the specified file.

One can set up time-to-live (TTL) and/or maximum number of calls (NOC) for the cached data when the decorator is initialized:

import time
from cachepy import *

cache_with_ttl = Cache(ttl=2)  # ttl given in seconds

@cache_with_ttl
def my_heavy_function(x):
    '''Performs heavy computations'''

    print('Hi, I was invoked...')
    return x**2

my_heavy_function(3)
# Hi, I was invoked... will be printed
# return 9
my_heavy_function(3)
# 'Hi, I was invoked ...' will not be printed
# return 9
time.sleep(2)
my_heavy_function(3)
# 'Hi, I was invoked ...' will be printed again
# return 9
cache_with_noc = Cache(noc=2)  # the number-of-calls: noc = 2

@cache_with_noc
def my_heavy_function(x):
    '''Performs heavy computations'''

    print('Hi, I was invoked...')
    return x**2

my_heavy_function(3)
my_heavy_function(3) # 'Hi, I was invoked ...' will not be printed
my_heavy_function(3) # 'Hi, I was invoked ...' will be printed again

It is easy to use both NOC and TTL arguments when defining a caching decorator:

cache_with_noc_ttl = Cache(noc=2, ttl=1)

@cache_with_noc_ttl
def my_heavy_function(x):
    '''Performs heavy computations'''

    print('Hi, I was invoked...')
    return x**2

my_heavy_function(3)
my_heavy_function(3)  # 'Hi, I was invoked ...' will not be printed
my_heavy_function(3)  # 'Hi, I was invoked ...' will be printed (noc is
# reached, recompute the func value)
time.sleep(2)  # get ttl expired
my_heavy_function(3) # 'Hi, I was invoked ...' will be printed again

One can encrypt the cached data by providing a non-empty key argument as a password (RSA encryption algorithm is used):

cache_to_file_ttl_noc = FileCache('mycache',
                                  noc=2, ttl = 2,
                                  key='mypassword')

@cache_to_file_ttl_noc
def my_heavy_function(x):
    '''Performs heavy computations'''

    print('Hi, I was invoked...')
    return x**2

my_heavy_function(2) # 'Hi, I was invoked...' will be printed
my_heavy_function(2) # 'Hi, I was invoked...' will not be printed

When my_heavy_function is decorated by cache_to_file_ttl_noc, as shown in the example above, the value 2**2 = 4 will be computed and the result of the computation will be stored in the file named mycache.dat. Along with the result of the computation, additional information will be stored in the file mycache.dat. The additional information includes: 1) the result’s expiration time (computed from the TTL), 2) NOC and 3) the number of already performed calls of the function being decorated (my_heavy_function).

Encryption is available only if PyCryptodome package is installed and the key parameter (a non-empty string representing the password) is passed to the cache constructor. It also could work with the old PyCrypto package.

If you passed the non-empty key parameter to the cache constructor but PyCryptodome was not found, a special warning would be raised in this case (“PyCryptodome not installed. Data will not be encrypted”) and the cache would work as usual but without encryption functionality.

Caching with limitations

Standard cache constructors are used to initialize caches of unlimited capacity. There are also caches of limited capacity. Such caches are initialized by constructors named LimitedCache and LimitedFileCache. These constructors have additional parameters cache_size (the maximum number of items stored in the cache) and algorithm (cache-clearing algorithm). Available algorithm values are lfu (default, which stands for least frequently used) and mfu (most frequently used). When algorithm=’lfu’, then the least frequently used item is removed from the cache, if it is exhausted. In case of algorithm=’mfu’, everything behaves the same way, with the only difference being that the most frequently used item is removed.

Testing

python -m  cachepy.test

TODO

  • Writing backend for redis server

Log list

  • Version 1.2 (testing compatibility with Python 3.8 - 3.9)

  • Version 1.1

  • Version 1.0 (broken installation via pip/pipenv)

  • Version 0.1
    • initial release

Author

Dmitry Kislov <kislov@easydan.com>

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

cachepy-1.2.tar.gz (14.8 kB view details)

Uploaded Source

Built Distribution

cachepy-1.2-py3-none-any.whl (20.2 kB view details)

Uploaded Python 3

File details

Details for the file cachepy-1.2.tar.gz.

File metadata

  • Download URL: cachepy-1.2.tar.gz
  • Upload date:
  • Size: 14.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.4.1 importlib_metadata/3.10.1 pkginfo/1.7.0 requests/2.25.1 requests-toolbelt/0.9.1 tqdm/4.60.0 CPython/3.6.10

File hashes

Hashes for cachepy-1.2.tar.gz
Algorithm Hash digest
SHA256 6d4a3fa9ed3fb157bec556b4b6a5d5e3942af2aa4efdf45e13eb343e39a04509
MD5 dd44cf4c2c83c9809d0fac00fcc0f84d
BLAKE2b-256 16fca9eaf23d7c05e1797898c5f926a2dd5ed362fd02c70b3551444b96dbee43

See more details on using hashes here.

File details

Details for the file cachepy-1.2-py3-none-any.whl.

File metadata

  • Download URL: cachepy-1.2-py3-none-any.whl
  • Upload date:
  • Size: 20.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.4.1 importlib_metadata/3.10.1 pkginfo/1.7.0 requests/2.25.1 requests-toolbelt/0.9.1 tqdm/4.60.0 CPython/3.6.10

File hashes

Hashes for cachepy-1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 680c042fbf5e2b154a2e54bf335892c0612aa64b1368538b160ec9510d796e19
MD5 da790db2ae9000e8fb61442b87905e3b
BLAKE2b-256 088c90276f25df792af41ba630dfe418198aff19ddb60fd6314bb2de8fe71956

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page