From 38108c1ab19f237d7c255c5c6a852c46b665951b Mon Sep 17 00:00:00 2001 From: hrodmn Date: Thu, 23 Oct 2025 10:54:32 -0500 Subject: [PATCH 1/3] fix: add opener_options arg to titiler.xarray.io.Reader resolves #1246 --- src/titiler/xarray/tests/test_io_tools.py | 65 +++++++++++++++++++++++ src/titiler/xarray/titiler/xarray/io.py | 2 + 2 files changed, 67 insertions(+) diff --git a/src/titiler/xarray/tests/test_io_tools.py b/src/titiler/xarray/tests/test_io_tools.py index 3bf883fd2..4b28ef5b8 100644 --- a/src/titiler/xarray/tests/test_io_tools.py +++ b/src/titiler/xarray/tests/test_io_tools.py @@ -2,6 +2,8 @@ import os from datetime import datetime +from typing import Any, Dict, Optional +from urllib.parse import urlparse import numpy import pytest @@ -223,6 +225,69 @@ def test_reader(protocol, filename): assert src.tile(0, 0, 0) +def test_opener(): + """test custom opener""" + src_path = "file://" + os.path.join("file://", prefix, "dataset_2d.nc") + + def custom_netcdf_opener( # noqa: C901 + src_path: str, + special_arg: bool, + group: Optional[str] = None, + decode_times: bool = True, + ) -> xarray.Dataset: + """Open Xarray dataset with fsspec. + + Args: + src_path (str): dataset path. + group (Optional, str): path to the netCDF/Zarr group in the given file to open given as a str. + decode_times (bool): If True, decode times encoded in the standard NetCDF datetime format into datetime objects. Otherwise, leave them encoded as numbers. + + Returns: + xarray.Dataset + + """ + import fsspec # noqa + + parsed = urlparse(src_path) + protocol = parsed.scheme or "file" + + if not special_arg: + raise ValueError("you forgot the special_arg :(") + + xr_open_args: Dict[str, Any] = { + "decode_coords": "all", + "decode_times": decode_times, + "engine": "h5netcdf", + "lock": False, + } + + # Argument if we're opening a datatree + if group is not None: + xr_open_args["group"] = group + + fs = fsspec.filesystem(protocol) + ds = xarray.open_dataset(fs.open(src_path), **xr_open_args) + + return ds + + with Reader( + src_path=src_path, + opener=custom_netcdf_opener, + opener_options={"special_arg": True}, + variable="dataset", + ) as src: + assert src.info() + + with pytest.raises(ValueError): + with Reader( + src_path=src_path, + opener=custom_netcdf_opener, + opener_options={"special_arg": False}, + variable="dataset", + ) as src: + assert src.info() + + @pytest.mark.parametrize( "group", [0, 1, 2], diff --git a/src/titiler/xarray/titiler/xarray/io.py b/src/titiler/xarray/titiler/xarray/io.py index 44bb11ab3..631519121 100644 --- a/src/titiler/xarray/titiler/xarray/io.py +++ b/src/titiler/xarray/titiler/xarray/io.py @@ -196,6 +196,7 @@ class Reader(XarrayReader): # xarray.Dataset options opener: Callable[..., xarray.Dataset] = attr.ib(default=xarray_open_dataset) + opener_options: Dict = attr.ib(factory=dict) group: Optional[str] = attr.ib(default=None) decode_times: bool = attr.ib(default=True) @@ -219,6 +220,7 @@ def __attrs_post_init__(self): self.src_path, group=self.group, decode_times=self.decode_times, + **self.opener_options, ) self.input = get_variable( From e14f96a60f18ea20ae37e42b019f3563de3309d6 Mon Sep 17 00:00:00 2001 From: hrodmn Date: Thu, 23 Oct 2025 10:56:49 -0500 Subject: [PATCH 2/3] chore: update changelog --- CHANGES.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGES.md b/CHANGES.md index cf0040659..1e96dde71 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -2,6 +2,9 @@ ## Unreleased +### titiler.xarray +* add `opener_options` arg to `titiler.xarray.io.Reader` to allow users to pass args through to a custom opener function ([#1248(https://github.com/developmentseed/titiler/pull/1248)]) + ### Misc * update docker image to python:3.13 From cdb3bd60faa1ad0a4e7cf9eb2f79f9c861d581d0 Mon Sep 17 00:00:00 2001 From: Henry Rodman Date: Thu, 23 Oct 2025 11:40:17 -0500 Subject: [PATCH 3/3] don't use confusing assert statement in test Co-authored-by: Vincent Sarago --- src/titiler/xarray/tests/test_io_tools.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/titiler/xarray/tests/test_io_tools.py b/src/titiler/xarray/tests/test_io_tools.py index 4b28ef5b8..28e224908 100644 --- a/src/titiler/xarray/tests/test_io_tools.py +++ b/src/titiler/xarray/tests/test_io_tools.py @@ -285,7 +285,7 @@ def custom_netcdf_opener( # noqa: C901 opener_options={"special_arg": False}, variable="dataset", ) as src: - assert src.info() + pass @pytest.mark.parametrize(