Development-only caching and mocking library for expensive Python functions
Project description
cacheow
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.
Project details
Release history Release notifications | RSS feed
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 cacheow-0.1.1.tar.gz.
File metadata
- Download URL: cacheow-0.1.1.tar.gz
- Upload date:
- Size: 37.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c181b6a8baef06abf97ab95331ea416bac8a48471eddd156f2932a1c8cc21034
|
|
| MD5 |
a45bc4c076609e23e19569ed727cb31e
|
|
| BLAKE2b-256 |
1b07efa6663cb84d2471b5a3588cfa61f818a5309244299d248f34386c9d3d13
|
File details
Details for the file cacheow-0.1.1-py3-none-any.whl.
File metadata
- Download URL: cacheow-0.1.1-py3-none-any.whl
- Upload date:
- Size: 28.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e68122b526c4ae7ac8ee62e5da58112484a66474c699616e9b97a0293cd845fa
|
|
| MD5 |
ce0a5cbabcdd8ecdda7dc74afe413ee3
|
|
| BLAKE2b-256 |
7e3f699ca564a7f84798020f56997879da50790379f149f92867f99ffe9984e8
|