10000 opendap / dap4 support for pydap backend by Mikejmnez · Pull Request #10182 · pydata/xarray · GitHub
[go: up one dir, main page]

Skip to content

opendap / dap4 support for pydap backend #10182

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 25 commits into from
Apr 19, 2025
Merged
Changes from 1 commit
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
5258386
initial pydap4 commit
Mikejmnez Mar 28, 2025
4e463f2
update some links on documentation, and how to define opendap protoco…
Mikejmnez Mar 28, 2025
2861d2e
fix spacing
Mikejmnez Mar 28, 2025
bd7ffa8
update url
Mikejmnez Apr 9, 2025
19bbc7e
enable opening (remote) datatrees
Mikejmnez Apr 12, 2025
0fe174b
update testing
Mikejmnez Apr 12, 2025
e270471
initial tests on datatree
Mikejmnez Apr 12, 2025
e509464
another datatree test
Mikejmnez Apr 12, 2025
385f9a4
update pydap model for getting dimensions`s names
Mikejmnez Apr 13, 2025
bb9a644
pre-commit
Mikejmnez Apr 13, 2025
bae96c3
remove pydap/opendap specific attrs
Mikejmnez Apr 13, 2025
7e8f842
include `path` attribute to pydap dataset/group
Mikejmnez Apr 13, 2025
d475581
update engine ref
Mikejmnez Apr 13, 2025
7a473ae
add DeprecationWarning for `output_grid`
Mikejmnez Apr 15, 2025
881e771
pre-commit
Mikejmnez Apr 15, 2025
50c0311
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] Apr 15, 2025
a4b17e7
rebase
Mikejmnez Apr 15, 2025
ad6a72a
reverse ghost commits?
Mikejmnez Apr 16, 2025
22a3722
use latest `pydap` conda release compat with `3.10` as min dependency
Mikejmnez Apr 16, 2025
7fdc9b6
whoops set pydap to `3.5.5`
Mikejmnez Apr 16, 2025
ee10d8f
sets min version to `pydap==3.5.0`
Mikejmnez Apr 16, 2025
80354fe
Merge branch 'main' into pydap4
dcherian Apr 17, 2025
0da9c17
add description under `New Features`, as well as bump version on `Bre…
Mikejmnez Apr 17, 2025
56eaf2b
Merge branch 'main' into pydap4
Mikejmnez Apr 18, 2025
e0b29fc
add `pydap` as `T_DataTreeNetcdfEngine`
Mikejmnez Apr 18, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
update url
  • Loading branch information
Mikejmnez committed Apr 15, 2025
commit bd7ffa82299e1e0504c04d1fcc3858b247af1bc5
97 changes: 95 additions & 2 deletions xarray/backends/pydap_.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,29 @@ def _getitem(self, key):
return result


def _pydap_check_groups(ds, group):
if group in {None, "", "/"}:
# use the root group
return ds
else:
Groups = ds.groups()
# make sure it's a string
if not isinstance(group, str):
raise ValueError("group must be a string")
# support path-like syntax
path = group.strip("/").split("/")
for key in path:
try:
ds = ds.groups[key]
except KeyError as e:
if mode != "r":
ds = create_group(ds, key)
else:
# wrap error to provide slightly more helpful message
raise OSError(f"group not found: {key}", e) from e
return ds


class PydapDataStore(AbstractDataStore):
"""Store for accessing OpenDAP datasets with pydap.

Expand All @@ -71,7 +94,7 @@ def __init__(self, ds, dap2=True):
Parameters
----------
ds : pydap DatasetType
dap2 : bool (default=True). When DAP4 set dap2=`False`.
dap2 : bool (default=True). When DAP4, dap2=`False`.
"""
self.ds = ds
self.dap2 = dap2
Expand Down Expand Up @@ -148,7 +171,7 @@ class PydapBackendEntrypoint(BackendEntrypoint):
This backend is selected by default for urls.

For more information about the underlying library, visit:
https://www.pydap.org
https://pydap.github.io/pydap/en/intro.html

See Also
--------
Expand All @@ -175,6 +198,7 @@ def open_dataset(
drop_variables: str | Iterable[str] | None = None,
use_cftime=None,
decode_timedelta=None,
group=None,
application=None,
session=None,
timeout=None,
Expand Down Expand Up @@ -211,5 +235,74 @@ def open_dataset(
)
return ds

def open_groups_as_dict(
self,
filename_or_obj: str | os.PathLike[Any] | ReadBuffer | AbstractDataStore,
*,
mask_and_scale=True,
decode_times=True,
concat_characters=True,
decode_coords=True,
drop_variables: str | Iterable[str] | None = None,
use_cftime=None,
decode_timedelta=None,
group: str | None = None,
application=None,
session=None,
timeout=None,
verify=None,
user_charset=None,
use_cache=None,
session_kwargs=None,
cache_kwargs=None,
get_kwargs=None,
) -> dict[str, Dataset]:
from xarray.backends.common import _iter_nc_groups
from xarray.core.treenode import NodePath

filename_or_obj = _normalize_path(filename_or_obj)
store = PydapDataStore.open(
url=filename_or_obj,
application=application,
session=session,
timeout=timeout,
verify=verify,
user_charset=user_charset,
use_cache=use_cache,
session_kwargs=session_kwargs,
cache_kwargs=cache_kwargs,
get_kwargs=get_kwargs,
)

# Check for a group and make it a parent if it exists
if group:
parent = NodePath("/") / NodePath(group)
else:
parent = NodePath("/")

manager = store._manager
groups_dict = {}
for path_group in _iter_nc_groups(store.ds, parent=parent):
print(path_group, parent)
# group_store = NetCDF4DataStore(manager, group=path_group, **kwargs)
# store_entrypoint = StoreBackendEntrypoint()
# with close_on_error(group_store):
# group_ds = store_entrypoint.open_dataset(
# group_store,
# mask_and_scale=mask_and_scale,
# decode_times=decode_times,
# concat_characters=concat_characters,
# decode_coords=decode_coords,
# drop_variables=drop_variables,
# use_cftime=use_cftime,
# decode_timedelta=decode_timedelta,
# )
# if group:
# group_name = str(NodePath(path_group).relative_to(parent))
# else:
# group_name = str(NodePath(path_group))
# groups_dict[group_name] = group_ds

return groups_dict

BACKEND_ENTRYPOINTS["pydap"] = ("pydap", PydapBackendEntrypoint)
0