Skip to main content

cacheow

PyPI version Python versions

Development-only caching and mocking for expensive Python functions. Add one decorator, then control runtime behavior through persisted disk storage and a small web UI.

Development use only. Do not use cacheow in production. When disabled, the decorator is a no-op with near-zero overhead.

Requirements

  • Python 3.13+

Installation

pip install cacheow

Quick start

Enable cacheow with an environment variable:

export CACHEOW_ENABLE=1
from cacheow import cacheow

@cacheow()
def expensive_function(x: int) -> int:
    return x * x

expensive_function(3)  # recorded to disk in default mode

When CACHEOW_ENABLE is not 1, @cacheow() returns the original function unchanged.

A control panel starts automatically at http://127.0.0.1:8765/ (configurable via environment variables below).

Runtime modes

Each decorated function has one mode, persisted in SQLite:

Mode Behavior
default Call the function normally; persist every outcome to disk. Never read cache.
cache Return cached outcomes matching call arguments; call the function on miss.
mock Never call the original; replay stored outcomes (weighted random by default).

Always set mode using function.cacheow_function_id on the wrapped function. Do not look up functions by name in SQLite; stale registrations can remain after source edits.

Modes can also be changed via the web UI or JSON API (see below).

Complete example

Save as cacheow_example.py and run with python cacheow_example.py:

import asyncio
import os
import time

os.environ.setdefault("CACHEOW_ENABLE", "1")
os.environ.setdefault("CACHEOW_DATA_DIR", ".cacheow")
os.environ.setdefault("CACHEOW_START_SERVER", "1")

from cacheow import cacheow
from cacheow.manager import get_manager


@cacheow()
def sync_compute(n: int) -> int:
    print(f"computing {n}")
    time.sleep(0.1)
    return n * n


@cacheow()
async def async_compute(n: int) -> int:
    print(f"async computing {n}")
    await asyncio.sleep(0.1)
    return n + 10


def main() -> None:
    print("=== Default mode: record outcomes ===")
    print("sync_compute(3) =", sync_compute(3))
    print("async_compute(5) =", asyncio.run(async_compute(5)))

    manager = get_manager()
    assert manager is not None
    fn_id: str = sync_compute.cacheow_function_id  # type: ignore[attr-defined]

    print("\n=== Cache mode: replay from disk ===")
    manager.db.set_mode(fn_id, "cache")
    start = time.perf_counter()
    print(
        "sync_compute(3) cached =",
        sync_compute(3),
        f"in {(time.perf_counter() - start) * 1000:.1f}ms",
    )

    print("\n=== Mock mode: never call original ===")
    manager.db.set_mode(fn_id, "mock")
    print("sync_compute(999) mocked =", sync_compute(999))

    host = manager.settings.server_host
    port = manager.settings.server_port
    print(f"\nControl panel: http://{host}:{port}/")
    print(f"Data directory: {manager.settings.data_dir}")


if __name__ == "__main__":
    main()

Expected output (approximate):

=== Default mode: record outcomes ===
computing 3
sync_compute(3) = 9
async computing 5
async_compute(5) = 15

=== Cache mode: replay from disk ===
sync_compute(3) cached = 9 in 0.5ms

=== Mock mode: never call original ===
sync_compute(999) mocked = 9

Control panel: http://127.0.0.1:8765/
Data directory: /path/to/.cacheow

In cache and mock modes, computing ... is not printed — the original function is not called.

Environment variables

Variable Default Description
CACHEOW_ENABLE unset Set to 1 to enable cacheow
CACHEOW_DATA_DIR .cacheow Persistence directory
CACHEOW_SERVER_HOST 127.0.0.1 HTTP server bind address
CACHEOW_SERVER_PORT 8765 HTTP server port
CACHEOW_START_SERVER 1 Set to 0 to disable auto-start

Supported function types

  • Sync and async functions
  • Sync and async generators
  • Functions that raise exceptions
  • Arbitrary return types (JSON-first serialization with pickle fallback)

On-disk layout

.cacheow/
  cacheow.db              # SQLite: metadata, modes, stats, outcome index
  functions/
    <function-id>/
      outcomes/
        <outcome-id>.json # Human-inspectable outcome payloads

SQLite stores registration, modes, configuration, stats, and an index of outcome files. JSON files store the actual return values, exceptions, and generator sequences so outcomes stay easy to inspect, diff, and edit manually.

HTTP API

Endpoint Description
GET /api/functions List all decorated functions
GET /api/functions/{id} Function detail, outcomes, stats
POST /api/functions/{id}/mode Set mode (default, cache, mock)
POST /api/functions/{id}/latency Set artificial delay (ms)
POST /api/functions/{id}/mock-outcomes Configure weighted mock selection
POST /api/functions/{id}/outcomes/manual Add manual return/exception outcome
POST /api/functions/{id}/rebuild-index Rebuild outcome index from disk

HTML UI: / and /ui/functions/{id}.

Safety

In default mode, persistence or stats failures log a warning and never prevent the wrapped function from returning its result. In cache mode, cache read failures fall back to executing the original function when safe.

Public API

from cacheow import cacheow

That is the intended user-facing entry point. Wrapped functions expose cacheow_function_id for runtime control.

Metadata

Release files for cacheow 0.1.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for cacheow 0.1.1
File Size Uploaded
cacheow-0.1.1.tar.gz 37.5 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for cacheow 0.1.1
File Interpreter ABI Platform
cacheow-0.1.1-py3-none-any.whl Python 3 none any Details

Total release size: 65.8 kB

Release files / cacheow-0.1.1.tar.gz

Download URL cacheow-0.1.1.tar.gz
Size 37.5 kB
Tags Source
SHA-256 checksum
How to use checksums
c181b6a8baef06abf97ab95331ea416bac8a48471eddd156f2932a1c8cc21034
BLAKE2b-256 checksum
How to use checksums
1b07efa6663cb84d2471b5a3588cfa61f818a5309244299d248f34386c9d3d13
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.13

Release files / cacheow-0.1.1-py3-none-any.whl

Download URL cacheow-0.1.1-py3-none-any.whl
Size 28.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
e68122b526c4ae7ac8ee62e5da58112484a66474c699616e9b97a0293cd845fa
BLAKE2b-256 checksum
How to use checksums
7e3f699ca564a7f84798020f56997879da50790379f149f92867f99ffe9984e8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.13

Release history Release notifications | RSS feed

This release

0.1.1 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page