2018-04-06 13:37:49 +01:00
|
|
|
|
import json
|
2018-04-19 10:23:21 +01:00
|
|
|
|
from contextlib import suppress
|
2018-04-06 13:37:49 +01:00
|
|
|
|
from datetime import timedelta
|
|
|
|
|
|
from functools import wraps
|
2018-04-19 10:23:21 +01:00
|
|
|
|
from inspect import signature
|
2018-04-06 13:37:49 +01:00
|
|
|
|
|
2019-02-14 14:25:31 +00:00
|
|
|
|
from app.extensions import redis_client
|
|
|
|
|
|
|
2018-04-23 17:07:41 +01:00
|
|
|
|
TTL = int(timedelta(days=7).total_seconds())
|
2018-04-06 13:37:49 +01:00
|
|
|
|
|
|
|
|
|
|
|
2018-04-20 16:32:02 +01:00
|
|
|
|
def _get_argument(argument_name, client_method, args, kwargs):
|
2018-04-06 13:37:49 +01:00
|
|
|
|
|
2018-04-19 10:23:21 +01:00
|
|
|
|
with suppress(KeyError):
|
|
|
|
|
|
return kwargs[argument_name]
|
2018-04-06 13:37:49 +01:00
|
|
|
|
|
2018-04-19 10:24:35 +01:00
|
|
|
|
with suppress(ValueError, IndexError):
|
2018-04-20 16:32:02 +01:00
|
|
|
|
argument_index = list(signature(client_method).parameters).index(argument_name)
|
|
|
|
|
|
return args[argument_index - 1] # -1 because `args` doesn’t include `self`
|
2018-04-19 10:23:21 +01:00
|
|
|
|
|
2018-04-19 10:24:35 +01:00
|
|
|
|
with suppress(KeyError):
|
|
|
|
|
|
return signature(client_method).parameters[argument_name].default
|
|
|
|
|
|
|
2018-04-19 10:23:21 +01:00
|
|
|
|
raise TypeError("{}() takes no argument called '{}'".format(
|
|
|
|
|
|
client_method.__name__, argument_name
|
|
|
|
|
|
))
|
|
|
|
|
|
|
|
|
|
|
|
|
2018-04-20 16:32:02 +01:00
|
|
|
|
def _make_key(key_format, client_method, args, kwargs):
|
|
|
|
|
|
return key_format.format(**{
|
|
|
|
|
|
argument_name: _get_argument(argument_name, client_method, args, kwargs)
|
|
|
|
|
|
for argument_name in list(signature(client_method).parameters)
|
|
|
|
|
|
})
|
2018-04-19 10:23:21 +01:00
|
|
|
|
|
|
|
|
|
|
|
2018-04-20 16:32:02 +01:00
|
|
|
|
def set(key_format):
|
2018-04-06 13:37:49 +01:00
|
|
|
|
|
|
|
|
|
|
def _set(client_method):
|
|
|
|
|
|
|
|
|
|
|
|
@wraps(client_method)
|
|
|
|
|
|
def new_client_method(client_instance, *args, **kwargs):
|
2018-04-20 16:32:02 +01:00
|
|
|
|
redis_key = _make_key(key_format, client_method, args, kwargs)
|
2019-02-14 14:25:31 +00:00
|
|
|
|
cached = redis_client.get(redis_key)
|
2018-04-06 13:37:49 +01:00
|
|
|
|
if cached:
|
|
|
|
|
|
return json.loads(cached.decode('utf-8'))
|
|
|
|
|
|
api_response = client_method(client_instance, *args, **kwargs)
|
2019-02-14 14:25:31 +00:00
|
|
|
|
redis_client.set(
|
2018-04-06 13:37:49 +01:00
|
|
|
|
redis_key,
|
|
|
|
|
|
json.dumps(api_response),
|
|
|
|
|
|
ex=TTL,
|
|
|
|
|
|
)
|
|
|
|
|
|
return api_response
|
|
|
|
|
|
|
|
|
|
|
|
return new_client_method
|
|
|
|
|
|
return _set
|
|
|
|
|
|
|
|
|
|
|
|
|
2018-04-20 16:32:02 +01:00
|
|
|
|
def delete(key_format):
|
2018-04-06 13:37:49 +01:00
|
|
|
|
|
|
|
|
|
|
def _delete(client_method):
|
|
|
|
|
|
|
|
|
|
|
|
@wraps(client_method)
|
|
|
|
|
|
def new_client_method(client_instance, *args, **kwargs):
|
2018-04-20 16:32:02 +01:00
|
|
|
|
redis_key = _make_key(key_format, client_method, args, kwargs)
|
2019-02-14 14:25:31 +00:00
|
|
|
|
redis_client.delete(redis_key)
|
2018-04-06 13:37:49 +01:00
|
|
|
|
return client_method(client_instance, *args, **kwargs)
|
|
|
|
|
|
|
|
|
|
|
|
return new_client_method
|
|
|
|
|
|
|
|
|
|
|
|
return _delete
|