def get_key(path): if path == "/" or path == "": raise CellxgeneException( "No matching dataset found.", status.HTTP_404_NOT_FOUND ) trimmed = path[:-1] if path[-1] == "/" else path try: # valid paths come in three forms: if trimmed.endswith('.h5ad') and data_file_exists(trimmed): # 1) somedir/dataset.h5ad: a dataset return CacheKey(trimmed, trimmed, None) elif trimmed.endswith('.csv'): # 2) somedir/dataset_annotations/saldaal1-T5HMVBNV.csv : an actual annotations file. annotations_dir = os.path.split(trimmed)[0] dataset = make_h5ad(annotations_dir) if data_file_exists(dataset): data_dir_ensure(annotations_dir) return CacheKey(trimmed, dataset, trimmed) elif trimmed.endswith('_annotations') and data_dir_exists(trimmed): # 3) somedir/dataset_annotations: an annotation directory. The corresponding h5ad must exist, but the directory may not. dataset = make_h5ad(trimmed) if data_file_exists(dataset): return CacheKey(trimmed, dataset, '') except CellxgeneException: pass split = os.path.split(trimmed) return get_key(split[0])
def do_view(path, source_name=None): source = matching_source(source_name) match = cache.check_path(source, path) if match is None: lookup = source.lookup(path) if lookup is None: raise CellxgeneException( f"Could not find item for path {path} in source {source.name}", 404, ) key = CacheKey.for_lookup(source, lookup) print( f"view path={path}, source_name={source_name}, dataset={key.file_path}, annotation_file= {key.annotation_file_path}, key={key.descriptor}, source={key.source_name}" ) with entry_lock: match = cache.check_entry(key) if match is None: uascripts = get_extra_scripts() match = cache.create_entry(key, uascripts) match.timestamp = current_time_stamp() if (match.status == CacheEntryStatus.loaded or match.status == CacheEntryStatus.loading): return match.serve_content(path) elif match.status == CacheEntryStatus.error: raise ProcessException.from_cache_entry(match)
def test_launch_GIVEN_no_stdout_THEN_throw_ProcessException(self, popen): subprocess = MagicMock() subprocess.stdout.readline().decode.return_value = "" subprocess.stderr.read().decode.return_value = "An unexpected error" popen.return_value = subprocess key = CacheKey( FileItem("/czi/", name="pbmc3k.h5ad", type=ItemType.h5ad), FileItemSource("/tmp", "local"), ) entry = CacheEntry.for_key(key, 8000) from cellxgene_gateway.subprocess_backend import SubprocessBackend backend = SubprocessBackend() cellxgene_loc = "/some/cellxgene" scripts = [ "http://example.com/script.js", "http://example.com/script2.js" ] with self.assertRaises(ProcessException) as context: backend.launch(cellxgene_loc, scripts, entry) popen.assert_called_once_with( [ "yes | /some/cellxgene launch /tmp/czi/pbmc3k.h5ad --port 8000 --host 127.0.0.1 --disable-annotations --scripts http://example.com/script.js --scripts http://example.com/script2.js" ], shell=True, stderr=-1, stdout=-1, ) self.assertEqual("An unexpected error", context.exception.stderr)
def do_terminate(path): source_name = request.args.get("source_name") or default_item_source.name source = matching_source(source_name) key = CacheKey.for_lookup(source, source.lookup(path)) match = cache.check_entry(key) if not match is None: match.terminate() return redirect(url_for("do_GET_status"), code=302)
def do_relaunch(path): source_name = request.args.get("source_name") or default_item_source.name source = matching_source(source_name) key = CacheKey.for_lookup(source, source.lookup(path)) match = cache.check_entry(key) if not match is None: match.terminate() return redirect( key.view_url, code=302, )
import unittest from flask import Flask from cellxgene_gateway import flask_util from cellxgene_gateway.cache_entry import CacheEntry, CacheEntryStatus from cellxgene_gateway.cache_key import CacheKey from cellxgene_gateway.gateway import app from cellxgene_gateway.items.file.fileitem import FileItem from cellxgene_gateway.items.file.fileitem_source import FileItemSource from cellxgene_gateway.items.item import ItemType key = CacheKey( FileItem("/czi/", name="pbmc3k.h5ad", type=ItemType.h5ad), FileItemSource("/tmp", "local"), ) class TestRenderEntry(unittest.TestCase): def setUp(self): self.app = app self.app_context = self.app.test_request_context() self.app_context.push() self.client = self.app.test_client() def test_GIVEN_key_and_port_THEN_returns_loading_CacheEntry(self): entry = CacheEntry.for_key("some-key", 1) self.assertEqual(entry.status, CacheEntryStatus.loading) def test_GIVEN_absolute_static_url_THEN_include_path(self): flask_util.include_source_in_url = False
import unittest from cellxgene_gateway.cache_entry import CacheEntry, CacheEntryStatus from cellxgene_gateway.cache_key import CacheKey key = CacheKey("czi/pbmc3k.h5ad", "pbmc3k.h5ad", "tmp.csv") class TestRenderEntry(unittest.TestCase): def test_GIVEN_key_and_port_THEN_returns_loading_CacheEntry(self): entry = CacheEntry.for_key("some-key", 1) self.assertEqual(entry.status, CacheEntryStatus.loading) def test_GIVEN_absolute_static_url_THEN_include_path(self): actual = CacheEntry.for_key( key, 8000).rewrite_text_content("src:url(/static/assets/") expected = ( "src:url(http://localhost:5005/view/czi/pbmc3k.h5ad/static/assets/" ) self.assertEqual(actual, expected) def test_GIVEN_absolute_src_THEN_include_path(self): actual = CacheEntry.for_key(key, 8000).rewrite_text_content( '<link rel="shortcut icon" href="/static/assets/favicon.ico">') expected = '<link rel="shortcut icon" href="http://localhost:5005/view/czi/pbmc3k.h5ad/static/assets/favicon.ico">' self.assertEqual(actual, expected) if __name__ == "__main__": unittest.main()