Skip to article frontmatterSkip to article content

Microsoft Planetary Computer


The Planetary Computer includes a vast amount of ECMWF open data available via Azure Storage.

The earthkit and ecmwf-opendata package

When using the ecmwf-opendata Python library, we set source to azure and data hosted on Microsoft’s Azure should be accessed.

If the packages are not installed yet, uncomment the code below and run it.

# !pip3 install ecmwf-opendata earthkit-data earthkit
from ecmwf.opendata import Client
import earthkit.data as ekd

client = Client(source="azure")
request = {
    "date": "2025-08-08 12:00:00",
    "time": 12,
    "type": "fc",
    "step": 0,
    "param": "2t",
}
client.retrieve(request, "azure_2t_data.grib2")
dm_2t = ekd.from_source("file", "azure_2t_data.grib2")
dm_2t.ls()
client = Client(source="https://ai4edataeuwest.blob.core.windows.net/ecmwf/20250625/12z/ifs/0p25/oper/20250625120000-0h-oper-fc.grib2?st=2025-07-01T09%3A54%3A00Z&se=2025-07-02T10%3A39%3A00Z&sp=rl&sv=2024-05-04&sr=c&skoid=9c8ff44a-6a2c-4dfb-b298-1c9212f64d9a&sktid=72f988bf-86f1-41af-91ab-2d7cd011db47&skt=2025-07-02T02%3A32%3A03Z&ske=2025-07-09T02%3A32%3A03Z&sks=b&skv=2024-05-04&sig=qcG7eWdtC7/lhamMO1x8UwyA8A45tGFXAE55Xu5UQKg%3D")
request = {
    "date": "2025-06-25 12:00:00",
    "time": 12,
    "type": "fc",
    "step": 0,
    "stream": "oper",
    "param": "2t",
}
client.retrieve(request, "azure_2t_data.grib2")
dm_2t = ekd.from_source("file", "azure_2t_data.grib2")
dm_2t.ls()
ds = earthkit.data.from_source(
    "ecmwf-open-data",
    source="https://ai4edataeuwest.blob.core.windows.net/ecmwf/20250625/12z/ifs/0p25/oper/20250625120000-0h-oper-fc.grib2?st=2025-07-01T09%3A54%3A00Z&se=2025-07-02T10%3A39%3A00Z&sp=rl&sv=2024-05-04&sr=c&skoid=9c8ff44a-6a2c-4dfb-b298-1c9212f64d9a&sktid=72f988bf-86f1-41af-91ab-2d7cd011db47&skt=2025-07-02T02%3A32%3A03Z&ske=2025-07-09T02%3A32%3A03Z&sks=b&skv=2024-05-04&sig=qcG7eWdtC7/lhamMO1x8UwyA8A45tGFXAE55Xu5UQKg%3D",
    model="ifs",
    date="20250625",
    time=12,
    stream="oper",
    type="fc",
    target="azure_2t_data.grib2",
)
ds.ls()

The pystac_client and planetary_computer package

The example below shows how to download yesterday’s data.

!pip3 install pystac_client planetary_computer
!pip3 install xarray cfgrib
import pystac_client
import planetary_computer
import requests
import xarray as xr

catalog = pystac_client.Client.open(
    "https://planetarycomputer.microsoft.com/api/stac/v1",
    modifier=planetary_computer.sign_inplace,
)
search = catalog.search(
    collections=["ecmwf-forecast"],
    query={
        "ecmwf:stream": {"eq": "oper"},
        "ecmwf:type": {"eq": "fc"},
        "ecmwf:step": {"eq": "0h"},
    },
)
items = search.item_collection()

# select the most recent item
item = max(items, key=lambda item: item.datetime)

url = item.assets["data"].href
url_ecmwf = url.rpartition('?')[0]
filename = str(url_ecmwf.rpartition('oper/')[-1])

r = requests.get(url, stream=True)
with open(filename, mode="wb") as file:
    for chunk in r.iter_content(chunk_size=10 * 1024):
        file.write(chunk)

ds = xr.open_dataset(f'./{filename}', engine='cfgrib',
                     decode_timedelta=True,
                     backend_kwargs={'filter_by_keys': {'typeOfLevel': 'soilLayer'}})
ds
Loading...
Retrieve data for the date range of your interest
import pystac_client
import planetary_computer
import requests
import earthkit.data as ekd

catalog = pystac_client.Client.open(
    "https://planetarycomputer.microsoft.com/api/stac/v1",
    modifier=planetary_computer.sign_inplace,
)
# specify a date range
time_range = "2025-06-01/2025-06-01"

search = catalog.search(
    collections=["ecmwf-forecast"],
    query={
        "ecmwf:stream": {"eq": "oper"},
        "ecmwf:type": {"eq": "fc"},
        "ecmwf:step": {"eq": "0h"},
        },
    datetime=time_range)
items = search.item_collection()

list_of_files = []
for item in items:
    url = item.assets["data"].href
    url_ecmwf = url.rpartition('?')[0]
    filename = str(url_ecmwf.rpartition('oper/')[-1])
    
    r = requests.get(url, stream=True)
    with open(filename, mode="wb") as file:
        for chunk in r.iter_content(chunk_size=10 * 1024):
            file.write(chunk)
    list_of_files.append(filename)

for file_ in list_of_files:
    print(f'File: {file_}')
    ds = ekd.from_source("file", f'./{file_}')
    ds.ls()