Skip to content

Commit 70c99cd

Browse files
committed
Add JsonWrapper class
1 parent 843a638 commit 70c99cd

File tree

4 files changed

+139
-1
lines changed

4 files changed

+139
-1
lines changed

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
44

55
[project]
66
name = "vitessce"
7-
version = "3.4.2"
7+
version = "3.4.3"
88
authors = [
99
{ name="Mark Keller", email="[email protected]" },
1010
]

tests/test_wrappers.py

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
OmeZarrWrapper,
1616
AnnDataWrapper,
1717
CsvWrapper,
18+
JsonWrapper,
1819
MultivecZarrWrapper,
1920
ImageOmeTiffWrapper,
2021
ObsSegmentationsOmeTiffWrapper,
@@ -358,6 +359,53 @@ def test_csv_with_base_dir(self):
358359
}
359360
})
360361

362+
def test_json(self):
363+
w = JsonWrapper(
364+
json_path=data_path / 'test.segmentations.json',
365+
data_type="obsSegmentations",
366+
coordination_values={
367+
"obsType": "nucleus"
368+
}
369+
)
370+
w.local_json_uid = 'test_uid'
371+
372+
file_def_creator = w.make_json_file_def_creator(
373+
"A",
374+
"0"
375+
)
376+
file_def = file_def_creator('http://localhost:8000')
377+
self.assertEqual(file_def, {
378+
'fileType': 'obsSegmentations.json',
379+
'url': 'http://localhost:8000/A/0/test_uid',
380+
'coordinationValues': {
381+
"obsType": "nucleus"
382+
}
383+
})
384+
385+
def test_json_with_base_dir(self):
386+
w = JsonWrapper(
387+
json_path='test.segmentations.json',
388+
data_type="obsSegmentations",
389+
coordination_values={
390+
"obsType": "nucleus"
391+
}
392+
)
393+
w.base_dir = data_path
394+
w.local_json_uid = 'test_uid'
395+
396+
file_def_creator = w.make_json_file_def_creator(
397+
"A",
398+
"0"
399+
)
400+
file_def = file_def_creator('http://localhost:8000')
401+
self.assertEqual(file_def, {
402+
'fileType': 'obsSegmentations.json',
403+
'url': 'http://localhost:8000/test.segmentations.json',
404+
'coordinationValues': {
405+
"obsType": "nucleus"
406+
}
407+
})
408+
361409
def test_multivec_zarr(self):
362410
zarr_filepath = data_path / 'test_out.snap.multivec.zarr'
363411

vitessce/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
OmeZarrWrapper,
4848
MultiImageWrapper,
4949
CsvWrapper,
50+
JsonWrapper,
5051
AnnDataWrapper,
5152
MultivecZarrWrapper,
5253
ImageOmeTiffWrapper,

vitessce/wrappers.py

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -808,6 +808,95 @@ def get_csv_url(self, base_url="", dataset_uid="", obj_i=""):
808808
obj_i, self.local_csv_uid)
809809

810810

811+
class JsonWrapper(AbstractWrapper):
812+
813+
"""
814+
Wrap a JSON file by creating an instance of the ``JsonWrapper`` class.
815+
816+
:param str data_type: The data type of the information contained in the file.
817+
:param str json_path: A local filepath JSON a JSON file.
818+
:param str json_url: A remote URL of a CSV file.
819+
:param dict options: The file options.
820+
:param dict coordination_values: The coordination values.
821+
:param \\*\\*kwargs: Keyword arguments inherited from :class:`~vitessce.wrappers.AbstractWrapper`
822+
"""
823+
824+
def __init__(self, json_path=None, json_url=None, data_type=None, options=None, coordination_values=None,
825+
**kwargs):
826+
super().__init__(**kwargs)
827+
self._repr = make_repr(locals())
828+
self._json_path = json_path
829+
self._json_url = json_url
830+
self._data_type = norm_enum(data_type, dt)
831+
self._options = options
832+
self._coordination_values = coordination_values
833+
self.is_remote = json_url is not None
834+
self.local_json_uid = make_unique_filename(".json")
835+
if data_type is None:
836+
raise ValueError("Expected data_type to be provided")
837+
if json_url is not None and json_path is not None:
838+
raise ValueError(
839+
"Did not expect json_url to be provided with json_path")
840+
if json_url is None and json_path is None:
841+
raise ValueError(
842+
"Expected json_url or json_path to be provided")
843+
844+
def convert_and_save(self, dataset_uid, obj_i, base_dir=None):
845+
# Only create out-directory if needed
846+
if not self.is_remote:
847+
super().convert_and_save(dataset_uid, obj_i, base_dir=base_dir)
848+
849+
file_def_creator = self.make_json_file_def_creator(
850+
dataset_uid, obj_i)
851+
routes = self.make_json_routes(dataset_uid, obj_i)
852+
853+
self.file_def_creators.append(file_def_creator)
854+
self.routes += routes
855+
856+
def make_json_routes(self, dataset_uid, obj_i):
857+
if self.is_remote:
858+
return []
859+
else:
860+
# TODO: Move imports back to top when this is factored out.
861+
from .routes import FileRoute
862+
from starlette.responses import FileResponse
863+
864+
if self.base_dir is not None:
865+
local_json_path = join(self.base_dir, self._json_path)
866+
local_json_route_path = file_path_to_url_path(self._json_path)
867+
else:
868+
local_json_path = self._json_path
869+
local_json_route_path = self._get_route_str(dataset_uid, obj_i, self.local_json_uid)
870+
871+
async def response_func(req):
872+
return FileResponse(local_json_path, filename=os.path.basename(self._json_path))
873+
routes = [
874+
FileRoute(local_json_route_path, response_func, local_json_path),
875+
]
876+
return routes
877+
878+
def make_json_file_def_creator(self, dataset_uid, obj_i):
879+
def json_file_def_creator(base_url):
880+
file_def = {
881+
"fileType": f"{self._data_type}.json",
882+
"url": self.get_json_url(base_url, dataset_uid, obj_i),
883+
}
884+
if self._options is not None:
885+
file_def["options"] = self._options
886+
if self._coordination_values is not None:
887+
file_def["coordinationValues"] = self._coordination_values
888+
return file_def
889+
return json_file_def_creator
890+
891+
def get_json_url(self, base_url="", dataset_uid="", obj_i=""):
892+
if self.is_remote:
893+
return self._json_url
894+
if self.base_dir is not None:
895+
return self._get_url_simple(base_url, file_path_to_url_path(self._json_path, prepend_slash=False))
896+
return self._get_url(base_url, dataset_uid,
897+
obj_i, self.local_json_uid)
898+
899+
811900
class OmeZarrWrapper(AbstractWrapper):
812901

813902
"""

0 commit comments

Comments
 (0)