netCDF4 file access via h5py with hierarchical and legacy APIs for scientific computing
npx @tessl/cli install tessl/pypi-h5netcdf@1.6.00
# h5netcdf
1
2
A Python library that provides netCDF4 file access via h5py, offering both a modern hierarchical API and a legacy netCDF4-python compatible API. h5netcdf bypasses the traditional Unidata netCDF library, reducing binary dependencies while maintaining full compatibility with the netCDF4 file format.
3
4
## Package Information
5
6
- **Package Name**: h5netcdf
7
- **Language**: Python
8
- **Installation**: `pip install h5netcdf` (requires h5py)
9
10
## Core Imports
11
12
Modern API (recommended for new code):
13
14
```python
15
import h5netcdf
16
```
17
18
Legacy API (compatible with netCDF4-python):
19
20
```python
21
import h5netcdf.legacyapi as netCDF4
22
```
23
24
## Basic Usage
25
26
### Modern API
27
28
```python
29
import h5netcdf
30
import numpy as np
31
32
# Read a netCDF4 file
33
with h5netcdf.File('data.nc', 'r') as f:
34
# Access variables
35
temperature = f['temperature'][:]
36
37
# Access attributes
38
units = f['temperature'].attrs['units']
39
40
# Access dimensions
41
time_dim = f.dimensions['time']
42
print(f"Time dimension size: {time_dim.size}")
43
44
# Create a new netCDF4 file
45
with h5netcdf.File('output.nc', 'w') as f:
46
# Create dimensions
47
f.dimensions['time'] = 10
48
f.dimensions['lat'] = 180
49
f.dimensions['lon'] = 360
50
51
# Create variables
52
temp = f.create_variable('temperature', ('time', 'lat', 'lon'), dtype='f4')
53
temp[:] = np.random.random((10, 180, 360))
54
temp.attrs['units'] = 'K'
55
temp.attrs['long_name'] = 'Air Temperature'
56
```
57
58
### Legacy API
59
60
```python
61
import h5netcdf.legacyapi as netCDF4
62
import numpy as np
63
64
# Compatible with existing netCDF4-python code
65
with netCDF4.Dataset('data.nc', 'r') as f:
66
# Access variables through .variables
67
temperature = f.variables['temperature'][:]
68
units = f.variables['temperature'].getncattr('units')
69
70
# Access dimensions
71
time_size = len(f.dimensions['time'])
72
```
73
74
## Architecture
75
76
h5netcdf provides two distinct APIs:
77
78
- **Modern API** (`h5netcdf.File`): Hierarchical, h5py-inspired interface with direct access to variables and attributes
79
- **Legacy API** (`h5netcdf.legacyapi.Dataset`): Drop-in replacement for netCDF4-python with identical method names and behavior
80
81
Both APIs operate on the same underlying HDF5 files via h5py, ensuring full interoperability while providing flexibility for different coding styles and migration paths.
82
83
## Capabilities
84
85
### File Operations
86
87
Core file management including opening, creating, and closing netCDF4 files with various access modes and configuration options.
88
89
```python { .api }
90
class File(Group):
91
def __init__(self, path, mode: str = "r", invalid_netcdf: bool = False,
92
phony_dims: str = None, track_order: bool = None,
93
decode_vlen_strings: bool = False, **kwargs): ...
94
def close(self) -> None: ...
95
def flush(self) -> None: ...
96
def sync(self) -> None: ...
97
@property
98
def filename(self) -> str: ...
99
@property
100
def mode(self) -> str: ...
101
```
102
103
[File Operations](./file-operations.md)
104
105
### Groups and Hierarchical Organization
106
107
Managing hierarchical data organization through groups, including creation, navigation, and nested group structures.
108
109
```python { .api }
110
class Group(Mapping):
111
def create_group(self, name: str) -> Group: ...
112
def create_variable(self, name: str, dimensions: tuple = (), dtype=None,
113
data=None, fillvalue=None, chunks=None, **kwargs) -> Variable: ...
114
def resize_dimension(self, dim: str, size: int) -> None: ...
115
def create_enumtype(self, datatype, datatype_name: str, enum_dict: dict) -> EnumType: ...
116
def create_vltype(self, datatype, datatype_name: str) -> VLType: ...
117
def create_cmptype(self, datatype, datatype_name: str) -> CompoundType: ...
118
def flush(self) -> None: ...
119
def sync(self) -> None: ...
120
@property
121
def groups(self) -> Frozen: ...
122
@property
123
def variables(self) -> Frozen: ...
124
@property
125
def parent(self) -> Group: ...
126
@property
127
def name(self) -> str: ...
128
@property
129
def dims(self) -> Dimensions: ...
130
@property
131
def enumtypes(self) -> Frozen: ...
132
@property
133
def vltypes(self) -> Frozen: ...
134
@property
135
def cmptypes(self) -> Frozen: ...
136
```
137
138
[Groups and Hierarchical Organization](./groups.md)
139
140
### Variables and Data Access
141
142
Creating, reading, and writing data variables with support for chunking, compression, and various data types.
143
144
```python { .api }
145
class Variable(BaseVariable):
146
def __getitem__(self, key) -> np.ndarray: ...
147
def __setitem__(self, key, value) -> None: ...
148
def __len__(self) -> int: ...
149
def __array__(self, *args, **kwargs) -> np.ndarray: ...
150
@property
151
def shape(self) -> tuple: ...
152
@property
153
def dtype(self) -> np.dtype: ...
154
@property
155
def datatype(self): ...
156
@property
157
def dimensions(self) -> tuple: ...
158
@property
159
def ndim(self) -> int: ...
160
@property
161
def chunks(self) -> tuple: ...
162
@property
163
def compression(self) -> str: ...
164
@property
165
def compression_opts(self): ...
166
@property
167
def fletcher32(self) -> bool: ...
168
@property
169
def shuffle(self) -> bool: ...
170
```
171
172
[Variables and Data Access](./variables.md)
173
174
### Dimensions Management
175
176
Creating and managing dimensions including unlimited dimensions and dimension scaling.
177
178
```python { .api }
179
class Dimension:
180
def __init__(self, parent: Group, name: str, size: int = None,
181
create_h5ds: bool = False, phony: bool = False): ...
182
def isunlimited(self) -> bool: ...
183
@property
184
def size(self) -> int: ...
185
```
186
187
[Dimensions Management](./dimensions.md)
188
189
### Attributes and Metadata
190
191
Managing attributes on files, groups, and variables with proper type handling and netCDF4 conventions.
192
193
```python { .api }
194
class Attributes(MutableMapping):
195
def __getitem__(self, key: str): ...
196
def __setitem__(self, key: str, value) -> None: ...
197
def __delitem__(self, key: str) -> None: ...
198
```
199
200
[Attributes and Metadata](./attributes.md)
201
202
### User-Defined Types
203
204
Creating and managing custom data types including enumeration, variable-length, and compound types.
205
206
```python { .api }
207
class EnumType(UserType):
208
@property
209
def enum_dict(self) -> dict: ...
210
211
class VLType(UserType): ...
212
213
class CompoundType(UserType):
214
@property
215
def dtype_view(self) -> np.dtype: ...
216
```
217
218
[User-Defined Types](./user-types.md)
219
220
### Legacy API Compatibility
221
222
netCDF4-python compatible interface for existing code migration and compatibility.
223
224
```python { .api }
225
class Dataset(File, Group, HasAttributesMixin):
226
def createGroup(self, name: str) -> Group: ...
227
def createDimension(self, name: str, size: int = None) -> Dimension: ...
228
def createVariable(self, varname: str, datatype, dimensions: tuple = (), **kwargs) -> Variable: ...
229
```
230
231
[Legacy API Compatibility](./legacy-api.md)
232
233
## Types
234
235
```python { .api }
236
class CompatibilityError(Exception):
237
"""Raised when using features incompatible with netCDF4 API."""
238
pass
239
240
class BaseObject:
241
@property
242
def name(self) -> str: ...
243
@property
244
def dtype(self) -> np.dtype: ...
245
246
class BaseVariable(BaseObject):
247
"""Base class for Variable with common functionality."""
248
def __array__(self) -> np.ndarray: ...
249
@property
250
def shape(self) -> tuple: ...
251
@property
252
def ndim(self) -> int: ...
253
@property
254
def dimensions(self) -> tuple: ...
255
256
class UserType(BaseObject):
257
@property
258
def dtype(self) -> np.dtype: ...
259
260
class Frozen(Mapping):
261
"""Immutable wrapper for mapping objects."""
262
@property
263
def _mapping(self): ...
264
265
class Dimensions(MutableMapping):
266
"""Container for managing dimensions within a group."""
267
def add(self, name: str): ...
268
def add_phony(self, name: str, size: int): ...
269
270
# Constants
271
NOT_A_VARIABLE: bytes = b"This is a netCDF dimension but not a netCDF variable."
272
273
# Default fill values (from legacy API)
274
default_fillvals: dict = {
275
'S1': '\x00',
276
'i1': -127,
277
'u1': 255,
278
'i2': -32767,
279
'u2': 65535,
280
'i4': -2147483647,
281
'u4': 4294967295,
282
'i8': -9223372036854775806,
283
'u8': 18446744073709551614,
284
'f4': 9.969209968386869e36,
285
'f8': 9.969209968386869e36,
286
}
287
288
# Utility Functions
289
def _join_h5paths(parent_path: str, child_path: str) -> str:
290
"""Join HDF5 paths properly."""
291
...
292
293
def _name_from_dimension(dim) -> str:
294
"""Extract name from dimension."""
295
...
296
297
def _invalid_netcdf_feature(feature: str, allow: bool) -> None:
298
"""Check feature compatibility and raise CompatibilityError if needed."""
299
...
300
301
def _get_default_fillvalue(dtype) -> any:
302
"""Get default fill value for data type."""
303
...
304
305
def _check_return_dtype_endianess(endian: str = "native") -> str:
306
"""Check and normalize endianness specification."""
307
...
308
```