@@ -112,6 +112,182 @@ You can learn more about using and developing backends in the
112112 linkStyle default font-size:18pt,stroke-width:4
113113
114114
115+ .. _io.backend_resolution :
116+
117+ Backend Selection
118+ -----------------
119+
120+ When opening a file or URL without explicitly specifying the ``engine `` parameter,
121+ xarray automatically selects an appropriate backend based on the file path or URL.
122+ The backends are tried in order: **netcdf4 → h5netcdf → scipy → pydap → zarr **.
123+
124+ .. note ::
125+ You can customize the order in which netCDF backends are tried using the
126+ ``netcdf_engine_order `` option in :py:func: `~xarray.set_options `:
127+
128+ .. code-block :: python
129+
130+ # Prefer h5netcdf over netcdf4
131+ xr.set_options(netcdf_engine_order = [' h5netcdf' , ' netcdf4' , ' scipy' ])
132+
133+ See :ref: `options ` for more details on configuration options.
134+
135+ The following tables show which backend will be selected for different types of URLs and files.
136+
137+ .. important ::
138+ ✅ means the backend will **guess it can open ** the URL or file based on its path, extension,
139+ or magic number, but this doesn't guarantee success. For example, not all Zarr stores are
140+ xarray-compatible.
141+
142+ ❌ means the backend will not attempt to open it.
143+
144+ Remote URL Resolution
145+ ~~~~~~~~~~~~~~~~~~~~~
146+
147+ .. list-table ::
148+ :header-rows: 1
149+ :widths: 50 10 10 10 10 10
150+
151+ * - URL
152+ - :ref: `netcdf4 <io.netcdf >`
153+ - :ref: `h5netcdf <io.hdf5 >`
154+ - :ref: `scipy <io.netcdf >`
155+ - :ref: `pydap <io.opendap >`
156+ - :ref: `zarr <io.zarr >`
157+ * - ``https://example.com/store.zarr ``
158+ - ❌
159+ - ❌
160+ - ❌
161+ - ❌
162+ - ✅
163+ * - ``https://example.com/data.nc ``
164+ - ✅
165+ - ✅
166+ - ❌
167+ - ❌
168+ - ❌
169+ * - ``http://example.com/data.nc?var=temp ``
170+ - ✅
171+ - ❌
172+ - ❌
173+ - ❌
174+ - ❌
175+ * - ``http://example.com/dap4/data.nc?var=x ``
176+ - ✅
177+ - ❌
178+ - ❌
179+ - ✅
180+ - ❌
181+ * - ``dap2://opendap.nasa.gov/dataset ``
182+ - ❌
183+ - ❌
184+ - ❌
185+ - ✅
186+ - ❌
187+ * - ``https://example.com/DAP4/data ``
188+ - ❌
189+ - ❌
190+ - ❌
191+ - ✅
192+ - ❌
193+ * - ``http://test.opendap.org/dap4/file.nc4 ``
194+ - ✅
195+ - ✅
196+ - ❌
197+ - ✅
198+ - ❌
199+ * - ``https://example.com/DAP4/data.nc ``
200+ - ✅
201+ - ✅
202+ - ❌
203+ - ✅
204+ - ❌
205+
206+ Local File Resolution
207+ ~~~~~~~~~~~~~~~~~~~~~
208+
209+ For local files, backends first try to read the file's **magic number ** (first few bytes).
210+ If the magic number **cannot be read ** (e.g., file doesn't exist, no permissions), they fall
211+ back to checking the file **extension **. If the magic number is readable but invalid, the
212+ backend returns False (does not fall back to extension).
213+
214+ .. list-table ::
215+ :header-rows: 1
216+ :widths: 40 20 10 10 10 10
217+
218+ * - File Path
219+ - Magic Number
220+ - :ref: `netcdf4 <io.netcdf >`
221+ - :ref: `h5netcdf <io.hdf5 >`
222+ - :ref: `scipy <io.netcdf >`
223+ - :ref: `zarr <io.zarr >`
224+ * - ``/path/to/file.nc ``
225+ - ``CDF\x01 `` (netCDF3)
226+ - ✅
227+ - ❌
228+ - ✅
229+ - ❌
230+ * - ``/path/to/file.nc4 ``
231+ - ``\x89HDF\r\n\x1a\n `` (HDF5/netCDF4)
232+ - ✅
233+ - ✅
234+ - ❌
235+ - ❌
236+ * - ``/path/to/file.nc.gz ``
237+ - ``\x1f\x8b `` + ``CDF `` inside
238+ - ❌
239+ - ❌
240+ - ✅
241+ - ❌
242+ * - ``/path/to/store.zarr/ ``
243+ - (directory)
244+ - ❌
245+ - ❌
246+ - ❌
247+ - ✅
248+ * - ``/path/to/file.nc ``
249+ - *(no magic number) *
250+ - ✅
251+ - ✅
252+ - ✅
253+ - ❌
254+ * - ``/path/to/file.xyz ``
255+ - ``CDF\x01 `` (netCDF3)
256+ - ✅
257+ - ❌
258+ - ✅
259+ - ❌
260+ * - ``/path/to/file.xyz ``
261+ - ``\x89HDF\r\n\x1a\n `` (HDF5/netCDF4)
262+ - ✅
263+ - ✅
264+ - ❌
265+ - ❌
266+ * - ``/path/to/file.xyz ``
267+ - *(no magic number) *
268+ - ❌
269+ - ❌
270+ - ❌
271+ - ❌
272+
273+ .. note ::
274+ Remote URLs ending in ``.nc `` are **ambiguous **:
275+
276+ - They could be netCDF files stored on a remote HTTP server (readable by ``netcdf4 `` or ``h5netcdf ``)
277+ - They could be OPeNDAP/DAP endpoints (readable by ``netcdf4 `` with DAP support or ``pydap ``)
278+
279+ These interpretations are fundamentally incompatible. If xarray's automatic
280+ selection chooses the wrong backend, you must explicitly specify the ``engine `` parameter:
281+
282+ .. code-block :: python
283+
284+ # Force interpretation as a DAP endpoint
285+ ds = xr.open_dataset(" http://example.com/data.nc" , engine = " pydap" )
286+
287+ # Force interpretation as a remote netCDF file
288+ ds = xr.open_dataset(" https://example.com/data.nc" , engine = " netcdf4" )
289+
290+
115291 .. _io.netcdf :
116292
117293netCDF
@@ -1213,6 +1389,8 @@ See for example : `ncdata usage examples`_
12131389.. _Ncdata : https://ncdata.readthedocs.io/en/latest/index.html
12141390.. _ncdata usage examples : https://github.com/pp-mo/ncdata/tree/v0.1.2?tab=readme-ov-file#correct-a-miscoded-attribute-in-iris-input
12151391
1392+ .. _io.opendap :
1393+
12161394OPeNDAP
12171395-------
12181396
0 commit comments