mirror of
https://github.com/chanzuckerberg/cellxgene.git
synced 2026-09-30 13:28:11 +08:00
add GET routes for expression data (#1387)
* add GET routes for expression data * fix comment typo
This commit is contained in:
@@ -206,6 +206,13 @@ class EndPoints(object):
|
||||
result = self.session.put(url, headers=header)
|
||||
self.assertEqual(result.status_code, HTTPStatus.BAD_REQUEST)
|
||||
|
||||
def test_data_get_fbs(self):
|
||||
endpoint = f"data/var"
|
||||
url = f"{self.URL_BASE}{endpoint}"
|
||||
header = {"Accept": "application/octet-stream"}
|
||||
result = self.session.get(url, headers=header)
|
||||
self.assertEqual(result.status_code, HTTPStatus.BAD_REQUEST)
|
||||
|
||||
def test_data_put_filter_fbs(self):
|
||||
endpoint = f"data/var"
|
||||
url = f"{self.URL_BASE}{endpoint}"
|
||||
@@ -222,6 +229,19 @@ class EndPoints(object):
|
||||
self.assertEqual(len(df["columns"]), df["n_cols"])
|
||||
self.assertListEqual(df["col_idx"].tolist(), [0, 1, 4])
|
||||
|
||||
def test_data_get_filter_fbs(self):
|
||||
index_col_name = self.schema["schema"]["annotations"]["var"]["index"]
|
||||
query = f"var:{index_col_name}=SIK1"
|
||||
endpoint = f"data/var"
|
||||
url = f"{self.URL_BASE}{endpoint}?{query}"
|
||||
header = {"Accept": "application/octet-stream"}
|
||||
result = self.session.get(url, headers=header)
|
||||
self.assertEqual(result.status_code, HTTPStatus.OK)
|
||||
self.assertEqual(result.headers["Content-Type"], "application/octet-stream")
|
||||
df = decode_fbs.decode_matrix_FBS(result.content)
|
||||
self.assertEqual(df["n_rows"], 2638)
|
||||
self.assertEqual(df["n_cols"], 1)
|
||||
|
||||
def test_data_put_single_var(self):
|
||||
endpoint = f"data/var"
|
||||
url = f"{self.URL_BASE}{endpoint}"
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
import unittest
|
||||
from urllib.parse import parse_qs
|
||||
from werkzeug.datastructures import MultiDict
|
||||
from server.common.rest import _query_parameter_to_filter
|
||||
from server.common.errors import FilterError
|
||||
|
||||
|
||||
def _qsparse(qs):
|
||||
""" emulate what Flask/Werkzeug do to our QS """
|
||||
return MultiDict(parse_qs(qs))
|
||||
|
||||
|
||||
class FilterParseTests(unittest.TestCase):
|
||||
""" Test cases for various filter parsing """
|
||||
|
||||
def test_queryparam_to_filter_parse(self):
|
||||
# categories
|
||||
self.assertEqual(_query_parameter_to_filter(_qsparse("obs:foo=bar&var:baz=133&var:baz=A&obs:baz=foo")), {
|
||||
"obs": {
|
||||
"annotation_value": [
|
||||
{"name": "foo", "values": ["bar"]},
|
||||
{"name": "baz", "values": ["foo"]},
|
||||
]
|
||||
},
|
||||
"var": {
|
||||
"annotation_value": [
|
||||
{"name": "baz", "values": ["133", "A"]}
|
||||
]
|
||||
}
|
||||
})
|
||||
|
||||
# ranges
|
||||
self.assertEqual(_query_parameter_to_filter(_qsparse("obs:A=1,99&obs:B=*,100&obs:C=0,*")), {
|
||||
"obs": {
|
||||
"annotation_value": [
|
||||
{"name": "A", "min": 1, "max": 99.},
|
||||
{"name": "B", "max": 100.},
|
||||
{"name": "C", "min": 0.},
|
||||
]
|
||||
},
|
||||
})
|
||||
|
||||
# combo
|
||||
self.assertEqual(_query_parameter_to_filter(_qsparse("var:B=YES&var:A=1,99&var:B=NO")), {
|
||||
"var": {
|
||||
"annotation_value": [
|
||||
{"name": "B", "values": ["YES", "NO"]},
|
||||
{"name": "A", "min": 1., "max": 99.},
|
||||
]
|
||||
},
|
||||
})
|
||||
|
||||
def test_queryparam_to_filter_escaping(self):
|
||||
self.assertEqual(_query_parameter_to_filter(_qsparse("obs:var=%2521%252C%253AOK%253D&obs:A%2521=YO")), {
|
||||
"obs": {
|
||||
"annotation_value": [
|
||||
{"name": "var", "values": ["!,:OK="]},
|
||||
{"name": "A!", "values": ["YO"]},
|
||||
],
|
||||
},
|
||||
})
|
||||
|
||||
def test_queryparam_to_filter_errors(self):
|
||||
|
||||
# should raise FilterError
|
||||
filter_errors = [
|
||||
"foo=bar", # no axis
|
||||
"X=&Y=3", # no value
|
||||
"X&Y=3", # no value
|
||||
"moo:foo=bar", # bad axis
|
||||
"obs:x=1,A", # non-numeric range
|
||||
"var:X=1,2&var:X=3,4", # duplicate ranges
|
||||
"var:Y=,",
|
||||
"var:Y=2,",
|
||||
"var:Y=,5",
|
||||
"var:Y=*,",
|
||||
"var:Y=,*",
|
||||
"var:Y=*,*",
|
||||
]
|
||||
|
||||
for qs in filter_errors:
|
||||
with self.assertRaises(FilterError):
|
||||
_query_parameter_to_filter(_qsparse(qs))
|
||||
Reference in New Issue
Block a user