diff --git a/src/searchly/api/v1/controllers/similarity.py b/src/searchly/api/v1/controllers/similarity.py index 86ba484..096d3b2 100644 --- a/src/searchly/api/v1/controllers/similarity.py +++ b/src/searchly/api/v1/controllers/similarity.py @@ -1,7 +1,7 @@ from flask import request from src.searchly.api.v1.services import response -from src.searchly.helper import searcher, log +from src.searchly.helper import searcher, log, cache def by_song(): @@ -10,14 +10,24 @@ def by_song(): :return: JSON response. """ try: + # Parameters retrieving song_id = request.args.get('song_id') if not song_id: return response.make(error=True, message='`song_id` missed as a query parameter.') + # Cache processing + method = by_song.__name__ + key = '{}'.format(song_id) + results_cached = cache.get(method, key) + if results_cached is not None: + return response.make(response=results_cached, cached=True) + # Feature extraction features = searcher.extract_features_from_song(song_id) if features is None: - return response.make(error=True, message='Song not found.') + return response.make(error=True, message='Song not found.', method=method, key=key) + # Searching results = searcher.search(features, song_id=song_id) - return response.make(error=False, response=dict(similarity_list=results)) + # Return results and refresh cache + return response.make(error=False, response=dict(similarity_list=results), method=method, key=key) except Exception as e: log.error(f'Unexpected error: [{e}]') log.exception(e) @@ -30,6 +40,7 @@ def by_content(): :return: JSON response. """ try: + # Parameters retrieving request_json = request.json content = response.get('content', request_json) if not content: diff --git a/src/searchly/api/v1/services/response.py b/src/searchly/api/v1/services/response.py index 9c84c06..cc373c1 100644 --- a/src/searchly/api/v1/services/response.py +++ b/src/searchly/api/v1/services/response.py @@ -1,19 +1,37 @@ -def make(error, message=None, response=None, code=200): +from flask import jsonify + +from src.searchly.helper import cache + + +def make(error=None, message=None, response=None, code=200, cached=False, method=None, key=None): """ API response generator function. :param error: True if the response has to be flagged as an error, False otherwise. :param message: Error message string formatted. Only being used when [error == True] :param response: JSON response dictionary formatted. Only being used when [error == False] :param code: Response code. + :param cached: True if the response is from the cache, False otherwise. + :param method: Cache method. + :param key: Cache key. :return: JSON response. """ - response_dict = dict(error=error) - if error: - assert type(message) is str - response_dict['message'] = message - else: + if cached: assert type(response) is dict - response_dict['response'] = response + response_dict = jsonify(response) + response_dict.headers['X-Cache'] = 'HIT' + else: + assert error is not None + response_dict = dict(error=error) + if error: + assert type(message) is str + response_dict['message'] = message + else: + assert type(response) is dict + response_dict['response'] = response + if method is not None and key is not None: + cache.refresh(method, key, response_dict) + response_dict = jsonify(response_dict) + response_dict.headers['X-Cache'] = 'MISS' return response_dict, code