Add caching back in (#312)

* Add caching back in

Works now against filter instead of dataframe view

* Layout cache and move post->put

* Fix tests
This commit is contained in:
Charlotte Weaver
2018-10-11 16:29:46 -07:00
parent b90292ce4c
commit 3229babd14
4 changed files with 47 additions and 27 deletions
+1 -1
View File
@@ -461,7 +461,7 @@ Get the _default_ layout for all observations or (_future_) all variables. Retur
}
```
### POST /layout/obs, (_future_) POST /layout/var
### PUT /layout/obs, (_future_) PUT /layout/var
Generate layout for the caller-specified subset of data, as indicated by the filter. This operation implicitly requests a re-layout operation to be performed on the specified data.
+5 -10
View File
@@ -670,17 +670,12 @@ class LayoutObsAPI(Resource):
},
}
})
def post(self):
def put(self):
try:
return make_response(
jsonify({
"layout": current_app.data.layout(
request.get_json()["filter"],
interactive_limit=current_app.data.features["layout"]["obs"]["interactiveLimit"]
)
}),
HTTPStatus.OK
)
filter = request.get_json()["filter"]
interactive_limit = current_app.data.features["layout"]["obs"]["interactiveLimit"]
layout = current_app.data.layout(filter, interactive_limit=interactive_limit)
return make_response(jsonify({"layout": layout}), HTTPStatus.OK)
except FilterError as e:
return make_response(e.message, HTTPStatus.BAD_REQUEST)
except InteractiveError:
+4 -6
View File
@@ -6,8 +6,7 @@ from pandas import DataFrame, Series
import scanpy.api as sc
from scipy import stats
# TODO fix memoization so that it correctly identifies the same request
# from server.app.app import cache
from server.app.app import cache
from server.app.driver.driver import CXGDriver
from server.app.util.constants import Axis, DEFAULT_TOP_N, DiffExpMode
from server.app.util.utils import FilterError, InteractiveError
@@ -201,7 +200,7 @@ class ScanpyEngine(CXGDriver):
index = np.logical_and(index, key_idx)
return index
# @cache.memoize()
@cache.memoize()
def annotation(self, filter, axis, fields=None):
"""
Gets annotation value for each observation
@@ -224,7 +223,7 @@ class ScanpyEngine(CXGDriver):
"data": annotations.reset_index().values.tolist()
}
# @cache.memoize()
@cache.memoize()
def data_frame(self, filter, axis):
"""
Retrieves data for each variable for observations in data frame
@@ -261,7 +260,6 @@ class ScanpyEngine(CXGDriver):
}
return result
# @cache.memoize()
def diffexp(self, filter1, filter2, top_n=None, interactive_limit=None):
"""
Computes the top differentially expressed variables between two observation sets. If dataframes
@@ -321,7 +319,7 @@ class ScanpyEngine(CXGDriver):
# Results need to be returned in var index order
return sorted(result, key=lambda gene: gene[0])
# @cache.memoize()
@cache.memoize()
def layout(self, filter, interactive_limit=None):
"""
Computes a n-d layout for cells through dimensionality reduction.
+37 -10
View File
@@ -84,22 +84,16 @@ class EndPoints(unittest.TestCase):
}
}
}
result = self.session.post(url, json=obs_filter)
result = self.session.put(url, json=obs_filter)
self.assertEqual(result.status_code, HTTPStatus.OK)
result_data = result.json()
self.assertEqual(len(result_data["layout"]["coordinates"]), 15)
def test_bad_filter(self):
endpoints = {
"layout/obs": "post",
"annotations/obs": "put",
"annotations/var": "put",
"data/obs": "put",
"data/var": "put"
}
for endpoint, method in endpoints.items():
endpoints = ["layout/obs", "annotations/obs", "annotations/var", "data/obs", "data/var"]
for endpoint in endpoints:
url = f"{URL_BASE}{endpoint}"
result = getattr(self.session, method)(url, json=BAD_FILTER)
result = self.session.put(url, json=BAD_FILTER)
self.assertEqual(result.status_code, HTTPStatus.BAD_REQUEST)
def test_get_annotations_obs(self):
@@ -373,6 +367,39 @@ class EndPoints(unittest.TestCase):
self.assertEqual(len(result_data["obs"]), 2638)
self.assertEqual(len(result_data["var"][0]), 2639)
def test_cache(self):
endpoint = "annotations/var"
url = f"{URL_BASE}{endpoint}"
f1 = {"filter": {"var": {"annotation_value": [{"name": "name",
"values": ["HLA-DRB1", "HLA-DQA1", "HLA-DQB1", "HLA-DPA1",
"HLA-DPB1", "MS4A1", "IL32", "CCL5", "CD79B",
"CD79A"]}]}}}
result = self.session.put(url, json=f1)
self.assertEqual(result.status_code, HTTPStatus.OK)
result_data1 = result.json()
f2 = {"filter": {"var": {"annotation_value": [{"name": "name",
"values": ["FGFBP2", "GZMA", "LTB", "PRF1", "CTSW", "GZMH",
"CCL5", "CCL4", "CST7", "NKG7"]}]}}}
result = self.session.put(url, json=f2)
self.assertEqual(result.status_code, HTTPStatus.OK)
result_data2 = result.json()
self.assertNotEqual(result_data1, result_data2)
def test_cache_nofilter(self):
endpoint = "annotations/var"
url = f"{URL_BASE}{endpoint}"
f1 = {"filter": {}}
result = self.session.put(url, json=f1)
self.assertEqual(result.status_code, HTTPStatus.OK)
result_data1 = result.json()
f2 = {"filter": {"var": {"annotation_value": [{"name": "name",
"values": ["FGFBP2", "GZMA", "LTB", "PRF1", "CTSW", "GZMH",
"CCL5", "CCL4", "CST7", "NKG7"]}]}}}
result = self.session.put(url, json=f2)
self.assertEqual(result.status_code, HTTPStatus.OK)
result_data2 = result.json()
self.assertNotEqual(result_data1, result_data2)
def test_static(self):
endpoint = "static"
file = "js/service-worker.js"