Sitelet https://github.com/kitsuyui/cachepot
Skip to content

cachepot

PyPI - Python Version PyPI PyPI - Downloads Lint and Test Python Coverage License

Yet another Python cache library. This has Python 3 typing hints.

Installation

$ pip install cachepot

Usage

>>> from cachepot import CacheStore, FileSystemCacheBackend
>>> from cachepot.serializer.pickle import PickleSerializer
>>> store = CacheStore(
...     namespace='testing',
...     key_serializer=PickleSerializer(),
...     value_serializer=PickleSerializer(),
...     backend=FileSystemCacheBackend('/tmp'),
...     default_expire_seconds=3600,
... )
>>> store.put({'some': 'key'}, {'some': 'value'})
>>> store.get({'some': 'key'})
{'some': 'value'}
>>> store.put({'some': 'short expiring key'}, {'some': 'value'}, expire_seconds=10)
>>> store.delete_expired()
0

delete_expired() returns the number of entries removed when the backend can observe that count. Redis handles TTL expiry server-side, so its backend returns None when the deleted-entry count is unknown. SQLite also opportunistically removes expired rows during later writes, while delete_expired() remains available when you want to force a cleanup cycle.

Security note: PickleSerializer uses Python's pickle module, which can execute arbitrary code during deserialization. The serializer is intentionally not exported from cachepot's top-level namespace. Import it explicitly from cachepot.serializer.pickle only when the cache backend storage is fully under your control and trusted. For untrusted environments, prefer JSONSerializer instead.

Proxy method

result = store.proxy(some_func)(some_args, cache_key=some_arg)

is the equivalent of

result = store.get(some_arg)
if result is None:
    result = some_func(some_args)
    store.put(some_arg, result)

In short, this works as proxy. This helps to make codes straight forward. cache_key and expire_seconds are keyword-only arguments of the proxy itself, not of the proxied function. store.proxy(...) raises TypeError at proxy creation time if the proxied function declares a parameter named cache_key or expire_seconds, because those names are reserved for the proxy.

When a proxied cache write fails, cachepot keeps returning the computed result, emits a CachepotWarning, logs the failure on the cachepot.store logger, and increments store.cache_write_failures. This lets applications forward failures to their existing logging or metrics pipeline without giving up graceful degradation.

Core idea

Serializers convert python objects into bytes. Backends save/load bytes. So serializers and backends are independent. CacheStore is the facade of them.

Backends now enforce a finite per-entry size contract by default: max_entry_bytes=8 * 1024 * 1024 (8 MiB). Entries larger than that are rejected on save(), and load() checks the backend-side size before materializing the payload into process memory. You can override the limit per backend instance when your application has a different budget.

  • Python3 typing supports
  • namespaces
  • Proxy method
  • Expired entry cleanup

Features

Serializers

And more serializers you can define.

Backends

Of course you can define own backend.

Development

This repository uses lefthook to run the same checks as CI locally, so problems surface before they reach CI.

# Install dependencies
uv sync

# Install the Git hooks (once; requires lefthook on your PATH)
lefthook install

Once installed, the hooks run automatically:

  • pre-commit: uv run poe check
  • pre-push: uv run poe check and uv run poe test

You can also run the checks manually:

uv run poe check
uv run poe test

CI still runs the full matrix (see .github/workflows/); the hooks only bring that feedback earlier on your machine.

LICENSE

The 3-Clause BSD License. See also LICENSE file.

About

Yet another Python cache library. This has Python 3 typing hints.

Resources

Code of conduct

Contributing

Security policy

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages