0
# Caching Decorators
1
2
Function and view decorators that provide transparent caching capabilities for Flask applications. The @cached decorator caches view results based on request path, while @memoize caches function results based on arguments.
3
4
## Capabilities
5
6
### View Caching with @cached
7
8
Cache Flask view functions and regular functions with intelligent key generation based on request context.
9
10
```python { .api }
11
def cached(
12
timeout: Optional[int] = None,
13
key_prefix: str = "view/%s",
14
unless: Optional[Callable] = None,
15
forced_update: Optional[Callable] = None,
16
response_filter: Optional[Callable] = None,
17
query_string: bool = False,
18
hash_method: Callable = hashlib.md5,
19
cache_none: bool = False,
20
make_cache_key: Optional[Callable] = None,
21
source_check: Optional[bool] = None,
22
response_hit_indication: Optional[bool] = False
23
) -> Callable:
24
"""
25
Decorator for caching function results.
26
27
Parameters:
28
- timeout: Cache timeout in seconds (None uses default)
29
- key_prefix: Key prefix template, '%s' replaced with request.path
30
- unless: Function to bypass cache when returns True
31
- forced_update: Function to force cache update when returns True
32
- response_filter: Function to filter responses before caching
33
- query_string: Include query string in cache key
34
- hash_method: Hash function for key generation
35
- cache_none: Cache None values
36
- make_cache_key: Custom cache key generation function
37
- source_check: Include function source code in cache key
38
- response_hit_indication: Add 'hit_cache' header when cache is used
39
40
Returns:
41
Decorated function with caching behavior
42
"""
43
```
44
45
**Basic Usage:**
46
```python
47
from flask import Flask
48
from flask_caching import Cache
49
50
app = Flask(__name__)
51
cache = Cache(app)
52
53
# Cache view for 5 minutes
54
@app.route('/expensive-data')
55
@cache.cached(timeout=300)
56
def get_expensive_data():
57
# Expensive database query or API call
58
data = perform_expensive_operation()
59
return jsonify(data)
60
61
# Cache with custom key prefix
62
@app.route('/user/<int:user_id>/profile')
63
@cache.cached(timeout=600, key_prefix='user_profile_%s')
64
def user_profile(user_id):
65
profile = get_user_profile(user_id)
66
return render_template('profile.html', profile=profile)
67
```
68
69
**Advanced Usage:**
70
```python
71
# Cache with query string consideration
72
@app.route('/search')
73
@cache.cached(timeout=300, query_string=True)
74
def search():
75
query = request.args.get('q', '')
76
page = request.args.get('page', 1, type=int)
77
results = perform_search(query, page)
78
return jsonify(results)
79
80
# Conditional caching
81
def skip_cache_for_admin():
82
return current_user.is_admin if current_user else False
83
84
@app.route('/dashboard')
85
@cache.cached(timeout=60, unless=skip_cache_for_admin)
86
def dashboard():
87
return render_template('dashboard.html')
88
89
# Custom cache key generation
90
def make_user_cache_key():
91
return f"user_{current_user.id}_dashboard"
92
93
@app.route('/user-dashboard')
94
@cache.cached(timeout=300, make_cache_key=make_user_cache_key)
95
def user_dashboard():
96
return render_template('user_dashboard.html')
97
```
98
99
### Function Memoization with @memoize
100
101
Cache function results based on their arguments, enabling efficient memoization of expensive computations.
102
103
```python { .api }
104
def memoize(
105
timeout: Optional[int] = None,
106
make_name: Optional[Callable] = None,
107
unless: Optional[Callable] = None,
108
forced_update: Optional[Callable] = None,
109
response_filter: Optional[Callable] = None,
110
hash_method: Callable = hashlib.md5,
111
cache_none: bool = False,
112
source_check: Optional[bool] = None,
113
args_to_ignore: Optional[List[str]] = None
114
) -> Callable:
115
"""
116
Decorator for memoizing function results based on arguments.
117
118
Parameters:
119
- timeout: Cache timeout in seconds
120
- make_name: Function to customize cache key name
121
- unless: Function to bypass cache when returns True
122
- forced_update: Function to force cache update when returns True
123
- response_filter: Function to filter results before caching
124
- hash_method: Hash function for key generation
125
- cache_none: Cache None values
126
- source_check: Include function source in cache key
127
- args_to_ignore: List of argument names to ignore in cache key
128
129
Returns:
130
Decorated function with memoization behavior
131
"""
132
```
133
134
**Basic Usage:**
135
```python
136
# Memoize expensive computation
137
@cache.memoize(timeout=3600)
138
def fibonacci(n):
139
if n <= 1:
140
return n
141
return fibonacci(n-1) + fibonacci(n-2)
142
143
# Memoize database queries
144
@cache.memoize(timeout=600)
145
def get_user_posts(user_id, include_drafts=False):
146
query = Post.query.filter_by(user_id=user_id)
147
if not include_drafts:
148
query = query.filter_by(published=True)
149
return query.all()
150
151
# Usage
152
result = fibonacci(50) # Computed and cached
153
result = fibonacci(50) # Retrieved from cache
154
155
posts = get_user_posts(123, include_drafts=False) # Cached separately from drafts=True
156
```
157
158
**Advanced Usage:**
159
```python
160
# Ignore certain arguments in cache key
161
@cache.memoize(timeout=300, args_to_ignore=['current_time'])
162
def get_daily_stats(date, current_time=None):
163
# current_time is used for logging but not cache key
164
log_request(current_time)
165
return calculate_daily_stats(date)
166
167
# Custom function naming
168
def custom_name_func(func_name):
169
return f"analytics_{func_name}"
170
171
@cache.memoize(timeout=1800, make_name=custom_name_func)
172
def calculate_conversion_rate(campaign_id, date_range):
173
return perform_analytics_calculation(campaign_id, date_range)
174
175
# Class method memoization
176
class UserService:
177
@cache.memoize(timeout=600)
178
def get_user_permissions(self, user_id):
179
return database.get_user_permissions(user_id)
180
181
@cache.memoize(timeout=300)
182
@classmethod
183
def get_system_config(cls, config_name):
184
return database.get_system_config(config_name)
185
```
186
187
### Cache Management for Decorated Functions
188
189
Functions decorated with @cached and @memoize get additional cache management methods.
190
191
```python { .api }
192
# Available on @cached decorated functions
193
decorated_function.uncached # Original undecorated function
194
decorated_function.cache_timeout # Current cache timeout
195
decorated_function.make_cache_key # Cache key generation function
196
197
# Available on @memoize decorated functions
198
decorated_function.uncached # Original undecorated function
199
decorated_function.cache_timeout # Current cache timeout
200
decorated_function.make_cache_key # Cache key generation function
201
decorated_function.delete_memoized # Function to clear this function's cache
202
```
203
204
**Usage:**
205
```python
206
@cache.memoize(timeout=600)
207
def expensive_calculation(x, y):
208
return x ** y + complex_math(x, y)
209
210
# Call original function without caching
211
result = expensive_calculation.uncached(10, 3)
212
213
# Change timeout dynamically
214
expensive_calculation.cache_timeout = 1200
215
216
# Clear cached results for this function
217
expensive_calculation.delete_memoized()
218
219
# Generate cache key for inspection
220
cache_key = expensive_calculation.make_cache_key(expensive_calculation, 10, 3)
221
```
222
223
### Cache Invalidation
224
225
Manual cache invalidation for decorated functions.
226
227
```python { .api }
228
def delete_memoized(f: Callable, *args, **kwargs) -> None:
229
"""
230
Delete cached results for a memoized function.
231
232
Parameters:
233
- f: The memoized function
234
- args: Positional arguments (deletes cache for specific args)
235
- kwargs: Keyword arguments (deletes cache for specific args)
236
237
If no args/kwargs provided, deletes all cached results for the function.
238
"""
239
240
def delete_memoized_verhash(f: Callable, *args) -> None:
241
"""
242
Delete the version hash for a memoized function.
243
Forces regeneration of all cached results.
244
245
Parameters:
246
- f: The memoized function
247
- args: Additional arguments (rarely used)
248
"""
249
```
250
251
**Usage:**
252
```python
253
@cache.memoize(timeout=3600)
254
def get_user_profile(user_id):
255
return User.query.get(user_id).to_dict()
256
257
# Delete all cached profiles
258
cache.delete_memoized(get_user_profile)
259
260
# Delete cached profile for specific user
261
cache.delete_memoized(get_user_profile, 123)
262
263
# Force regeneration of all cached results (use carefully)
264
cache.delete_memoized_verhash(get_user_profile)
265
266
# Delete via function method
267
get_user_profile.delete_memoized() # All cached results
268
```
269
270
### Dynamic Cache Response
271
272
Override cache timeout dynamically using CachedResponse.
273
274
```python { .api }
275
class CachedResponse(Response):
276
"""
277
Response wrapper that allows dynamic cache timeout override.
278
279
Attributes:
280
- timeout: Cache timeout in seconds for this specific response
281
"""
282
def __init__(self, response, timeout: Optional[int]): ...
283
```
284
285
**Usage:**
286
```python
287
from flask_caching import Cache, CachedResponse
288
289
@cache.cached(timeout=300)
290
def dynamic_content():
291
data = get_content()
292
293
# Cache VIP content longer
294
if data.get('is_vip'):
295
return CachedResponse(jsonify(data), timeout=3600)
296
297
# Cache regular content with default timeout
298
return jsonify(data)
299
```