fastapi-cache
fastapi-cache copied to clipboard
Not working on class method?
Not working example:
class A:
@cache(namespace="app", expire=3600)
async def test(self, a=True):
print("test")
return [], [], []
Working example:
class A:
@staticmethod
@cache(namespace="app", expire=3600)
async def test(a=True):
print("test")
return [], [], []
Is any way to cache data on class method?
The same here :c
The cache key is generated using parameters including self
which is an object reference.
By supplying custom key_builder, we can convert the object reference to string composed of attribute you want to use as a key for caching.
from abc import ABC, abstractmethod
from enum import Enum
class KeyGenMixIn(ABC):
@abstractmethod
def to_key(self):
raise NotImplementedError
def custom_key_builder(
func,
namespace: Optional[str] = "",
request: Optional[Request] = None,
response: Optional[Response] = None,
args: Optional[tuple] = None,
kwargs: Optional[dict] = None,
):
"""
Handle Enum and object reference.
"""
prefix = f"{FastAPICache.get_prefix()}:{namespace}:"
# convert Enum parameters to strings
arguments = {}
for key, value in kwargs.items():
arguments[key] = value.value if isinstance(value, Enum) else value
new_args = []
for arg in args:
if isinstance(arg, KeyGenMixIn):
new_args.append(arg.to_key())
else:
new_args.append(arg)
cache_key = (
prefix
+ hashlib.md5(
f"{func.__module__}:{func.__name__}:{new_args}:{arguments}".encode()
).hexdigest()
)
return cache_key
The custom key builder function above replaces object reference with output of to_key
when the class overrides KeyGenMixIn
abstract class.
Now, I've updated your example by inheriting KeyGenMixIn
. Note that to_key
ignores self.db_session, and specify custom_key_builder
as key_builder
.
class A(KeyGenMixIn):
def __init__(self, name, db_session):
self.name = name
self.db_session = db_session
def to_key(self):
return self.name
@cache(namespace="app", expire=3600, key_builder=custom_key_builder)
async def test(self, a=True):
print("test")
return [], [], []
This should probably be covered in documentation. I have ideas for marking up arguments for key use that could also help here, see #129.