Decorator de cache para funções e métodos Python, com backends InMemory e SQLite, TTL configurável, hash estável de parâmetros e serialização segura.
Project description
PyCacheable
A cache decorator for Python methods and functions with in-memory and SQLite backends — automatic serialization with JSON-first + pickle fallback strategy, stable parameter hashing, instance/state support, and pluggable architecture.
Problem
In many Python applications, there are methods that:
- make repeated queries to databases or external APIs;
- receive the same parameters multiple times;
- repeat expensive CPU or I/O work;
- in short: do the same work more than once, wasting time and resources.
Without a caching mechanism, each call results in complete re-execution, leading to high latencies, extra load on databases/services, and degraded user experience.
Solution
The library provides:
- A
@cacheable(...)decorator that wraps functions or methods, generates a stable key from parameters (canonical serialization + sha256); - Backend support:
InMemoryCache: volatile in-memory cache with LRU + TTL.SQLiteCache: persistent disk cache (SQLite) with TTL, ideal for between executions or processes;
- Clear flow logs: HIT / MISS / EXPIRE — allowing you to understand if the cache is working;
- Safe serialization:
- JSON-first for simple structures (safe, no RCE risk)
- Pickle fallback for complex objects (flexible)
- Helper methods:
.cache_clear(),.cache_info()on wrapper for inspection/maintenance;
How to use
from src.pycacheable.backend_sqlite import SQLiteCache
from src.pycacheable.backend_memory import InMemoryCache
from src.pycacheable.cacheable import cacheable
mem = InMemoryCache(max_entries=512)
disk = SQLiteCache(path="./.cache/myapp.sqlite")
class Repo:
@cacheable(ttl=60, backend=mem)
def get_user(self, user_id: int) -> dict:
# expensive database query
return {"user_id": user_id, "name": f"user{user_id}"}
@cacheable(ttl=300, backend=disk)
def get_orders(self, user_id: int, status: str = "open") -> list:
return [{"order_id": 101, "user_id": user_id, "status": status}]
repo = Repo()
u1 = repo.get_user(42) # MISS → executes query
u2 = repo.get_user(42) # HIT → returns cache, query not executed
Benefits
- Lower latency on repeated calls (hit almost instant).
- Lower load on database/service, less repeated I/O.
- Local persistence (via SQLite) enables cache between restarts/processes.
- Transparent to function users — just apply the decorator.
- Logs and metrics help monitor real impact.
- Safe serialization with JSON-first (no risk of arbitrary code execution).
When to use
- Functions/methods with deterministic results (same parameters → same result)
- Idempotent and repeated queries
- Expensive CPU or I/O calculations
- Scenarios where latency matters and repetition should be avoided
Considerations and limits
- Cache avoids re-executions only if the method parameters are the same and serializable.
- If the method depends on mutable state outside parameters (e.g.,
self.some_state), you should useinclude_self=Trueor customkey_fn. - TTL is used for expiration — results may become "stale" if parameters or context change without changing the key.
- Although SQLite backend is persistent, it does not replace a distributed cache (e.g., Redis) in multi-process/semi-distributed scenarios.
- Pickle fallback maintains compatibility with complex objects, but use with trusted data.
Benchmarks
See real results measuring MISS vs HIT:
| Backend | MISS (s) | HIT (s) | Speedup | Calls |
|---|---|---|---|---|
| RAW | 0.4410 | — | — | — |
| InMemory | 0.4043 | 0.000043 | ~9,494x | 1 |
| SQLite | 0.4001 | 0.000763 | ~524x | 1 |
Cache reduces execution time from ~0.4 s to ~0.00004 s — a speedup over 9,000×.
Next steps
- Support for
async deffunctions (awaitable decorator) - Redis / LMDB backend for distributed scenarios
- Metrics and Prometheus integration
License
MIT License — see the LICENSE file for details.
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
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pycacheable-0.2.1.tar.gz.
File metadata
- Download URL: pycacheable-0.2.1.tar.gz
- Upload date:
- Size: 15.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6d68a059aead024111508d18a126db2907e74b411650960e0149010252cc7de8
|
|
| MD5 |
6fbc98dd0443493df2f411bff6ca01bb
|
|
| BLAKE2b-256 |
1dd9b6326fefdca3de0a10a8311a2479a070d012e21f09cb44e9e9d2f366a4bb
|
Provenance
The following attestation bundles were made for pycacheable-0.2.1.tar.gz:
Publisher:
publish.yml on leonardopinho/pycacheable
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pycacheable-0.2.1.tar.gz -
Subject digest:
6d68a059aead024111508d18a126db2907e74b411650960e0149010252cc7de8 - Sigstore transparency entry: 2194658030
- Sigstore integration time:
-
Permalink:
leonardopinho/pycacheable@4c69a274ac943118a167c4b19be27a82563200f9 -
Branch / Tag:
refs/tags/v0.2.1 - Owner: https://github.com/leonardopinho
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@4c69a274ac943118a167c4b19be27a82563200f9 -
Trigger Event:
push
-
Statement type:
File details
Details for the file pycacheable-0.2.1-py3-none-any.whl.
File metadata
- Download URL: pycacheable-0.2.1-py3-none-any.whl
- Upload date:
- Size: 12.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
42aa7d547c535e8c15249bc790b4b26a4aa34c225d829fec4e9dacdbb110e338
|
|
| MD5 |
41616b10eb1c80202e07463389f28cda
|
|
| BLAKE2b-256 |
c644f70c7b969ff2b38ab92d2db1528732d3c30c11d76ca4602f662fd7e265f0
|
Provenance
The following attestation bundles were made for pycacheable-0.2.1-py3-none-any.whl:
Publisher:
publish.yml on leonardopinho/pycacheable
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pycacheable-0.2.1-py3-none-any.whl -
Subject digest:
42aa7d547c535e8c15249bc790b4b26a4aa34c225d829fec4e9dacdbb110e338 - Sigstore transparency entry: 2194658045
- Sigstore integration time:
-
Permalink:
leonardopinho/pycacheable@4c69a274ac943118a167c4b19be27a82563200f9 -
Branch / Tag:
refs/tags/v0.2.1 - Owner: https://github.com/leonardopinho
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@4c69a274ac943118a167c4b19be27a82563200f9 -
Trigger Event:
push
-
Statement type: