or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

backend-cores.mdcache-management.mdcore-decorator.mdglobal-configuration.mdindex.md

core-decorator.mddocs/

0

# Core Caching Decorator

1

2

The `cachier` decorator is the main interface for adding persistent caching to Python functions. It provides comprehensive memoization with multiple backend support, configurable expiration, and advanced features like stale-aware caching and background refresh.

3

4

## Capabilities

5

6

### Basic Caching

7

8

Simple persistent caching with default pickle backend:

9

10

```python { .api }

11

def cachier(

12

hash_func: Optional[HashFunc] = None,

13

hash_params: Optional[HashFunc] = None, # Deprecated

14

backend: Optional[Backend] = None,

15

mongetter: Optional[Mongetter] = None,

16

sql_engine: Optional[Union[str, Any, Callable[[], Any]]] = None,

17

redis_client: Optional[RedisClient] = None,

18

stale_after: Optional[timedelta] = None,

19

next_time: Optional[bool] = None,

20

cache_dir: Optional[Union[str, os.PathLike]] = None,

21

pickle_reload: Optional[bool] = None,

22

separate_files: Optional[bool] = None,

23

wait_for_calc_timeout: Optional[int] = None,

24

allow_none: Optional[bool] = None,

25

cleanup_stale: Optional[bool] = None,

26

cleanup_interval: Optional[timedelta] = None,

27

):

28

"""

29

Wrap as a persistent, stale-free memoization decorator.

30

31

The positional and keyword arguments to the wrapped function must be

32

hashable (i.e. Python's immutable built-in objects, not mutable

33

containers).

34

35

Parameters:

36

- hash_func: A callable that gets the args and kwargs from the decorated

37

function and returns a hash key for them. Enables use with

38

functions that get arguments not automatically hashable.

39

- hash_params: Deprecated, use hash_func instead

40

- backend: Backend name ('pickle', 'mongo', 'memory', 'sql', 'redis').

41

Defaults to 'pickle' unless a core-associated parameter is provided.

42

- mongetter: A callable that takes no arguments and returns a

43

pymongo.Collection object with writing permissions.

44

If unset, local pickle cache is used.

45

- sql_engine: SQLAlchemy connection string, Engine, or callable returning

46

an Engine. Used for the SQL backend.

47

- redis_client: Redis client instance or callable returning a Redis client.

48

Used for the Redis backend.

49

- stale_after: Time delta after which a cached result is considered stale.

50

Calls made after result goes stale trigger recalculation.

51

- next_time: If True, stale result returned when finding one, not waiting

52

for fresh result calculation. Defaults to False.

53

- cache_dir: Fully qualified path to cache file directory. Process must

54

have running permissions. Defaults to XDG-compliant cache directory

55

or ~/.cachier/ as fallback

56

- pickle_reload: If True, in-memory cache reloaded on each read, enabling

57

different threads to share cache. Should be False for

58

faster reads in single-thread programs. Defaults to True.

59

- separate_files: For Pickle cores only. Instead of single cache file per

60

function, each function's cache split between several files,

61

one for each argument set. Helps with large cache files.

62

- wait_for_calc_timeout: For MongoDB only. Maximum time to wait for ongoing

63

calculation. When process starts calculation setting

64

being_calculated to True, any process trying to read

65

same entry waits maximum of seconds specified.

66

0 means wait forever.

67

- allow_none: Allows storing None values in cache. If False, functions

68

returning None not cached and recalculated every call.

69

- cleanup_stale: If True, stale cache entries periodically deleted in

70

background thread. Defaults to False.

71

- cleanup_interval: Minimum time between automatic cleanup runs.

72

Defaults to one day.

73

74

Returns:

75

Decorated function with attached cache management methods:

76

- clear_cache(): Clear all cached entries

77

- clear_being_calculated(): Mark all entries as not being calculated

78

- cache_dpath(): Return cache directory path if exists

79

- precache_value(*args, value_to_cache, **kwargs): Add initial value to cache

80

"""

81

```

82

83

Usage examples:

84

85

```python

86

from cachier import cachier

87

from datetime import timedelta

88

import os

89

90

# Basic caching with default pickle backend

91

@cachier()

92

def compute_heavy_task(data):

93

# Expensive computation

94

return sum(x**2 for x in data)

95

96

# Custom cache directory

97

@cachier(cache_dir="/tmp/my_cache")

98

def process_files(file_path):

99

with open(file_path, 'r') as f:

100

return f.read().upper()

101

102

# Stale-aware caching with background refresh

103

@cachier(

104

stale_after=timedelta(minutes=30),

105

next_time=True # Return stale while refreshing in background

106

)

107

def fetch_external_data(api_endpoint):

108

import requests

109

return requests.get(api_endpoint).json()

110

111

# Custom hash function for complex objects

112

def custom_hash(args, kwargs):

113

# Custom hashing logic for non-hashable arguments

114

import pickle

115

import hashlib

116

serialized = pickle.dumps((args, sorted(kwargs.items())))

117

return hashlib.sha256(serialized).hexdigest()

118

119

@cachier(hash_func=custom_hash)

120

def analyze_dataframe(df, options):

121

# Process pandas DataFrame (not naturally hashable)

122

return df.groupby('category').sum()

123

124

# Cleanup stale entries automatically

125

@cachier(

126

stale_after=timedelta(hours=1),

127

cleanup_stale=True,

128

cleanup_interval=timedelta(minutes=30)

129

)

130

def periodic_report(date_range):

131

# Generate reports with automatic cleanup

132

return generate_report(date_range)

133

```

134

135

### Runtime Cache Control

136

137

Functions can control caching behavior at runtime using special keyword arguments:

138

139

```python

140

# Skip cache for specific call

141

result = my_cached_function(data, cachier__skip_cache=True)

142

143

# Overwrite cached value

144

result = my_cached_function(data, cachier__overwrite_cache=True)

145

146

# Enable verbose cache logging

147

result = my_cached_function(data, cachier__verbose=True)

148

149

# Override stale_after for specific call

150

result = my_cached_function(data, cachier__stale_after=timedelta(minutes=5))

151

152

# Override next_time behavior

153

result = my_cached_function(data, cachier__next_time=False)

154

155

# Set maximum age for this specific call

156

result = my_cached_function(data, max_age=timedelta(minutes=10))

157

```

158

159

**Runtime Parameters**:

160

- `cachier__skip_cache`: Skip cache lookup and storage for this call

161

- `cachier__overwrite_cache`: Force recalculation and overwrite existing cache entry

162

- `cachier__verbose`: Enable verbose logging for this call

163

- `cachier__stale_after`: Override decorator's stale_after setting for this call

164

- `cachier__next_time`: Override decorator's next_time setting for this call

165

- `cachier__cleanup_stale`: Override decorator's cleanup_stale setting for this call

166

- `cachier__cleanup_interval`: Override decorator's cleanup_interval setting for this call

167

- `cachier__allow_none`: Override decorator's allow_none setting for this call

168

- `max_age`: Maximum allowed age for cached value (triggers recalculation if exceeded)

169

170

## Cache Management Methods

171

172

All decorated functions receive these attached methods:

173

174

### Clear Cache

175

176

```python { .api }

177

def clear_cache() -> None:

178

"""Clear all cached entries for this function."""

179

```

180

181

### Clear Being Calculated

182

183

```python { .api }

184

def clear_being_calculated() -> None:

185

"""Mark all entries in this cache as not being calculated."""

186

```

187

188

### Cache Directory Path

189

190

```python { .api }

191

def cache_dpath() -> Optional[str]:

192

"""Return the path to the cache directory, if exists; None if not."""

193

```

194

195

### Precache Value

196

197

```python { .api }

198

def precache_value(*args, value_to_cache, **kwargs):

199

"""

200

Add an initial value to the cache.

201

202

Parameters:

203

- *args, **kwargs: Function arguments to associate with cached value

204

- value_to_cache: Entry to be written into the cache

205

206

Returns:

207

The cached value

208

"""

209

```

210

211

Usage examples:

212

213

```python

214

@cachier()

215

def expensive_function(x, y):

216

return x * y + complex_calculation(x, y)

217

218

# Pre-populate cache with known values

219

expensive_function.precache_value(5, 10, value_to_cache=150)

220

221

# Clear specific function's cache

222

expensive_function.clear_cache()

223

224

# Get cache location

225

cache_path = expensive_function.cache_dpath()

226

print(f"Cache stored at: {cache_path}")

227

228

# Reset calculation locks (useful after crashes)

229

expensive_function.clear_being_calculated()

230

```