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 recurse_dir(path): if not os.path.exists(path): raise CellxgeneException("The given path does not exist.", status.HTTP_400_BAD_REQUEST) all_entries = os.listdir(path) def is_h5ad(el): return el.endswith('.h5ad') and os.path.isfile(os.path.join(path, el)) h5ad_entries = [x for x in all_entries if is_h5ad(x)] annotation_dir_entries = [ x for x in all_entries if x.endswith(annotations_suffix) and make_h5ad(x) in h5ad_entries ] def list_annotations(el): full_path = os.path.join(path, el) if not os.path.isdir(full_path): entries = [] else: entries = [{ "name": x[:-13] if (len(x) > 13 and x[-13] in ['-', '_']) else (x[:-4] if x.endswith('.csv') else x), "path": os.path.join(full_path, x).replace(env.cellxgene_data, ""), } for x in os.listdir(full_path) if x.endswith('.csv') and os.path.isfile(os.path.join(full_path, x))] return [{ "name": 'new', "class": 'new', "path": full_path.replace(env.cellxgene_data, "") }] + entries def make_entry(el): full_path = os.path.join(path, el) if el in h5ad_entries: return { "path": full_path.replace(env.cellxgene_data, ""), "name": el, "type": "file", "annotations": list_annotations(make_annotations(el)), } elif os.path.isdir(full_path) and el not in annotation_dir_entries: return { "path": full_path.replace(env.cellxgene_data, ""), "name": el, "type": "directory", "children": recurse_dir(full_path), } else: return { "path": full_path, "name": el, "type": "neither", } return [make_entry(x) for x in os.listdir(path)]
def test_GIVEN_annotation_dir_THEN_returns_h5ad(self): self.assertEqual(make_h5ad("pbmc_annotations"), "pbmc.h5ad")