Skip to main content

Minimal on-disk cache decorator: DataFrame→Parquet (else pickle); others→pickle; top-level containers.

Project description

dfcached

PyPI Python Versions License: MIT CI

Disk‑backed function result cache for pandas‑heavy workflows.

  • Zero‑config: @persist_cache() works out of the box.
  • Smart I/O: DataFrames → Parquet (fallback to pickle); other objects → pickle.
  • Integrity by default: per‑file sha256 + size; strict verification on read.
  • Stable keys: kwargs order canonicalized; optional exclusions and custom key_fn.

Install

pip install dfcached
# Optional: for Parquet I/O (recommended)
pip install pyarrow  # or fastparquet

Python 3.11–3.12 supported.


Quick start

from dfcached import persist_cache
import pandas as pd

@persist_cache()  # strict_integrity=True, write/verify_checksums=True by default
def build(n: int) -> pd.DataFrame:
    return pd.DataFrame({"x": range(n)})

cold = build(10)
hot  = build(10)  # loaded from cache
assert cold.equals(hot)

Mixed containers

dfcached understands tuples, lists and dicts. Any element that is a pd.DataFrame is stored as Parquet (fallback to pickle if Parquet fails); everything else is pickled.

@persist_cache()
def compute(n: int):
    df = pd.DataFrame({"x": range(n)})
    return (
        df,
        ["meta", 1],
        {"df": df, "sum": df["x"].sum()},
    )

_ = compute(5)   # writes cache
_ = compute(5)   # hot hit

Parameters

@persist_cache(
  cache_dir: str | Path = ".dfcached_cache",
  *,
  key_fn: Callable[[tuple, dict], str] | None = None,
  version: str | None = None,
  refresh: bool = False,
  exclude_from_key: Iterable[str] | None = None,
  lock_timeout: float = 10.0,
  lock_sleep: float = 0.02,
  canonicalize_kwargs: bool = True,
  write_checksums: bool = True,
  verify_checksums: bool = True,
  strict_integrity: bool = True,
)
Parameter Default Meaning
cache_dir .dfcached_cache Root directory for on‑disk cache.
version None Optional version namespace. Bump to invalidate old keys.
refresh False Force recompute even if a cache hit exists.
exclude_from_key None Iterable of kwarg names excluded from the key (e.g. verbose).
canonicalize_kwargs True Make kwargs order irrelevant for the key.
key_fn None Custom key generator taking (args, kwargs) and returning a hex string.
write_checksums True Write sha256 and file size per leaf.
verify_checksums True Verify sha256/size on load.
strict_integrity True On mismatch, raise with a remediation message (don’t read corrupted files).
lock_timeout / lock_sleep 10.0 / 0.02 Directory lock to prevent duplicate work under concurrency.

Integrity & corruption handling

By default, each cached file stores sha256 and size. On load, they’re verified — if a file was modified or corrupted, you get a clear error pointing to the exact path and the manifest to edit/remove.

To bypass temporarily and recompute on mismatch:

@persist_cache(strict_integrity=False)

Tip: deleting the single key directory is usually best (see layout below).


Cache layout

.dfcached_cache/
  <func qualname>/
    <key hex>/
      manifest.json             # container + leaf entries (kind, file, sha256, size)
      0.parquet|0.pkl           # DataFrame or non‑DF element
      1.pkl
      ...

Utilities

from dfcached.utils import clear, read_manifest, iter_leaf_entries, count_key_dirs

# Remove all cache
clear(".dfcached_cache")

# Remove all keys for a function
clear(".dfcached_cache", func_qualname="my_mod.my_func")

# Inspect a manifest
manifest, meta = read_manifest(".dfcached_cache")
for leaf in iter_leaf_entries(meta):
    print(leaf["kind"], leaf["file"], leaf.get("sha256"))

Key semantics

  • Keys are based on a pickle of (args, kwargs) plus version and the function qualname.
  • With canonicalize_kwargs=True, kwargs order is ignored.
  • Use exclude_from_key to omit non‑semantic flags (e.g., logging, progress).
  • For special cases (e.g., large non‑picklable args), supply a custom key_fn.

Note: pickled argument bytes can differ across Python versions or object implementations. If you need cross‑env key stability, provide a custom key_fn.


Concurrency

A lightweight directory lock avoids duplicate work when the same key is computed concurrently. Tune with lock_timeout and lock_sleep.


Development

poetry install --with dev
poetry run ruff check src tests
poetry run mypy src tests
poetry run pytest -q

Releasing is automated via GitHub Actions (Trusted Publishing). RC tags (vX.Y.ZrcN) publish to TestPyPI; final tags (vX.Y.Z) publish to PyPI.


License

MIT © Iurii Zhakun

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

dfcached-0.3.0.tar.gz (7.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

dfcached-0.3.0-py3-none-any.whl (10.6 kB view details)

Uploaded Python 3

File details

Details for the file dfcached-0.3.0.tar.gz.

File metadata

  • Download URL: dfcached-0.3.0.tar.gz
  • Upload date:
  • Size: 7.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for dfcached-0.3.0.tar.gz
Algorithm Hash digest
SHA256 5d3d3de1a0237cc7ccd9a3a1ef1709f60ea82ab9c4ea6901e847c7a8f4f98618
MD5 b5b3f45febe08cedbfc2457ea9dcda0e
BLAKE2b-256 7a22d825ddd27b317683d830239d34dfe5f6d0e763db220b46b3ca9262d42e80

See more details on using hashes here.

Provenance

The following attestation bundles were made for dfcached-0.3.0.tar.gz:

Publisher: workflow.yml on IuriiZhakun/dfcached

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file dfcached-0.3.0-py3-none-any.whl.

File metadata

  • Download URL: dfcached-0.3.0-py3-none-any.whl
  • Upload date:
  • Size: 10.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for dfcached-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 93ac4987bb0134dfdd5be138a3bf4f11ff7ed91324de996a2480ab8462aeebaf
MD5 a68fceb3ef9537e7405331c6ac95d550
BLAKE2b-256 53a9e7596e62eb2d41f30637908e979ffd6584848b9886d14284f829ac4b46b2

See more details on using hashes here.

Provenance

The following attestation bundles were made for dfcached-0.3.0-py3-none-any.whl:

Publisher: workflow.yml on IuriiZhakun/dfcached

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

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