diff --git a/flatisfy/data.py b/flatisfy/data.py index 5510aba..c504bd7 100644 --- a/flatisfy/data.py +++ b/flatisfy/data.py @@ -13,6 +13,7 @@ from flatisfy import database from flatisfy import data_files from flatisfy.models.postal_code import PostalCode from flatisfy.models.public_transport import PublicTransport +from flatisfy.tools import hash_dict LOGGER = logging.getLogger(__name__) @@ -68,6 +69,7 @@ def preprocess_data(config, force=False): session.add_all(data_objects) +@hash_dict @lru_cache(maxsize=5) def load_data(model, constraint, config): """ diff --git a/flatisfy/tools.py b/flatisfy/tools.py index 698dddc..152f75b 100644 --- a/flatisfy/tools.py +++ b/flatisfy/tools.py @@ -18,6 +18,18 @@ import time import requests import unidecode +try: + from functools import wraps +except ImportError: + try: + from functools32 import wraps + except ImportError: + def wraps(func): + """ + Identity implementation of ``wraps`` for fallback. + """ + return lambda func: func + LOGGER = logging.getLogger(__name__) @@ -25,6 +37,33 @@ LOGGER = logging.getLogger(__name__) NAVITIA_ENDPOINT = "https://api.navitia.io/v1/coverage/fr-idf/journeys" +def hash_dict(func): + """ + Decorator to use on functions accepting dict parameters, to transform them + into immutable dicts and be able to use lru_cache. + + From https://stackoverflow.com/a/44776960. + """ + class HDict(dict): + """ + Transform mutable dictionnary into immutable. Useful to be compatible + with lru_cache + """ + def __hash__(self): + return hash(json.dumps(self)) + + @wraps(func) + def wrapped(*args, **kwargs): + args = tuple( + [HDict(arg) if isinstance(arg, dict) else arg + for arg in args + ]) + kwargs = {k: HDict(v) if isinstance(v, dict) else v + for k, v in kwargs.items()} + return func(*args, **kwargs) + return wrapped + + class DateAwareJSONEncoder(json.JSONEncoder): """ Extend the default JSON encoder to serialize datetimes to iso strings.