Sentinel-2 cloud-masked median composite via openEO¶
The sentinel-2-l2a-cloud-masked-composite recipe masks clouds (mask_scl_dilation) and reduces the time axis to a median composite (reduce_dimension(t, median)), returning a single multi-band GeoTIFF. We use a small bbox and a one-month window so the synchronous download stays small and fast.
For a large AOI or a long window the synchronous endpoint is size-capped - pass execute="batch" to run it as a polled batch job instead (a batch job queues server-side and can take many minutes; see the Usage page).
pip install earthlens[openeo]
Setup¶
A single cell for the imports: os / pathlib.Path for the credential check, and the unified EarthLens entry point.
import os
from pathlib import Path
from earthlens import EarthLens
Credentials¶
openEO authenticates with CDSE via OIDC. The download cell below runs for real when credentials are present (env OPENEO_CLIENT_ID / OPENEO_CLIENT_SECRET, or a cached refresh token from a prior interactive login) and prints a skip note otherwise - so this notebook executes cleanly with or without secrets. See the Authentication page.
Detecting a credential source¶
has_openeo_credentials() reports whether any OIDC credential source is available: headless client env vars, a refresh-token env var, or a cached ~/.openeo login.
def has_openeo_credentials() -> bool:
"""Whether some openEO OIDC credential source is available."""
if os.environ.get("OPENEO_CLIENT_ID") and os.environ.get("OPENEO_CLIENT_SECRET"):
return True
if os.environ.get("OPENEO_REFRESH_TOKEN"):
return True
return (Path.home() / ".openeo").exists()
A graceful-skip download wrapper¶
run_or_skip() runs the live download() when credentials exist and otherwise prints a skip note, so the notebook executes top-to-bottom with no errors whether or not CDSE OIDC credentials are configured (the docs build never needs secrets).
def run_or_skip(facade, **download_kwargs):
"""Run the live download when credentials exist, else print a skip note.
Keeps the notebook executing top-to-bottom with no errors whether or not
CDSE OIDC credentials are configured (so the docs build never needs secrets).
"""
if not has_openeo_credentials():
print(
"No openEO OIDC credentials found - skipping the live download.\n"
"Set OPENEO_CLIENT_ID / OPENEO_CLIENT_SECRET (headless) or sign in once\n"
"interactively (see the Authentication page) to run this cell for real."
)
return []
paths = facade.download(**download_kwargs)
for path in paths:
print(path)
return paths
Build the request¶
Describe the composite once: the openEO backend, the cloud-masked-composite dataset, a small bbox over the Balearic Sea, and a one-month July window. max_cloud_cover filters the input scenes before compositing.
facade = EarthLens(
data_source='openeo',
dataset='sentinel-2-l2a-cloud-masked-composite',
variables=[],
start='2023-07-01',
end='2023-07-31',
aoi=[3.67, 40.40, 3.72, 40.45],
path='data/openeo-composite',
max_cloud_cover=60,
)
Inspect the output format the recipe will produce - a single multi-band GeoTIFF.
facade.datasource._output_format
Download (server-side execution)¶
openEO builds and runs the process graph on CDSE, then earthlens streams the resulting GeoTIFF down to path. run_or_skip() returns the written paths (or an empty list when credentials are absent).
paths = run_or_skip(facade)
paths