From d8cd78e8e536fcf73d662bbe5840b87c7d943c3d Mon Sep 17 00:00:00 2001 From: Axel Bocciarelli Date: Thu, 29 Aug 2024 16:19:31 +0200 Subject: [PATCH 1/2] Support fetching boolean data as binary --- h5grove/utils.py | 2 +- test/base_test.py | 21 +++++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/h5grove/utils.py b/h5grove/utils.py index e3094e9..65b9093 100644 --- a/h5grove/utils.py +++ b/h5grove/utils.py @@ -212,7 +212,7 @@ def _sanitize_dtype(dtype: np.dtype) -> np.dtype: :raises ValueError: If trying to sanitize a non-numeric numpy dtype """ - if dtype.kind not in ("f", "i", "u"): + if dtype.kind not in ("f", "i", "u", "b"): raise ValueError(f"Unsupported numpy dtype `{dtype}`. Expected numeric dtype.") # Convert to little endian diff --git a/test/base_test.py b/test/base_test.py index 582aefa..e263225 100644 --- a/test/base_test.py +++ b/test/base_test.py @@ -140,6 +140,27 @@ def test_data_on_slice_with_format_and_flatten(self, server, format_arg): assert retrieved_data - data[100, 0] < 1e-8 + def test_data_on_bool(self, server): + """Test /data/ endpoint on boolean dataset with format=bin""" + tested_h5entity_path = "/bool" + data = np.array([True, False, True, True]) + + filename = "test.h5" + with h5py.File(server.served_directory / filename, mode="w") as h5file: + dset = h5file.create_dataset(tested_h5entity_path, data=data) + dtype = dset.dtype + shape = dset.shape + + response = server.get( + f"/data/?{urlencode({'file': filename, 'path': tested_h5entity_path, 'format': 'bin'})}" + ) + + content_type = response.find_header_value("content-type") + assert content_type == "application/octet-stream" + + retrieved_data = decode_array_response(response, "bin", dtype.str, shape) + assert np.array_equal(retrieved_data, data) + def test_data_on_opaque(self, server): """Test /data/ endpoint on opaque dataset with format=bin""" tested_h5entity_path = "/opaque" From d0bd0b7a979603bc31195b60a8f37f7b5de3d3b3 Mon Sep 17 00:00:00 2001 From: Axel Bocciarelli Date: Mon, 2 Sep 2024 11:22:19 +0200 Subject: [PATCH 2/2] Refactor `_sanitize_dtype` --- h5grove/utils.py | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/h5grove/utils.py b/h5grove/utils.py index 65b9093..c49f256 100644 --- a/h5grove/utils.py +++ b/h5grove/utils.py @@ -208,25 +208,21 @@ def get_type_metadata(type_id: h5py.h5t.TypeID) -> TypeMetadata: def _sanitize_dtype(dtype: np.dtype) -> np.dtype: - """Sanitize numpy dtype to one with a matching typed array in modern JavaScript. - - :raises ValueError: If trying to sanitize a non-numeric numpy dtype - """ - if dtype.kind not in ("f", "i", "u", "b"): - raise ValueError(f"Unsupported numpy dtype `{dtype}`. Expected numeric dtype.") - - # Convert to little endian - result = dtype.newbyteorder("<") + """Sanitize numpy dtype to one with a matching typed array in modern JavaScript.""" # Convert float16 to float32 - if result.kind == "f" and result.itemsize < 4: + if dtype.kind == "f" and dtype.itemsize < 4: return np.dtype(" 8: + if dtype.kind == "f" and dtype.itemsize > 8: return np.dtype("": + return dtype.newbyteorder("<") + + return dtype T = TypeVar("T", np.ndarray, np.number, np.bool_)