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 will be accessed.
# !pip3 install ecmwf-opendata
from ecmwf.opendata import Client
client = Client(source="azure")
request = {
"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()
from ecmwf.opendata import Client
import earthkit.data
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")
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",
#param="2t",
target="azure_2t_data.grib2",
)
ds.ls()
---------------------------------------------------------------------------
HTTPError Traceback (most recent call last)
Cell In[13], line 13
4 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")
5 request = {
6 "date": "2025-06-25 12:00:00",
7 "time": 12,
(...) 11 "param": "2t",
12 }
---> 13 client.retrieve(request, "azure_2t_data.grib2")
15 ds = earthkit.data.from_source(
16 "ecmwf-open-data",
17 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",
(...) 24 target="azure_2t_data.grib2",
25 )
28 #client.retrieve(request, "azure_2t_data.grib2")
29 #dm_2t = ekd.from_source("file", "azure_2t_data.grib2")
File ~/Alenka/Code4Earth_2025/python-dev/lib/python3.12/site-packages/ecmwf/opendata/client.py:147, in Client.retrieve(self, request, target, **kwargs)
146 def retrieve(self, request=None, target=None, **kwargs):
--> 147 result = self._get_urls(request, target=target, use_index=True, **kwargs)
148 result.size = download(
149 result.urls,
150 target=result.target,
151 verify=self.verify,
152 session=self.session,
153 )
154 return result
File ~/Alenka/Code4Earth_2025/python-dev/lib/python3.12/site-packages/ecmwf/opendata/client.py:247, in Client._get_urls(self, request, use_index, target, **kwargs)
244 seen.add(url)
246 if for_index and use_index:
--> 247 data_urls = self.get_parts(data_urls, for_index)
249 return Result(
250 urls=data_urls,
251 target=target,
(...) 254 for_index=for_index,
255 )
File ~/Alenka/Code4Earth_2025/python-dev/lib/python3.12/site-packages/ecmwf/opendata/client.py:268, in Client.get_parts(self, data_urls, for_index)
266 index_url = f"{base}.index"
267 r = robust(self.session.get)(index_url, verify=self.verify)
--> 268 r.raise_for_status()
270 parts = []
271 for line in r.iter_lines():
File ~/Alenka/Code4Earth_2025/python-dev/lib/python3.12/site-packages/requests/models.py:1026, in Response.raise_for_status(self)
1021 http_error_msg = (
1022 f"{self.status_code} Server Error: {reason} for url: {self.url}"
1023 )
1025 if http_error_msg:
-> 1026 raise HTTPError(http_error_msg, response=self)
HTTPError: 403 Client Error: Forbidden for url: 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/20250625/12z/ifs/0p25/oper/20250625120000-0h-oper-fc.index
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()