Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@
myst_enable_extensions = ["attrs_block", "substitution"]

myst_substitutions = {
"stac_api_url": f"{BASE_URL}/api/stac/v1",
"datastore_host": os.getenv("DATASTORE_HOST", "api.earthdatahub.destine.eu"),
"datastore_internal_host": os.getenv(
"DATASTORE_INTERNAL_HOST", "data.earthdatahub.destine.eu"
Expand Down
144 changes: 143 additions & 1 deletion source/data-access.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
myst:
html_meta:
description lang=en: This page explains how to access Earth Data Hub datasets using open standards such as Xarray and Zarr, including environment setup, API key authentication, protected datasets, quotas, and local caching.
description lang=en: This page explains how to access Earth Data Hub datasets using open standards such as Xarray and Zarr, including environment setup, API key authentication, protected datasets, quotas, and local caching, plus the STAC catalogue API and direct Zarr access over HTTPS.
---

# {edh-octicon}`download` Data Access
Expand Down Expand Up @@ -230,3 +230,145 @@ ds = xr.open_dataset(
Behind the scenes, caching is handled by the **fsspec** library. The `simplecache` backend is a great default for most workflows, while other caching backends provide additional features such as customisable cache expiration and size limits.

To learn more about available caching options, see the [fsspec documentation](https://filesystem-spec.readthedocs.io/en/latest/features.html#caching-files-locally).

## API reference

Under the hood, Earth Data Hub is just two open interfaces: a **STAC catalogue** to find data, and **Zarr over HTTPS** to read it. No SDK required. If your tool can make a web request, it can use Earth Data Hub.

### STAC catalogue

[STAC](https://stacspec.org/) (SpatioTemporal Asset Catalog) is a standard, searchable catalogue of Earth data. Every collection and dataset you see in the Earth Data Hub catalogue is also available as STAC metadata, starting from a single root URL: <code>{{ stac_api_url }}</code>

```{admonition} One URL to discover everything.
---
class: note
---
The STAC catalogue is **public**: browsing it requires no API key. You only need your key when you read the data itself.
```

Explore the catalogue straight from your terminal:

```{code-block} bash
---
substitutions:
---
# Root catalogue
curl |stac_api_url|/

# All collections (e.g. era5, cmip6, climate-dt-2)
curl |stac_api_url|/collections

# All datasets in a collection
curl |stac_api_url|/collections/era5/items

# Search across the catalogue
curl "|stac_api_url|/search?collections=era5&limit=5"
```

For the full list of endpoints and query parameters, see the {edh_url}`interactive STAC API documentation </api/stac/v1/api.html>`.

In STAC, each dataset is an **item**. Its `data` asset holds the **dataset URL**, along with the exact arguments needed to open it with Xarray:

```{code-block} json
---
emphasize-lines: 3
---
"assets": {
"data": {
"href": "https://data.earthdatahub.destine.eu/era5/era5-land-monthly-v0.zarr",
"roles": ["data"],
"xarray:open_kwargs": {"chunks": {}, "engine": "zarr"},
"xarray:storage_options": {"client_kwargs": {"trust_env": true}}
}
}
```

#### From catalogue to dataset in Python

Install [pystac-client](https://pystac-client.readthedocs.io/) alongside the packages from [](environment-setup):

````{tab-set}
---
class: outline
---
~~~{tab-item} {iconify}`vscode-icons:file-type-pypi` pip
```bash
pip install pystac-client xarray "zarr>3" dask aiohttp
```
~~~

~~~{tab-item} {iconify}`vscode-icons:file-type-uv` uv
```bash
uv add pystac-client xarray "zarr>3" dask aiohttp
```
~~~

~~~{tab-item} {iconify}`vscode-icons:file-type-conda` conda
```bash
conda install -c conda-forge pystac-client xarray "zarr>3" dask aiohttp
```
~~~
````

Then find a dataset in the catalogue and open it, with no URLs to copy and paste. This example uses your `.netrc` file, see [](protected-datasets):

```{code-block} python
---
substitutions:
---
import pystac_client
import xarray as xr

catalog = pystac_client.Client.open("|stac_api_url|")
item = catalog.get_collection("era5").get_item("era5-land")
asset = item.assets["data"]

xr.open_dataset(
asset.href,
storage_options=asset.extra_fields.get("xarray:storage_options"),
**asset.extra_fields.get("xarray:open_kwargs", {}),
)

```

### Zarr over HTTPS

A Zarr dataset is simply a **folder of small files** on the web: a few JSON files describing the data, plus the data itself split into chunks. Each of those files has its own URL, so a plain HTTPS request is all it takes to read one.

Try it with the public test dataset:

```{code-block} bash
---
substitutions:
---
# Dataset metadata: variables, dimensions and attributes
curl https://|datastore_internal_host|/public/test-dataset-v1.zarr/zarr.json

# Variable metadata: shape, chunk shape, data type and compression
curl https://|datastore_internal_host|/public/test-dataset-v1.zarr/demographic_totals/zarr.json

# A single chunk of raw data
curl -o chunk.bin https://|datastore_internal_host|/public/test-dataset-v1.zarr/year/c/0
```

File names follow the standard [Zarr conventions](https://zarr-specs.readthedocs.io/en/latest/v3/core/index.html). To learn more about how chunks are organised, see [](chunking-schemes).

For protected datasets, add your API key to the request:

```{code-block} bash
---
substitutions:
---
# Using your API key directly
curl -u edh:<your API key> https://|datastore_internal_host||private_test_dataset_path|/zarr.json

# Using your API key (with bearer auth)
curl https://|datastore_internal_host||private_test_dataset_path|/zarr.json -H "Authorization: Bearer <your API key>"

# Using your .netrc file
curl --netrc https://|datastore_internal_host||private_test_dataset_path|/zarr.json
```

```{note}
Every request counts towards your monthly quota, whichever tool you use. See [](quotas).
```
Loading