Coverage for ckanext/udc/search/logic/utils.py: 38%
39 statements
« prev ^ index » next coverage.py v7.7.1, created at 2026-01-19 23:48 +0000
« prev ^ index » next coverage.py v7.7.1, created at 2026-01-19 23:48 +0000
1from __future__ import annotations
3import cProfile
4import pstats
5import io
6import time
7from functools import wraps
8from typing import Any
11def profile_func(func):
12 @wraps(func)
13 def wrapper(*args, **kwargs):
14 pr = cProfile.Profile()
15 pr.enable()
17 result = func(*args, **kwargs)
19 pr.disable()
20 s = io.StringIO()
21 ps = pstats.Stats(pr, stream=s).sort_stats("cumulative")
22 ps.print_stats(50) # Top 500 slowest
24 print(s.getvalue()) # Or write to file
25 return result
27 return wrapper
30def cache_for(seconds, key_func=None):
31 """Cache function results for ``seconds`` based on an optional key."""
33 def decorator(func):
34 cached: dict[Any, dict[str, Any]] = {}
36 @wraps(func)
37 def wrapper(*args, **kwargs):
38 if key_func:
39 cache_key = key_func(*args, **kwargs)
40 else:
41 if not args and not kwargs:
42 cache_key = "__default__"
43 else:
44 cache_key = repr((args, sorted(kwargs.items())))
46 if cache_key is None:
47 cache_key = "__default__"
49 now = time.time()
50 entry = cached.get(cache_key)
51 if not entry or now - entry["time"] > seconds:
52 cached[cache_key] = {"time": now, "result": func(*args, **kwargs)}
53 return cached[cache_key]["result"]
55 return wrapper
57 return decorator