NetCDF metadata extraction#
Enumerate and normalize all metadata from NetCDF files using GDAL's Multidimensional (MDim) API.
Overview:
- Open NetCDF files as MDArray-backed datasets
- Traverse groups, arrays, dimensions, and attributes
- Produce a JSON-serializable metadata object
- Keep compatibility with the existing dimension parser exposed via
NetCDF.meta_data
Pipeline#
get_metadata drives a MetadataBuilder, which hands a GroupTraverser the root group and walks it
breadth-first, emitting one info record per group / array / dimension into the aggregate
NetCDFMetadata. The result serializes to JSON, a plain dict, or a flat search index — and round-trips
back from JSON:
flowchart LR
S[("GDAL MDIM dataset<br/>GetRootGroup()")] --> B["MetadataBuilder.build()"]
B --> T["GroupTraverser.walk(root)<br/>breadth-first"]
T --> VI["VariableInfo"]
T --> DI["DimensionInfo"]
T --> GI["GroupInfo"]
VI --> M["NetCDFMetadata"]
DI --> M
GI --> M
M -->|to_json| J[("JSON string")]
M -->|to_dict| D[("dict")]
M -->|flatten_for_index| FI[("flat index")]
J -->|from_json| M
to_json, to_dict, from_json, and flatten_for_index (the edge labels above) are module-level
functions in pyramids.netcdf.metadata that take a NetCDFMetadata argument — not methods on the
class. NetCDFMetadata's only public method is get_dimension.
See the data models for the structure of each info record.
Usage#
Read all metadata from a file:
from pyramids.netcdf.netcdf import NetCDF
from pyramids.netcdf.metadata import to_json
# Open the file in MDIM mode
nc = NetCDF.read_file("tests/data/netcdf/cf__4v__1d3-3d1__proj__y-desc.nc", open_as_multi_dimensional=True)
# Read everything (groups, arrays, dimensions, attributes)
md = nc.get_all_metadata()
# Convert to JSON
print(to_json(md))
You can also pass open options (persisted into the result for provenance):
Dimension overview#
For convenience and backward compatibility, the returned metadata includes a dimension_overview
section summarizing parsed dimensions using the existing dimensions.MetaData logic.
Shape:
names:list[str]sizes:dict[str, int]attrs:dict[str, dict[str, str]]values:dict[str, list[int | float | str]] | None
This mirrors nc.meta_data and provides a compact CF-friendly view.
Notes#
- The feature uses GDAL's MDim API starting at
dataset.GetRootGroup(). - Attributes are normalized to JSON-friendly scalars or vectors; bytes are decoded as UTF-8.
- Convenience fields on arrays include: unit, nodata (
_FillValue/missing_valueprecedence), scale/offset, CRS (WKT/PROJJSON), structural info, block size, and coordinate variables. - No array data values are read; only metadata.
- The module provides helpers to serialize to/from JSON and to a plain dict.
References#
API#
Functions for extracting, serializing, and deserializing NetCDF metadata using GDAL's Multidimensional API.
pyramids.netcdf.metadata.get_metadata(source, open_options=None, start_group=None)
#
Read and normalize all NetCDF MDIM metadata.
Accepts several source types and delegates to
MetadataBuilder to produce a NetCDFMetadata instance.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
source
|
Dataset | str | object
|
The data source.
Accepts a GDAL dataset directly, a file path (opened
internally with |
required |
open_options
|
dict[str, Any] | None
|
Optional dictionary of GDAL open-options. Stored in the resulting metadata for provenance but not used to open the file. |
None
|
start_group
|
'gdal.Group | None'
|
Optional GDAL group to traverse from instead
of the dataset's root group. A |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
NetCDFMetadata |
NetCDFMetadata
|
Fully populated metadata dataclass. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If source is a string path that cannot be opened as a multidimensional raster. |
Examples:
Open from a file path:
>>> from osgeo import gdal
>>> import pyramids.netcdf.metadata as meta
>>> md = meta.get_metadata(
... "precip.nc"
... )
>>> md.driver
'netCDF'
See Also
MetadataBuilder: The builder class used internally.
Source code in src/pyramids/netcdf/metadata.py
pyramids.netcdf.metadata.to_json(metadata)
#
Serialize NetCDFMetadata to a compact JSON string.
Converts the dataclass tree to plain dicts via to_dict
and then encodes to JSON with no extra whitespace.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
metadata
|
NetCDFMetadata
|
A |
required |
Returns:
| Name | Type | Description |
|---|---|---|
str |
str
|
JSON-encoded string with no ASCII escaping and
compact separators (no spaces after |
Examples:
Round-trip a minimal metadata object:
>>> import json
>>> from pyramids.netcdf.metadata import to_json
>>> from pyramids.netcdf.models import (
... NetCDFMetadata, StructuralInfo,
... )
>>> md = NetCDFMetadata(
... driver="netCDF",
... root_group="/",
... groups={},
... variables={},
... dimensions={},
... global_attributes={},
... structural=StructuralInfo(
... driver_name="netCDF"
... ),
... created_with={"library": "GDAL"},
... )
>>> s = to_json(md)
>>> json.loads(s)["driver"]
'netCDF'
See Also
to_dict: Converts to plain dicts without JSON encoding.
from_json: Deserializes the string back to
NetCDFMetadata.
Source code in src/pyramids/netcdf/metadata.py
pyramids.netcdf.metadata.from_json(s)
#
Deserialize NetCDFMetadata from a JSON string.
Parses the JSON produced by to_json and manually
reconstructs the dataclass hierarchy (GroupInfo,
VariableInfo, DimensionInfo, StructuralInfo).
Only the schema produced by to_dict / to_json is
supported; arbitrary JSON will likely raise KeyError.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
s
|
str
|
A JSON string previously produced by |
required |
Returns:
| Name | Type | Description |
|---|---|---|
NetCDFMetadata |
NetCDFMetadata
|
Reconstructed metadata instance. |
Raises:
| Type | Description |
|---|---|
JSONDecodeError
|
If s is not valid JSON. |
KeyError
|
If required fields are missing from the JSON payload. |
Examples:
Round-trip through JSON:
>>> from pyramids.netcdf.metadata import (
... to_json, from_json,
... )
>>> from pyramids.netcdf.models import (
... NetCDFMetadata, StructuralInfo,
... )
>>> md = NetCDFMetadata(
... driver="netCDF",
... root_group="/",
... groups={},
... variables={},
... dimensions={},
... global_attributes={"history": "created"},
... structural=StructuralInfo(
... driver_name="netCDF"
... ),
... created_with={"library": "GDAL"},
... )
>>> s = to_json(md)
>>> restored = from_json(s)
>>> restored.driver
'netCDF'
>>> restored.global_attributes["history"]
'created'
See Also
to_json: The serialization counterpart.
Source code in src/pyramids/netcdf/metadata.py
787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 | |
pyramids.netcdf.metadata.to_dict(metadata)
#
Convert NetCDFMetadata to plain dicts suitable for JSON.
Recursively walks all dataclass fields and converts them to
plain dict / list / scalar types so the result can be
passed directly to json.dumps.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
metadata
|
NetCDFMetadata
|
A |
required |
Returns:
| Name | Type | Description |
|---|---|---|
dict |
dict[str, Any]
|
Nested dictionary with all dataclass fields converted to plain dicts. |
Examples:
Convert a minimal metadata object:
>>> from pyramids.netcdf.metadata import to_dict
>>> from pyramids.netcdf.models import (
... NetCDFMetadata, StructuralInfo,
... )
>>> md = NetCDFMetadata(
... driver="netCDF",
... root_group="/",
... groups={},
... variables={},
... dimensions={},
... global_attributes={"title": "test"},
... structural=StructuralInfo(
... driver_name="netCDF"
... ),
... created_with={"library": "GDAL"},
... )
>>> d = to_dict(md)
>>> d["driver"]
'netCDF'
>>> d["global_attributes"]["title"]
'test'
>>> d["structural"]["driver_name"]
'netCDF'
See Also
to_json: Serializes directly to a JSON string.
from_json: Deserializes a JSON string back to
NetCDFMetadata.